FamiLamp: Cloud-Synchronized Color-Selectable Lamps

Finished product first. My family all live geographically far apart and I wanted an easy way to stay connected for a simple “I’m thinking of you” gesture. More detailed technical information as well as all code and schematics are available here: https://github.com/Here-Be-Dragons/familamp

To use, you hover your hand over a touch-sensitive hammered copper top plate until the color you want has reached the top of the lamp. The selected color is sent to all lamps listening on the same messaging channel. After an hour of no activity, the lamp fades back off.

Ordered PCBs from OSH Park using EAGLE

More details and a few additional photos here: http://imgur.com/a/0NYzQ


That is so awesome!! Good thing you didn’t post this before christmas because I would have dropped what I was doing and started trying to crank a bunch of these guys out instead. Do you have any more of the boards on hand you’d be interested in selling? If not, looks like the eagle files are up on github so I could just print some out myself!

I sure don’t; any spares I bought I burned through by making mistakes during build. You can order duplicates via https://oshpark.com/profiles/osmosis, or use the EAGLE files in the GitHub repository (I think I included everything needed) to modify and order as you see fit.

If I were to redo the board, I may move the capacitor further down the bus just before the LED strip, and add in a diode to prevent the photon from seeing the capacitor. I’ve had a few issues with voltage brown-out wrecking the EEPROM after unplugging the lamp from a power source (I think), and my best guess is as the capacitor is draining it may be causing the board to brown-out before losing power.

Additionally, I came across a circuit that could have raised the voltage of the data going to the pixels from 3.3V to 4V, which would have prevented the need for the logic level converter board.

Lastly, I would probably try to move the solder points for the LEDs and touch plate towards the top of the board instead of being down the side, to be closer to the holes they go through. This would especially be helpful for the copper wire I’m using for touch, since it runs down the entire side of the board and if the insulation wears off the wire, it could short something.

hey man I am glad you picked this project up again since it was abandoned 2 years ago by the original creator and I couldn’t get his code to work anymore. I’ve done a ton of googling to track down an updated version of this product and here it is!
He seems to have gone to an esp8266 and mqtt which is a lot cheaper but since he sells them he doesn’t provide the code anymore. Even though I have emailed him and contacted him on every single website I can find him on

I like the extra lighting effects that you have and the idle modes plus brightness modes. Yours looks way better anyway with the frosted glass and wood instead of the dumb block line design he had
3 questions I had about this

  1. it says via you description to use a 1m ohm resistor for the touch sensor. based on the last guys design, it used 10m ohm. would 10m still work in this case? as I don’t have any 1m ohms and don’t really want to buy any

  2. in his original design he tried to use particle subscribe and publish but he came to the conclusion that it was unreliable. Since it has been 2 years I would imagine they’ve done a lot of improvements on this. do you ever have any issues with them not syncing via the publish/subscribe function?

  3. I see you have a time.zone in the setup as -5. would changing this for each particle depending on their location cause a problem? for example if I had one is chicago -6 and one in germany +1. would this still sync up or would it cause problems based on different time zones

Thanks for the interest in the project. It definitely shares similar ideas to mine but I wanted to build something from the ground up, so I didn’t use any of the existing designs or code.

