In my UberFridge project, my router runs a python script that periodically requests new sensor data from the Arduino. The script logs this data in files for the web server running on the router. All other communication with Arduino (getting the OLED’s content, reading/changing settings) also goes via the python script. The Arduino is programmed as a slave that responds to requests from python. With the pyserial library for python, setting this up is fairly easy.
Python code
My Arduino connects to the router via a USB hub. The router mounts the Arduino as /dev/usb/tts/0. See this article on installing the drivers, python, etc.
Python can open the serial port to communicate to Arduino. I use a 2 second timeout, so Python waits 2 seconds for a reply after requesting data.
import serial # open serial port ser = serial.Serial('/dev/usb/tts/0',9600,timeout=2) |
I can now read lines printed by the Arduino with:
line = ser.readline() |
Request new data with:
ser.write("r") |
And give commands, in this case setting it a constant beer mode at a certain temperature:
ser.write("b"+str(temperatureSetting)) |
As you see, I start every line with a letter that indicates the type of message. The Arduino knows how the respond to these commands.
Arduino code
The Arduino constantly polls the serial port for data. When data is available, it looks at the first character of this data and performs the corresponding action. The functions that send sensor data to the serial port will be discussed in the article on data logging for Google annotated time line charts.
void handleSerialCommunication(void){ int newTemp; if (Serial.available() > 0) { char inByte = Serial.read(); switch(inByte) { case 'r': //Data request serialPrintTemperatures(); break; case 'b': //Set to constant beer temperature beerTemperatureSetting = numberFromSerial(); mode = BEER_CONSTANT; initControl(); updateSettings(); saveSettings(); //write new settings to EEPROM doNegPeakDetect=0; doPosPeakDetect=0; lastCoolTime=0; lastHeatTime=0; previousState=0xFF; //force LCD update state=IDLE; lcdPrintState(); serialBeerMessage(BEER_SETTING_FROM_SERIAL); break; case 'p': //Set profile temperature beerTemperatureSetting = numberFromSerial(); mode = BEER_PROFILE; updateSettings(); if(abs(beerTemperatureSetting - eepromReadInt(EEPROM_BEER_SETTING))>=5){ initControl(); updateSettings(); saveSettings(); //write new settings to EEPROM every half degree difference doNegPeakDetect=0; doPosPeakDetect=0; lastCoolTime=0; lastHeatTime=0; previousState=0xFF; //force LCD update state=IDLE; lcdPrintState(); } serialBeerMessage(BEER_SETTING_FROM_PROFILE); break; case 'f': //Set to constant fridge temperature newTemp = numberFromSerial(); if(abs(newTemp-fridgeTemperatureSetting)>3){ doNegPeakDetect=0; doPosPeakDetect=0; lastCoolTime=0; lastHeatTime=0; previousState=0xFF; //force LCD update state=IDLE; lcdPrintState(); initControl(); } mode = FRIDGE_CONSTANT; fridgeTemperatureSetting = newTemp; updateSettings(); saveSettings(); //write new settings to EEPROM serialFridgeMessage(FRIDGE_SETTING_FROM_SERIAL); break; case 's': //Settings requested switch(mode){ case BEER_CONSTANT: Serial.println("beer"); Serial.println(int(beerTemperatureSetting+.5)); break; case FRIDGE_CONSTANT: Serial.println("fridge"); Serial.println(int(fridgeTemperatureSetting+.5)); break; case BEER_PROFILE: Serial.println("profile"); Serial.println(int(beerTemperatureSetting+.5)); break; } break; case'l': //lcd contents requested lcdReadContents(); Serial.print(lcdText[0]);Serial.print(" "); Serial.print(lcdText[1]);Serial.print(" "); Serial.print(lcdText[2]);Serial.print(" "); Serial.println(lcdText[3]); break; default: Serial.println(".Invalid command Received by Arduino"); } Serial.flush(); } } int numberFromSerial(void) { char numberString[8]; unsigned char index=0; delay(10); while(Serial.available() > 0) { delay(10); numberString[index++]=Serial.read(); if(index>6) { break; } } numberString[index]=0; return atoi(numberString); } |



Hi Elco,
Your Uberfridge inspired me to create an interface by which I can controll my aquarium lights over the internet. I am looking for information on how to get my OpenWrt router to mount the Arduino. A link in this article that would have the information I want is dead. Would you please fix the link? Or else you could email me any resources you used
Best Regards
Marinus
Thanks for the heads up. It’s fixed now.
Hi Elco -
Did you ever see differences in the value between the Arduino output via the serial monitor and what was coming in via pySerial? I’m seeing a difference of about 40F. Thanks for any help. Brew on!
I have not noticed that. There is a small difference on how both languages round floats, so 22.0 might become 21.9999994 or something. I wrote the whole thing for Celcius. Could that explain something?