WIFI Color Detection with the ESP8266 and MQTT messaging

The previous implementation of the WIFI color detection was done with an ad-hoc messaging system. Now, the most bang for the buck would be to have MQTT integrated, as it is much more flexible in terms of the message format and content.

I got the color detection, which involves frequency decoding of each of the filtered signals for R,G,B and no-filter, and MQTT working like a charm.

The protocol is simple. An MQTT message is sent to topic “AcquireColor”. Response is obtained by listening to topics “GetColorP” for color percentage and “GetColorF” for raw frequency (proportional to color intensity). The returned info comes back as a JSON string as follows:

Percentages:

{“RGBP”: [{ “Red:”: “37”, “Green”: “30”, “Blue:”: “32”}]}

Frequencies:

{“RGBF”: [{ “Red:”: “6578”, “Green”: “5291”, “Blue:”: “5649”, “All:”: “8695”}]}

This module can be purchased at my Tindie store

IMG_5828

Here is the code:

file.writeline([[red=0 ]])
file.writeline([[green=0 ]])
file.writeline([[blue=0 ]])
file.writeline([[all=0 ]])
file.writeline([[IP_posted = 0]])
file.writeline([[color_done=0]])
file.writeline([[pin=5]])
file.writeline([[cur_color=0]])
file.writeline([[start=0]])
file.writeline([[count=0]])
file.writeline([[s_length=10000]])
file.writeline([[freq_multi=1000000]])

file.writeline([[collectgarbage()]])

file.writeline([[– Configuration to connect to the MQTT broker.]])
file.writeline([[BROKER = “your_mqtt_broker_IP_address” — Ip/hostname of MQTT broker]])
file.writeline([[BRPORT = 1883 — MQTT broker port]])
file.writeline([[BRUSER = “user” — If MQTT authenitcation is used then define the user]])
file.writeline([[BRPWD = “pwd” — The above user password]])
file.writeline([[CLIENTID = “ESP8266-” .. node.chipid() — The MQTT ID. Change to something you like]])
file.writeline([[BFSIZE = 16]])

file.writeline([[– MQTT topics to subscribe]])
file.writeline([[topics = {“AcquireColor”} ]])

file.writeline([[– Control variables.]])
file.writeline([[pub_sem = 0 ]])
file.writeline([[current_topic = 1 ]])
file.writeline([[topicsub_delay = 50]])

file.writeline([[– Publishing structures]])
file.writeline([[pub_topic = {}]])
file.writeline([[pub_message = {}]])
file.writeline([[pub_head = 1]])
file.writeline([[pub_tail = 1]])

file.writeline([[collectgarbage()]])

file.writeline([[print(“heap: ” .. node.heap() )]])
file.writeline([[m = mqtt.Client( CLIENTID, 120, BRUSER, BRPWD)]])

file.writeline([[print “Connecting to MQTT broker. Please wait…”]])
file.writeline([[m:connect( BROKER , BRPORT, 0, function(conn)]])
file.writeline([[ print(“Connected to MQTT:” .. BROKER .. “:” .. BRPORT ..” as ” .. CLIENTID )]])
file.writeline([[ mqtt_sub() ]])
file.writeline([[end)]])

file.writeline([[function mqtt_sub()]])

file.writeline([[ if table.getn(topics) < current_topic then]])
file.writeline([[ init_STA()]])
file.writeline([[ else]])
file.writeline([[collectgarbage()]])
file.writeline([[ m:subscribe(topics[current_topic] , 0, function(conn) ]])
file.writeline([[ end)]])
file.writeline([[ current_topic = current_topic + 1 ]])
file.writeline([[ tmr.alarm(5, topicsub_delay, 0, mqtt_sub )]])
file.writeline([[ end]])
file.writeline([[collectgarbage()]])

file.writeline([[end]])

