Skip to content

Instantly share code, notes, and snippets.

@abhigkar
Forked from kenci/i2c-arduino.ino
Created November 2, 2018 12:29
Show Gist options
  • Save abhigkar/940b7c38e50c23829a0673b6ddf675bd to your computer and use it in GitHub Desktop.
Save abhigkar/940b7c38e50c23829a0673b6ddf675bd to your computer and use it in GitHub Desktop.
Sending float array through I2C from Arduino to RPi
#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;
}
#!/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