Python Forum
MicroPython ESP32 color changing from temps
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
MicroPython ESP32 color changing from temps
#1
For a class I'm in I'm making a coaster that lights up differently depending on how cold or hot the drink sitting on it is.
Connected to the ESP32 board are the ds18b20 thermometer and a LED ring of 24 Neopixels. I've managed to make both of them work seperately just fine, but linking the RGB values to the temperature measurements is turning out to be very tricky.
The following is what I have now:

import machine, neopixel, onewire, ds18x20, time

np = neopixel.NeoPixel(machine.Pin(5), 24)
ds_pin = machine.Pin(4)
ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin))

roms = ds_sensor.scan()
r = 0
g = 0
b = 0
grens = 15
temp = (ds_sensor.read_temp(rom))

while True:
  ds_sensor.convert_temp()
  time.sleep_ms(750)
  for rom in roms:
    #print(rom)
    print(ds_sensor.read_temp(rom))
  def color(r, g, b):
    if (ds_sensor.read_temp(rom)) > grens:
      np[0] = color((temp//2), 0, 0)
      np.write
    else:
      np[0] = color(0, 0, (20-temp))
      np.write
  time.sleep(1)

print "done"
'grens' means limit/threshold and is there to be able to set greater/lesser than parameters.
The thermometer needs the following:

while True:
  ds_sensor.convert_temp()
  time.sleep_ms(750)
  for rom in roms:
    #print(rom)
    print(ds_sensor.read_temp(rom))
  time.sleep(1)
This made it print the temperature correctly every second.
A Neopixel can be controlled as follows:

r = 0
g = 0
b = 10

np[0] = (r, g, b)
np.write()
Running this will make the 1st LED light up blue. ((0, 0, 0) gives no light/off)
As you can see I've tried to put the LED's code in the Thermometer's loop, but it only gives temperature when it worked.

Is there a better way to go about it? How can I best link these parameters? Or any general tips will help a lot.
buran write Apr-15-2021, 09:53 AM:
Please, use proper tags when post code, traceback, output, etc.
See BBcode help for more info.
Reply
#2
Hi,

I use slightly different hardware, and therefore somewhat different commands.
For what i can see :
sometimes you write "np.write()", as it should be,
and sometimes "np.write" as in lines 23 and 26.

maybe try that.

Paul
Reply
#3
This defines a function:
  def color(r, g, b):
    if (ds_sensor.read_temp(rom)) > grens:
      np[0] = color((temp//2), 0, 0)  # <- Recursion is when a function call's itslef.  You don't want to use recursion here.
      np.write  # <- Missing something?
    else:
      np[0] = color(0, 0, (20-temp))  # nor should you use recursion here.
      np.write()
This calls a function:
Output:
color(0, 0, 0)
To make a function do something you need to call the function. Defining the function inside a loop does not call the function. And while Python allows defining a function inside a loop, it is convention to define functions before the start of the main body of code like this:
import machine, neopixel, onewire, ds18x20, time

def set_np(degc):
    """Convert degc temperature to rgb color.  Set neo pixels to the color"""
    color = to_be_determined
    np.set(color)
    np.write()

np = neopixel.NeoPixel(machine.Pin(5), 24)
ds_sensor = ds18x20.DS18X20(onewire.OneWire(machine.Pin(4)))
roms = ds_sensor.scan() 

while True:
    ds_sensor.convert_temp()
    time.sleep(1)
    set_np(ds_sensor.read_temp(roms[0]))
Your function for converting temperature to colors is unusual. Even if your code worked I don't think you would see the LED's light up. If the temperature is 24 C, the RGB color is (12, 0, 0). Drinking a cool soda at 12 C the RGB color is (0, 0, 5). Both of these colors are very dim.

Instead of doing something ad-hock I would use the HSV (Hue, Saturation, Value) color model. In HSV one number is devoted to color (Hue) making converting temperature-> color a simple scalar transform (multiply + add). The only strike against HSV is the conversion to RGB is complicated. However, the algorithm is easy to find online, or you could use the HSV->RGB color converter functions from the matplotlib or opencv packages.

To convert degrees C to color in the range red..blue

hsv(0, 1, 1) == rgb(255, 0, 0) and hsv(240, 1, 1) == rgb(0, 0, 255).
If I want freezing (0 C) to be blue (hue = 240) and boiling (100 C) to be red (hue = 0) the conversion is:

hue = blue + (red - blue) * (temperature - freezing) / (boiling - freezing)
hue = 240 + (0 - 240) * (temperature - 0) / (100 - 0)
hue = 240 - 2.4 * temperature

def hsv_to_rgb(hue, saturation, value):
    """Convert HSV color representation to RGB.  Could use function from matplotlib or opencv libraries."""
    chroma = value * saturation
    x = chroma * (1 - abs((hue / 60) % 2 - 1))
    v_c = value - chroma

    # Calculates rgb where r, g and b are floats with range from 0..1
    if hue <= 60 :
        rgb = (chroma + v_c, x + v_c, v_c)
    elif hue <= 120:
        rgb = (x + v_c, chroma + v_c, v_c)
    elif hue <= 180:
        rgb = (v_c, chroma + v_c, x + v_c)
    elif hue <= 240:
        rgb = (v_c, x + v_c, chroma + v_c)
    elif hue <= 300:
        rgb = (x + v_c, v_c, chroma + v_c)
    else:
        rgb = (chroma + v_c, v_c, x + v_c)

    # Convert to rgb to ints in range 0..255
    return [round(component * 255) for component in rgb]

def temp_to_rgb(degc):
    """Return RGB color value for degC"""
    # Clip temperature to range 0..100 degrees C
    degc = max(0, min(100, degc))
    # Convert degc(0..100) to hue(240..0).
    hue = 240 - degc * 2.4
    # return color as rgb.
    return hsv_to_rgb(hue, 1, 1)

for c in range(101):
    print(c, temp_to_rgb(c))
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Object Detection with ESP32 CAM. MateoG 0 538 Oct-11-2023, 01:44 PM
Last Post: MateoG
  [MicroPython] Beginner, program with lists Hellon 3 2,058 Nov-10-2019, 02:27 AM
Last Post: ichabod801
  working with Micropython - which ecosystem to choose - ESP 8266 or ESP 32? apollo 1 2,507 Aug-11-2019, 12:05 PM
Last Post: apollo

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020