file.writeline([[function publish_data()]])
file.writeline([[collectgarbage()]])
file.writeline([[ freq_all =(freq_multi/all)]])
file.writeline([[ freq_red =(freq_multi/red)]])
file.writeline([[ freq_green =(freq_multi/green)]])
file.writeline([[ freq_blue =(freq_multi/blue)]])
file.writeline([[ col_sum =freq_red+freq_green+freq_blue]])
file.writeline([[ perc_red = (100*freq_red)/col_sum]])
file.writeline([[ perc_green = (100*freq_green)/col_sum]])
file.writeline([[ perc_blue = (100*freq_blue)/col_sum]])

file.writeline([[payload = ‘{“RGBF”: [{ “Red:”: “‘ .. freq_red .. ‘”, “Green”: “‘ .. freq_green .. ‘”, “Blue:”: “‘ .. freq_blue .. ‘”, “All:”: “‘ .. freq_all .. ‘”}]}’]])
file.writeline([[m:publish( “GetColorF”, payload ,0 ,0 , function(conn) ]])
file.writeline([[end)]])
file.writeline([[payload = ‘{“RGBP”: [{ “Red:”: “‘ .. perc_red .. ‘”, “Green”: “‘ .. perc_green .. ‘”, “Blue:”: “‘ .. perc_blue .. ‘”}]}’]])
file.writeline([[m:publish( “GetColorP”, payload ,0 ,0 , function(conn) ]])
file.writeline([[end)]])
file.writeline([[payload = nil]])
file.writeline([[collectgarbage()]])
file.writeline([[end]])
file.writeline([[function pin1cb(level)]])
file.writeline([[if cur_color == 0 and count == 0 then]])
file.writeline([[ gpio.mode(6,gpio.OUTPUT)]])
file.writeline([[ gpio.mode(7,gpio.OUTPUT)]])
file.writeline([[ gpio.write(6,gpio.HIGH)]])
file.writeline([[ gpio.write(7,gpio.LOW)]])
file.writeline([[elseif cur_color == 1 and count == 0 then]])
file.writeline([[ gpio.mode(6,gpio.OUTPUT)]])
file.writeline([[ gpio.mode(7,gpio.OUTPUT)]])
file.writeline([[ gpio.write(6,gpio.LOW)]])
file.writeline([[ gpio.write(7,gpio.LOW)]])
file.writeline([[elseif cur_color == 2 and count == 0 then]])
file.writeline([[ gpio.mode(6,gpio.OUTPUT)]])
file.writeline([[ gpio.mode(7,gpio.OUTPUT)]])
file.writeline([[ gpio.write(6,gpio.HIGH)]])
file.writeline([[ gpio.write(7,gpio.HIGH)]])
file.writeline([[elseif cur_color == 3 and count == 0 then]])
file.writeline([[ gpio.mode(6,gpio.OUTPUT)]])
file.writeline([[ gpio.mode(7,gpio.OUTPUT)]])
file.writeline([[ gpio.write(6,gpio.LOW)]])
file.writeline([[ gpio.write(7,gpio.HIGH)]])
file.writeline([[end]])
file.writeline([[if count == 0 then]])
file.writeline([[ start = tmr.now()]])
file.writeline([[end]])
file.writeline([[tmr.wdclr()]])
file.writeline([[count=count+1]])
file.writeline([[if count > s_length then]])
file.writeline([[ if cur_color == 0 then]])
file.writeline([[ all=(tmr.now()-start)/s_length]])
file.writeline([[ cur_color=1]])
file.writeline([[ print(all )]])
file.writeline([[ elseif cur_color == 1 then]])
file.writeline([[ red=(tmr.now()-start)/s_length ]])
file.writeline([[ cur_color=2]])
file.writeline([[ print(red )]])
file.writeline([[ elseif cur_color == 2 then]])
file.writeline([[ green=(tmr.now()-start)/s_length]])
file.writeline([[ cur_color=3]])
file.writeline([[ print(green )]])
file.writeline([[ elseif cur_color == 3 then]])
file.writeline([[ blue=(tmr.now()-start)/s_length]])
ile.writeline([[ cur_color=0]])
file.writeline([[ color_done=1 ]])
file.writeline([[ gpio.mode(pin,gpio.INPUT)]])
file.writeline([[ print(blue )]])
file.writeline([[ publish_data()]])
file.writeline([[ end]])
file.writeline([[ count=0]])
file.writeline([[end]])
file.writeline([[end]])