Answers to your questions:

  1. You can vary the resistor you use to adjust lamp sensitivity to capacitance changes. A lower resistance is less sensitive, but also polls faster. A high resistance takes longer to poll but can detect changes to capacitance with more sensitivity. With 1m ohm, I have to be within a few mm of the copper plate to get it to register. I did build one lamp with a 10m ohm to test different values, and if you don’t want to bother with acquiring 1m ohm resistors it shouldn’t make a huge difference. I chose 1m ohm because I loop through a the captouch poll function frequently in the middle of effect transitions (you’ll see the code doesn’t spend much time in for loops, instead opting for state comparisons to decide what to do). I do this to try to get it to react to a touch as quickly as possible. Because of the frequency I was calling for polls, it was making the animations appear a little jumpy for my taste if the polling takes very long.
    That being said, the captouch library I used as a dependency for this project does automatic calibration of the touch sensitivity, so you shouldn’t see very much difference between resistor values. I have noticed in really dry weather it does slow down polling significantly which has the end result of making slightly stuttery animation effects, even with 1m ohm.

  2. I ran into some issues a few years ago with Particle.subscribe() and Particle.publish(). I’d chalk them up to about 30% actual issues with the functions in some circumstances, 50% my own fault, and 20% a lack of documentation from Particle. They’ve released tons of firmware updates in the last two years and as of about a year ago I stopped ever having issues with their cloud functions. I don’t think I’ve run into an issue I’d blame on particle in at least a year. Additionally, the time it takes for a lamp to sync its colors to all other lamps has to be in the milliseconds. It is almost instantaneous.

  3. Ugh… the time zone issue. The code I’ve made to tackle this issue I consider a hack, and am not happy with at all. My initial plan was to get the particle to figure out its public IP address, geolocate, then discover its time zone from that. Even better, once it has that information have it discover sunrise/sunset (I have the sunrise/sunset webhooks working great in another project), and have it intelligently dim at the right time when the sun goes down, and then dim further around bed time. I was unsuccessful in figuring out a solution for the public IP address and time zone without using pay-for APIs. So, because I won’t be frequently adding/removing lamps from service, and do not have plans of having a retail product, I’ve hard-coded Photon Device IDs into if statements and assigned them to a timezone within setup(). This works ok, even though sunset varies based on latitude as well as longitude. Thankfully, this only impacts when the lamps auto-dim.
    The code is something like this:

    // Timezone for each lamp
    if (System.deviceID() == “xxxxxxxxxxxxxxxxxxxxx” || System.deviceID() == “xxxxxxxxxxxxxxxxxxxxx”) {
    } else if (System.deviceID() == “xxxxxxxxxxxxxxxxxxxxx”) {
    } else {

Hope this helps.

ok cool, i mean technically i can buy some and they don’t cost much like 50 cents from china but takes a month to get here but i was hoping to get it done before vday to give to my gf

so i think i might of noticed a bug in your latest code, reason i say this is because i am not able to compile it getting a " error: a function-definition is not allowed here before ‘{’ token" tracing it back from your latest commit on github it looks like your missing 2 }} at the end of your “idleColorFader” function. i could be wrong though as I don’t know much about coding and i am really just using google and my entry level skills to diag what is wrong without bothering anyone and trying to learn at the same time
even by adding this i for some reason can’t get it to compile as it comes up with more of the same errors and i checked all the {} and []

Also may I ask why you have duplicate functions? do they serve a purpose. - genuinely asking
for the timezone i figured it affected the dimming, didn’t look into anything else but cool :slight_smile:
are you saying i should put different timezones in them? also i don’t see the statement you’re talking about in the code, so i am assuming you have changed it would you be able to commit it to github so I can take a look at it please.
Sorry to sorta take over your project share into a troubleshooting. we can talk about this outside of it if you’d like

You’re up against a heck of a timetable there… definitely stick to 10MOhm, it will be fine.

There was absolutely an error in the code. I sanitize some of the PII from the code (such as device IDs I have hard-coded), and must have messed up a copy/paste job. It was missing about 10 lines of code. I’ve published a new version that should compile successfully.

Can you clarify what you mean by duplicate functions?

Replace the line from github in setup() that reads:


with the code I pasted in the previous reply, replacing x’s with the Device ID you get from the Particle Console. In the example I gave above, the first if statement has two lamps in the timezone, the second if statement has one lamp, and then I have a catch-all after that for any other lamps. If you just have two lamps, you could do something like:

// Timezone for each lamp
if (System.deviceID() == "xxxxxxxxxxxxxxxxxxxxx") {
} else {

haha well everthing else is done on the lights I started this 2 months ago but found out that the orginal firmware was not working. just need to flash code
I will try this code tonight after work. the 10m ohm as you said works fine. I was able to get it to compile after fixing the }} missing and what I mean by double functions on version 12 on line 124 and 333 its the same exact function whileTouching same with sendColorUpdate and a few others. it looks like as you said a copy/paste job gone bad as its fixed in version 13 you uploaded

once I get it fully working I will mess with thi time zones

hey man sorry to bother you again
I still cant get it to update. Reviewing your void loop it doesn’t look like it actually ever calls sendColorUpdate in version 13 which i believe is supposed to publish the new color?
In your version 12 it looks like the sendcolorupdate was in Whiletouching but now its not in there.
Did you mean to take it out?
Where is sendcolorupdate supposed to be? whiletouching or loop?

