Created
November 22, 2015 18:51
-
-
Save kenci/13542baae8385ddb3c3c to your computer and use it in GitHub Desktop.
Sending float array through I2C from Arduino to RPi
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Wire.h> | |
#define SLAVE_ADDRESS 0x04 | |
#define FLOATS_SENT 3 | |
float data[FLOATS_SENT]; | |
void setup() { | |
pinMode(13, OUTPUT); | |
Serial.begin(9600); // start serial for output | |
// initialize i2c as slave | |
Wire.begin(SLAVE_ADDRESS); | |
// define callbacks for i2c communication | |
//Wire.onReceive(receiveData); | |
Wire.onRequest(sendData); | |
Serial.println("Ready!"); | |
} | |
void loop() { | |
delay(1000); | |
} | |
/* callback for received data */ | |
void receiveData(int byteCount) { | |
while (Wire.available()) { | |
status = Wire.read(); | |
Serial.print("data received: "); | |
Serial.println(status); | |
if (status == 1) { | |
if (state == 0) { | |
digitalWrite(13, HIGH); // set the LED on | |
state = 1; | |
} | |
else { | |
digitalWrite(13, LOW); // set the LED off | |
state = 0; | |
} | |
} | |
} | |
} | |
// callback for sending data | |
void sendData() { | |
data[0] = getWindspeed(A0); | |
data[1] = getLuminosity(A1); | |
data[2] = getRainRes(A2); | |
Wire.write((byte*) &data, FLOATS_SENT*sizeof(float)); | |
} | |
float getWindspeed(byte pin) { | |
int sensorValue = analogRead(pin); | |
float outVoltage = sensorValue * (5.0 / 1023); | |
return outVoltage*6; | |
} | |
int getLuminosity(byte pin) { | |
int sensorValue = analogRead(pin); | |
return sensorValue; | |
} | |
int getRainRes(byte pin) { | |
int sensorValue = analogRead(pin); | |
return sensorValue; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# coding: utf8 | |
import smbus | |
import struct | |
import time | |
import requests | |
# for RPI version 1, use "bus = smbus.SMBus(0)" | |
bus = smbus.SMBus(1) | |
# This is the address we setup in the Arduino Program | |
address = 0x04 | |
# Set the request parameters | |
urlPimatic = 'http://home.keno.lan:1607/api/variables/' | |
urlEmon = 'http://home.keno.lan/emoncms/input/post.json' | |
apiKey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' | |
user = 'user' | |
pwd = 'pass' | |
PROGRAM_NAME_VERSION = "I2C Reader v4.6.9" | |
DEBUG = True | |
# Set proper headers | |
headers = {"Content-Type":"application/json","Accept":"application/json"} | |
utime = time.time() | |
pausePatching = 1 #time in seconds for patching variables | |
thWind = 1.8 #threshold km/h value for patching variables | |
thLight = 0 #threshold for luminosity | |
thRain = 0 #threshold for rain sensor | |
oldValWind = 0.01 | |
oldValLight = 0.01 | |
oldValRain = 0.01 | |
isPatchedWind = False | |
isPatchedLight = False | |
isPatchedRain = False | |
previousSecs = 0 | |
retry = 0 | |
def splashScreen(name): | |
print " __ ____ _____ " | |
print " / /_____ ___ ___ / __/__ / _/ /_" | |
print " / '_/ -_) _ \/ _ \_\ \/ _ \/ _/ __/" | |
print "/_/\_\\__/_//_/\___/___/\___/_/ \__/ " | |
print " %s " % name | |
time.sleep(1) | |
def patchVarWind(val, var, threshold=0, node=False): | |
global oldValWind, isPatchedWind | |
print "Windmesser %f" % val | |
if((abs(val-oldValWind) >= threshold) or isPatchedWind == False): | |
if DEBUG: print "patching %s - %f" % (var, val) | |
# Do the HTTP request | |
oldValWind = val | |
isPatchedWind = True | |
requests.patch(urlPimatic+var, auth=(user, pwd), headers=headers ,data='{"type":"value", "valueOrExpression": "%.2f"}' % val) | |
if(node): | |
requests.get("%s?node=%d&json={windspeed:%.2f}&apikey=%s" % (urlEmon, node, val, apiKey), auth=(user, pwd)) | |
def patchVarLight(val, var, varString, threshold=0, node=False): | |
global oldValLight, isPatchedLight | |
if DEBUG: print "Light: %f" % val | |
if(abs(val-oldValLight) >= threshold or isPatchedLight == False): | |
if DEBUG: print "patching %s - %f" % (var, val) | |
# Do the HTTP request | |
oldValLight = val | |
isPatchedLight = True | |
requests.patch(urlPimatic+var, auth=(user, pwd), headers=headers ,data='{"type":"value", "valueOrExpression": "%.2f"}' % val) | |
requests.patch(urlPimatic+varString, auth=(user, pwd), headers=headers ,data='{"type":"value", "valueOrExpression": "%s"}' % convLightToStr(val)) | |
if(node): | |
requests.get("%s?node=%d&json={windspeed:%.2f}&apikey=%s" % (urlEmon, node, val, apiKey), auth=(user, pwd)) | |
def patchVarRain(val, var, threshold=0, node=False): | |
global oldValRain, isPatchedRain | |
print "Windmesser %f" % val | |
if((abs(val-oldValWind) >= threshold) or isPatchedWind == False): | |
if DEBUG: print "patching %s - %f" % (var, val) | |
# Do the HTTP request | |
oldValWind = val | |
isPatchedWind = True | |
requests.patch(urlPimatic+var, auth=(user, pwd), headers=headers ,data='{"type":"value", "valueOrExpression": "%.2f"}' % val) | |
if(node): | |
requests.get("%s?node=%d&json={windspeed:%.2f}&apikey=%s" % (urlEmon, node, val, apiKey), auth=(user, pwd)) | |
def convLightToStr(val): | |
if(val <= 11): return "sonnig" | |
elif(val >= 12 and val <= 100): return "wolkig" | |
elif(val >= 101 and val <= 470): return "daemmerung" | |
elif(val >= 671): return "nacht" | |
else: return "unknown" | |
def convRainToStr(val): | |
if(val <= 800): return "regen" | |
elif(val > 800): return "trocken" | |
def get_data(): | |
return bus.read_i2c_block_data(address, 0); | |
def get_float(data, index): | |
bytes = data[4*index:(index+1)*4] | |
return struct.unpack('f', "".join(map(chr, bytes)))[0] | |
## Begin ## | |
splashScreen(PROGRAM_NAME_VERSION) | |
while True: | |
try: | |
if (retry > 2): | |
time.sleep(30) | |
elif(retry > 5): | |
time.sleep(60) | |
data = get_data() | |
dataWind = get_float(data, 0)*3.6 | |
patchVarWind(dataWind, 'aussen-windmesser', thWind, 10) # x3.6 for km/h instead of m/s | |
dataLight = get_float(data, 1) | |
if (dataLight > 900): | |
interval = 600 | |
thLight = 20 | |
elif (dataLight > 50): | |
interval = 60 | |
thLight = 5 | |
elif (dataLight > 13): | |
interval = 60 | |
thLight = 4 | |
else: | |
interval = 60 | |
thLight = 1 | |
currentSecs = int(time.time()) | |
if(currentSecs - previousSecs > interval): | |
previousSecs = currentSecs | |
patchVarLight(dataLight, 'garten-lichtsensor', 'system-lichtsensor', thLight) # | |
except KeyboardInterrupt: | |
print "Abbruch durch Benutzer" | |
except requests.exceptions.ConnectionError as e: | |
print "Fehler bei der Verbindung zur Domain %s!" % url | |
time.sleep(10) | |
retry += 1 | |
except requests.exceptions.ConnectTimeout as e: | |
print "Zeitüberschreitung der Verbindung!" | |
except IOError: | |
time.sleep(10) | |
time.sleep(1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
How could I do this(return struct.unpack('f', "".join(map(chr, bytes)))[0]) in python 3?