file.writeline([[function init_STA()]]) — 1
file.writeline([[collectgarbage()]])

file.writeline([[m:on(“message”, function(conn, topic, payload)]])
file.writeline([[print(topic .. “:” )]])
file.writeline([[ –if (payload ~= nil ) then]])
file.writeline([[ — print ( payload )]])
file.writeline([[ –end]])
file.writeline([[collectgarbage()]])
file.writeline([[cur_color=0]])
file.writeline([[red=0 ]])
file.writeline([[green=0 ]])
file.writeline([[blue=0 ]])
file.writeline([[all=0 ]])
file.writeline([[IP_posted = 0]])
file.writeline([[color_done=0]])
file.writeline([[cur_color=0]])
file.writeline([[start=0]])
file.writeline([[count=0]])
file.writeline([[gpio.mode(pin,gpio.INT)]])
file.writeline([[gpio.trig(pin, “down”, pin1cb)]])

file.writeline([[end )]])
file.writeline([[end]]) — 1

Screen Shot 2015-05-29 at 4.08.15 PM

Posted in Uncategorized | 2 Comments

WIFI Color Detection with the ESP8266

IMG_5950:

The reading of the color components is done via a TCP request to the board. The reading returns a frequency in KHz proportional to the intensity of the color. The frequencies in KHz are returned in a JSON string. The value of the intensity for all colors is also returned. Percentage components of color can be calculated from the frequency readings as these are proportional to the color intensity.

The sequence for reading is done by sending the following strings via TCP on port 9999:

acquire

(wait 5 seconds for acquisition to complete)

readf to read the frequency values

readp to read the percent values

The return message is in JSON format as follows:

Frequency:

{“RGBF”: [{ “Red:”: “1640”, “Green”: “1230”, “Blue:”: “2250”, “All:”: “6250”}]}}]}

each number representing a frequency in KHz proportional to the intensity of the light for red, green, blue and unfiltered (all).

 

Percentage:

{“RGBP”: [{ “Red:”: “33”, “Green”: “42”, “Blue:”: “25”}]}}]}

each number representing a percentage of the intensity of the light for red, green, blue.

This might seem stupid, but given the memory issues on the LUA API, this at least works nicely. Lets see in I can squeeze in MQTT.

Posted in Uncategorized | Leave a comment

MQTT and ESP8266, using i2c sensor things work

Forget the DHT11. Implementing the protocol to read temperature and humidity eats all your memory on the ESP8266 and there is nothing left if you want to support MQTT messaging. However, and I2C sensor works. The I2C implementation using an LM75A can be done and integrated with MQTT.

I am preparing a post with the details on what I did.

Posted in Uncategorized | Leave a comment

MQTT and ESP8266

Got the vibration detection board working with MQTT. This was really an ordeal given that the memory issues with LUA and the ESP8266 are really frustrating. Its trial and error. Finally and after stripping the code to the bare minimum, i.e., remove all the fancy web page interface to the board configuration, things got working pretty good.

I installed my own MQTT broker on a MacBook, Mosquitto, and got it to work without major issues.

MQTT is really great for IoT, of course if you have a broker running or want to go through a public broker, otherwise my ad-hoc messaging solution I think it is a bit easier for home projects. But again, MQTT is the way to go if you want to control several devices, send and receive various commands, etc.

On my future boards I will offer ad-hoc messaging or MQTT, check them out on Tindie

Posted in Uncategorized | 2 Comments

Color recognition board using the ESP8266 and the TAOS TCS230 color-to-frequency module

This is a wifi enabled board that reads color components Red, Green and Blue of any material placed closed to the sensor.