Here’s a breakdown of the process, starting in loop():

  1. Touch.getEvent() is called, and the result is set to the variable touchEvent
  2. I check if touchEvent is equal to CapTouch::TouchEvent. If is is, it enters the whileTouching() function.
  3. For as long as touchEvent is not set to CapTouch::ReleaseEvent, the while loop inside whileTouching() runs. This is what does the color fading. Each loop it updates the variable (testColor) and increments by 1. When it detects you are no longer touching the lamp, it exits this loop. If you touched it long enough to get the color fader near the top (I try to ignore accidental touches this way), it sets the lamp to be on, and runs sendColorUpdate(), which is on line 151 in Version 13 of the release on GitHub.
  4. sendColorUpdate() calls Particle.publish(), which then updates any lamps subscribed via Particle.subscribe() listening to the FamiLamp_Update topic.
  5. A lamp receiving a color (including the lamp that sent the color, since I don’t actually set the color on a sending lamp directly) runs gotColorUpdate().

My recommendation if you are not getting expected results is to use Particle.publish() or Particle.variable() and a console connection via the Particle CLI to trace what’s happening as stuff runs. You can see an example debug on lines 174 and 175 where I publish an event any time a color is received by a lamp. You could put other Particle.publish() lines elsewhere to verify the code is getting to specific places in the loops.

I am surprised there are any issues getting it to run. The code should be drop-in ready. My only thought would be to remove the PRODUCT_ID() and PRODUCT_VERSION() lines, since you don’t own that product ID. No idea if that would prevent it from working.

It sure will - as mentioned in an other thread with @bizit524

Thanks for clarifying this. I will remove those lines from the code published on github next commit.

to be fair that is one of the first things I noticed was the product Id. I looked into it and setup my own product ID and have it working, this is how i semi debugged it , not via the cli. because i updated the CLI to troubleshoot any possibility I was making in this. and it broke on update. I have not fixed it yet
Mine just never exits the WhileTouching loop that increments by one even though i am not touching it. so it can’t update anything as it never gets passed that.
I know you mentioned based on the resistor and how wet/dry the air is the rainbow/fader effect will slow. In scotland it is always wet even inside and ive tried tons of different resistors 100k, 10m, 5m 10k. I will fix my cli and bash on from there

Why exactly do you (or either of you) need to have this in a product? Are you selling them and managing a bunch of them at once? If this is just for a personal project, adding it to a product will most likely complicate things, rather than simplify them.

Not sure how you’ve got the touch sensor set up, but I’ve found this breakout to work very well: MPR121. It has multiple configurable inputs, and can detect presence from a fair distance (a couple of centimeters, through wood, using a small piece of aluminium foil). For the little money they cost (check ebay/china), it’s not worth the hassle to fiddle with resistors and capacitors and whatnot.

Can you post some photos of your setup, and a link to the code? I am in an area with ~75% humidity constantly and have never had an issue with it triggering. It will even trigger correctly without any touch sensing wire plugged in to D2 if you touch the resistor or the D2 pin directly with your finger.

If you look at the purpose of this project, it is to have multiple lamps that communicate with each other. Each Photon controls one lamp, and they are in different states/countries. I have 8 of them, and Particle’s product functionality has been the perfect way to publish working code to them and keep them current, even if they aren’t all online when I have time to commit improvements.

I understand the purpose of the project, having ‘dabbled’ with it before, which is how I know it’s a pain to make a generic solution. While it’s true that the product auto-flash feature can be handy, it’s not at all helpful during the debugging process, where hard-coding is much easier.

was just cool to research and implement, obviously im using it for the wrong reason but it made it somewhat easier to troubleshoot (at least for me) as I could see logs rolling in via that .

YASS, I will so buy this, ill buy a couple for other projects as well.

So i finally got it working. what i did i took everything apart and rewired it (even though ive done this multiple times). i then reflashed everything from your verrsion 13 minus a few things changed as i dont have as many led’s. I do not have a resistor, cap or step up to 5v circuit. I will put those in eventually just had to rip out all stuff i thought could interfere with it. I put a lower resistor 100k instead of 10m. Also a process of deduction it looks like I damaged either pin 3 or 4 in either a past project or this project so the sensing wasn’t working. I switched sensing to 5 and 6 works fine :slight_smile: :slight_smile: :slight_smile: :slight_smile: :slight_smile: huuuzzzaaahhhh

However if i ever get time i think, i will do what moors suggested and use the capacitive circuit and just put it as a normal pin, and I would like to eventually port it over to ESP8266 with MQTT which is essentially what this is doing but on a professional level. I already have a home automation server with MQTT so I dont think it would be terribly hard to change/modify

Hi, I’m interested in starting this project and I’m curious to know if you have made the changes you mentioned to the PCB already? I’m not familiar with EAGLE or PCB design, and wouldn’t know how to make the changes myself.

I have not been able to make the changes. The device does work well with the current PCB on OSH Park, so they are more about me being nit-picky than requirements.