Raspberry Pi / Genuino - temperature display Jun 18, 2017

raspbberypi  genuino  hacks 

Temperature visualisation

It's currently very hot in Belgium, and I've been struggeling finding the best time to open my windows. It's a bad idea to open them when it's still hotter outside compared to inside. You can ofcourse check the weather online, compare it to a thermometer inhouse and do a mental calculation, but that all feels very archiac so instead I've chosen to spend 2 hours of my time hacking at a Genuino / Raspberry Pi project.

The Genuino has 3 leds (Green, Yellow, Blue) and a temperature sensor. It's connected to the Raspberry Pi by a serial USB connection. I wrote a small program for the Genuino that listens to commands on the serial port and returns results when required.

const int analog0 = A0;

int incomingMessage = 0;

// Actions
bool inCommand = false;
bool inGet = false;

void setup() {
  // open a serial connection to display values
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  
  for (int pinNumber = 2; pinNumber < 5; pinNumber++) {
    pinMode(pinNumber, OUTPUT);
    digitalWrite(pinNumber, LOW);
  }
}

void loop() {
  // send data only when you receive data:
  if (Serial.available() > 0) {

      incomingMessage = Serial.read();

      // say what you got:
      Serial.print("# I received: ");
      Serial.println(incomingMessage, DEC);

      // In command mode
      if (inCommand) {
        command();
        return;
      }

      // In get mode
      if (inGet) {
        get();
        return;
      }

      // Waiting for new command
      if (incomingMessage == 83) { // S
        inCommand = true;
      }

      if (incomingMessage == 71) { // G
        inGet = true;
      }
  }

}

int commandPort = -1;
int commandValue = -1;
void command() {
  Serial.println("# Command mode");

  // Set command port and wait for next value
  if (commandPort == -1) {
    commandPort = incomingMessage - 48;
    return;
  }
  
  Serial.print("# Port: ");
  Serial.println(commandPort, DEC);

  // Calculate value and set port accordingly 
  commandValue = incomingMessage - 48;
  if (commandValue == 1) {
    digitalWrite(commandPort, HIGH);
  } else {
    digitalWrite(commandPort, LOW);
  }

  commandPort = -1;
  commandValue = -1;
  inCommand = false;
}

int getPort = -1;
int getValue = -1;
void get() {
  Serial.println("# Get mode");

  // Calculate port
  getPort = incomingMessage - 48;
  
  Serial.print("# Port: ");
  Serial.println(getPort, DEC);

  // Currently only works for port 0, but can be easily extended
  if (getPort == 0) {
    getValue = analogRead(analog0);
  }

  Serial.println("# Value: ");
  Serial.println(getValue);

  getPort = -1;
  inGet = false;
}

On the Raspberry I have a simple Python program that reads the temperature from the OpenWeatherMap API, gets the temperature value from the Genuino, does some calculations with it and then it sets the leds according to the temperature difference.

#!/usr/bin/python
import serial
import time

OPENWEATHERMAP_APIKEY = ""

#The following line is for serial over GPIO
port = '/dev/ttyACM0'

ard = serial.Serial(port,9600,timeout=5)
time.sleep(2) # wait for Arduino

def getValue(port):
    # Send command
    ard.write(str("G%s" % port))

    # Wait on reply
    time.sleep(0.5)

    # Get data and clean
    msg = ard.read(ard.inWaiting())  # read all characters in buffer
    data = 0
    for line in msg.split("\n"):
        if len(line) == 0:
            continue

        if line[0] == "#":
            continue

        data = int(line)

    return data

def setLed(port, value):
    # Send command
    ard.write(str("S%s%s" % (port, int(value))))

def getApiTemperature():
    import urllib, json
    url = "http://api.openweathermap.org/data/2.5/weather?q=Gent&APPID=%s" % OPENWEATHERMAP_APIKEY
    response = urllib.urlopen(url)
    data = json.loads(response.read())

    outside = data['main']['temp'] - 273.15

    return outside

while True:
    sensorVal = getValue(0)

    # Convert to voltage
    voltage = (sensorVal / 1024.0) * 5.0

    # Convert to temperature
    temperature = (voltage - .5) * 100 + 3.5
    print "Temperature (inside): %s" % temperature

    # Get temperature from web api
    outside = getApiTemperature()
    print "Temperature (outside): %s" % outside

    # Set led depending on temperature difference
    diff = outside - temperature
    print "Difference: %s" % diff

    # Set leds
    setLed(2, False)
    setLed(3, False)
    setLed(4, False)
    if diff > 0:
        print "Red"
        setLed(2, True)
    elif diff > -2:
        print "Yellow"
        setLed(3, True)
    elif diff <= -2:
        print "Green"
        setLed(4, True)
    else:
        setLed(2, True)
        setLed(3, True)
        setLed(4, True)
        print "Unknown: %s" % diff

    time.sleep(10)

So there we are: every time the led is green I can open all my windows, if it's orange I need to wait a bit more, and if it's red I keep everything closed.

It was fun to hack something together so quickly with the tools and tutorials found online for both Raspberry Pi and the Genuino Uno. I think I'll try to add a screen someday, but it serves its purpose at the moment.


Comments