MQTT Cheerlights on ESP8266

Place your projects here
Post Reply
Posts: 63
Joined: Mon Feb 15, 2021 1:44 pm
Has thanked: 24 times
Been thanked: 54 times

MQTT Cheerlights on ESP8266

Post by AndyGadget »

This is an updated and improved version of the code I posted on the old forum which will set a string of neopixels to the current Cheerlights colour.

Cheerlights is a project created by Hans Scharler which listens for a mention of Cheerlights on the Twitter feed and updates its Thingspeak and MQTT feeds with any colour mentioned in the Tweet and so changes Cheerlights all across the world to synchronize to that color set by Twitter. This is a way to connect physical things with social networking experiences. I've had a 3D printed Cheerlights Cat running for a few of years now, originally with ESP8266 Basic but now Annex Basic. Cheerlights is particularly active over the Christmas period as a fair few people use them for Christmas lights.
More info at [External Link Removed for Guests]

Send a tweet mentioning @cheerlights and the name of a colour to change the Cheerlights all over the world.

I'm using a D1 mini board for the project, connecting the neopixel DataIn line to D4 (GPIO2). I've also connected an LDR with 47K pullup resistor on the analogue pin which monitors the ambient light allowing the software to reduce the neopixel intensity as the room light dims, turning off completely in total darkness as this is located in a bedroom. LDRs come in many varieties so the resistor value will need a bit of experimentation to give the best range from light to dark.

Code: [Local Link Removed for Guests]

' ****************************************
' ESP8266 Cheerlights for Annex Basic
' Using MQTT to retrieve current colour.
' ****************************************

' Set up Neopixel strip.
pause 100
neo.strip 0,11,5,5,5

' Initialise colour values
redval = 0
grnval = 0
bluval = 0

ldrval = 0
ldrdiv = 1
ldrave = 500

' Values for brightness fade rate : up and down.
ldrpdup = 20
ldrpddn = 100

gosub ConnectMQTT
timer0 200, LightLevel
onmqtt ChangeColour


' Subroutines
' ===========

' Connect to MQTT Cheerlights feed (
' No additional auth required.
  wlog "MQTT connecting"
  wlog mqtt.setup("")
  wlog mqtt.connect("", "")
  wlog mqtt.subscribe("cheerlightsRGB")
  pause 1000
loop until MQTT.Connected() = 1

' Check light level in room.
ldrval = adc

' Smooth the ldr values.  Different smoothing constant for brightness up and down.
if ldrave > ldrval then
  ldrave = ((ldrave * (ldrpdup - 1)) + ldrval) / ldrpdup
  ldrave = ((ldrave * (ldrpddn - 1)) + ldrval) / ldrpddn
end if

ldrdiv = ((ldrave / 100) - 1)

if ldrdiv < 1 then ldrdiv = 1
' Set this value to slightly less than value for full dark to set turn-off threshold.
if ldrdiv > 7.6 then ldrdiv = 999

' Check in case of MQTT disconnect.
MQ = MQTT.Connected()
if MQ = 0 then gosub ConnectMQTT

' Show values every second for debug.
lcnt = (lcnt + 1) mod 5
if lcnt = 0 then wlog  ColCode$, ldrval, ldrave, ldrdiv, MQ

neo.strip 0,11,redvalx \ ldrdiv, grnvalx \ ldrdiv, bluvalx \ ldrdiv


' Change colour when new MQTT message received

wlog "Colour change to " + ColCode$

' Tweak codes for better colours on my LED ring
if colcode$ = "FFA500" then colcode$ = "FF5000" 'Orange
if colcode$ = "FFC0CB" then colcode$ = "FF4040" 'Pink
if colcode$ = "800080" then colcode$ = "4B0096" 'Purple
if colcode$ = "FDF5E6" then colcode$ = "FDFD30" 'OldLace

' Store old colour values
' These will be modified in fade loop.
redvalx = redval
grnvalx = grnval
bluvalx = bluval

'Extract R, G and B bytes from new colour code.
redval = val("&H" + mid$(colcode$,1,2)) \ ldrdiv
grnval = val("&H" + mid$(colcode$,3,2)) \ ldrdiv
bluval = val("&H" + mid$(colcode$,5,2)) \ ldrdiv

' Colour change routine - output values increment / decrement to new colour.
for cnt = 1 to 256
  ' Clever bit!
  ' SGN() returns 1 for +ve numbers, -1 for -ve and 0 for zero result.
  ' Slightly faster than 6 x IF-THEN statements.
  redvalx = redvalx + sgn(redval-redvalx)
  grnvalx = grnvalx + sgn(grnval-grnvalx)
  bluvalx = bluvalx + sgn(bluval-bluvalx)
  ' Send intermediate colour divided by brightness level to neopixels.
  neo.strip 0,11,redvalx \ ldrdiv, grnvalx \ ldrdiv, bluvalx \ ldrdiv
next cnt
Post Reply