The reading of the color components is done via a TCP request to the board and the percentage color component values are returned in a JSON string.

The sequence for reading is done by sending the following strings via TCP on port 9999:

acquire

(wait 5 seconds for acquisition to complete)

read

The return message is in JSON format as follows:

{“RGB”: [{ “Red:”: “53”, “Green”: “23”, “Blue:”: “24”}]}

each number representing the percentage of that color. The board can be configured via web browser without the need for a serial interface to program it!

This board can be purchased at Tindie, press here to go to Tindie store

Posted in Uncategorized | Leave a comment

ESP8266: Handling analog signals without an analog input, just GPIO!

Experimenting with the ESP8266 at one point I came across the need of dealing with analog signals. There are a lot of versions of the module and most of them have GPIO accessibility but not ADC access. Some of the lates versions of the module have ADC though, but I have a few modules in stock that do not have it. And I need ADC handling.

Well, it is totally possible and here is how to do it.

There are 4 basic things that need to be done:

  • convert the analog signal into pulse width modulation (PWM)
  • read the PWM on any GPIO
  • read the PWM duty cycle on the ESP8266
  • calibrate the PWM to analog level response

This module can be purchased at my Tindie store

IMG_5923

I am using NodeMCU Lua API. Lets look in more detail:

Convert the analog signal into pulse width modulation (PWM)

This is quite simple. The popular LM555 will do the trick. Here is the circuit:

Screen Shot 2015-04-20 at 11.37.38 AM

A sawtooth signal ramping up from 0 to 5v simulates the analog signal, the 555 spits out a PWM, with duty cycle proportional to the analog level. The 555 output is then connected to a GPIO pin.

Read the PWM on any GPIO

This is even simpler. Just pipe the output of the 555 to any GPIO pin.

Read the PWM duty cycle on the ESP8266

To do this, watch for the GPIO pin ‘up’ and ‘down’ events:

file.writeline([[gpio.trig(pin, 'both', callback)]])

In the callback function, read the pin, track the time when the up and downs happen and calculate the ratio, that is the duty cycle:

file.writeline([[time_read= time_read-time_base]])
file.writeline([[rp=gpio.read(pin)]])
file.writeline([[if cnt == 0 and rp == 0 then low_start=time_read]])
file.writeline([[end]])
file.writeline([[if cnt == 1 and rp == 1 then low_end=time_read]])
file.writeline([[end]])
file.writeline([[if cnt == 2 and rp == 0 then high_end=time_read]])
file.writeline([[high_start = low_end]])
file.writeline([[end]])
file.writeline([[cnt=cnt+1]])
file.writeline([[if (high_end-low_start) > 0 and cnt == 3 then]])
file.writeline([[duty = (100*(high_end - high_start))/(high_end-low_start)]])
file.writeline([[print("Duty: " .. duty) ]])
file.writeline([[cnt = 0]])

Read the PWM duty cycle on the ESP8266

Finally, pick a few calibration points between the PWM duty cycle you are reading and the actual analog signal value and calibrate the reading.

My prototypes are available on Tindie.

Posted in Uncategorized | Leave a comment

WIFI vibration sensor using the ESP8266

A simple vibration sensor can be connected to the ESP8266 GPIO pin and an alarm can be triggered via TCP to report vibration. This could be useful for a number of things, including industrial monitoring, security, etc. The prototype uses a sensor originally designed for Arduino, but can easily be connected to one of the GPIOs in the ESP8266. The firmware checks whether the GPIO has triggered and if so it sends a TCP message to a server listening. SSID and password for the WIFI can be programmed remotely via web as with my other prototypes and the nice things is that the server address and the port number the server is listening at can also be programmed remotely via web, no serial connection required and it is persistent!!!

 

VibSensor

Vibration switch

VibrationSensor1

Vibration switch connected to ESP8266 board

Screen Shot 2015-04-16 at 6.19.16 PM

TCP trigger received overtime there is a vibration

 Check my other and future boards on Tindie

 

Posted in Uncategorized | Leave a comment