pdesnoyers76
Posts: 22
Joined: Mon Feb 08, 2016 10:33 pm

RPI 2B to Arduino pro mini

Tue Feb 09, 2016 3:49 pm

I'm new to RPI 2B world and I'm trying to setup some kind of error check communication between a RPI 2B and Arduino pro mini. In case of power failure, or failures of any component there would be back door to my script fall into a failed safe mode.

Ex. I want to be able to program my RPI to query the Arduino on power recycle to see if he's alive and he would respond with a answer. Then send a request to check all his attach sensor if they have a reading. Then my script would be allow to continue and assume everything is ok. This is fully automate my pool, 1 pump(potentially 2, for backup(I have a hand down))), 1 valve(maybe up to 4), with 3 temperature sensor, solar panel, light sensor, maybe 4 to 5 flow sensor. In all cases there has to be a failed safe mode in case the Arduino failed to respond. In any case, the pump will turn on if we are during the day(light sensor) and open the valve for the solar panel so it doesn't rupture.

Any example of code or help how I would do this would be greatly appreciated. I been at this for 3 days with no luck.

User avatar
skywatch
Posts: 46
Joined: Tue May 21, 2013 8:17 pm

Re: RPI 2B to Arduino pro mini

Tue Feb 09, 2016 10:03 pm

Two things spring to mind here.

1. Easy way. Have arduino give output from single gipo to pi (direct if arduino is powered by 3V, or level shifter if it is powered by 5V) and read that. The arduino could also have an interrupt to listen for a input from the pi on a pin, check it is running OK and then give a simple output, gpio arduino output to gipo pi input.

2. Use the serial communications ports on the pi and the arduino to send some data handshake. Again a level shifter might be needed, but it would give a more featured way to do things as multiple commands could be sent and received, all with only 2 wires and ground.

asandford
Posts: 1998
Joined: Mon Dec 31, 2012 12:54 pm
Location: Waterlooville

Re: RPI 2B to Arduino pro mini

Tue Feb 09, 2016 10:34 pm

Use LLAP designed for exctly your sort of requirement.

In my setup, my Nano sends 'a--STARTED ' on powerup. I run a node red flow to check temperature and humidity once a minute. If the temperature is lower than 5C a fan heater swithes on until 10C is reached and it's swiched off. At dusk, the pond lights come on and go off at dawn. During the summer, soil probes contol water pumps, and the humidity sensor controls Air extractors.

All the mains devices are plugged into remote controlled sockets.

The whole control flow runs on a pi in the house, and all the sensors and mains control transmitter are run by an Arduino in the greenhouse.

All 'transactions' are logged to a database.

The two are connected by APC 230 transcievers.

The whole thing has run since Nov 2014 without issue.

Edited to add:
if you can get the RasWIK, you'll realise how easy it can be.

PS I have no affiliation with ciseco/wirelessthings

pdesnoyers76
Posts: 22
Joined: Mon Feb 08, 2016 10:33 pm

Re: RPI 2B to Arduino pro mini

Wed Feb 10, 2016 1:01 am

I guess I am on the right track. I have my RPI setup as master and my arduino uno setup as slave and they communicate via i2c. it's working fine in my current code. The arduino has a photocell hook up on a analog pin and it send back light read to the PI and the PI make the led on a 10 led bar go on and off depending of the light source. My problem it's when I try to modify my code to send data requesting for other info... I thought I understood how the 2 communicate, I guess not. Here the code I'm using, have a look and tell me if you have a idea how to do this.
Here a scenario:
1- when the PI come up, send to arduino are you alive, arduino kind of send back an acknowledgement
2 - PI request light output, arduino send the light output
3 - PI request Temp sensor data, arduino send all or only the specific you ask

arduino code
#include <Wire.h>
#include <FastIO.h>
#include <I2CIO.h>
#define SLAVE_ADDRESS 0x04
int number = 0;
int state = 0;
int photocellPin = 0;
int photocellReading = 0;
int LEDbrightness = 0;
int data = 0;

void setup(){
pinMode(13, OUTPUT);
Serial.begin(9600); // start serial for output
Wire.begin(SLAVE_ADDRESS); // initialize i2c as slave
// define callbacks for i2c communication
Wire.onReceive(receiveData);
Wire.onRequest(sendData);
Serial.println("Ready!");
}

void loop(){
photocellReading = analogRead(photocellPin);
LEDbrightness = map(photocellReading, 0, 1023, 0, 255);
Serial.println(LEDbrightness);
Serial.println(data);
sendData();
delay(1000);
}

void receiveData(int byteCount){ // callback for received data
while(Wire.available()){
number = Wire.read();
if (number == 1){
if (state == 0){
digitalWrite(13, HIGH); // set the LED on
state = 1;
}
else{
digitalWrite(13, LOW); // set the LED off
state = 0;
}
}
}
}

void sendData(){ // sending data to light the right led
if (LEDbrightness>=29 && LEDbrightness<=56){
data=128;
Wire.write(data);
goto end;
}
if (LEDbrightness>=57 && LEDbrightness<=84){
data=192;
Wire.write(data);
goto end;
}
if (LEDbrightness>=85 && LEDbrightness<=112){
data=224;
Wire.write(data);
goto end;
}
if (LEDbrightness>=113 && LEDbrightness<=140){
data=240;
Wire.write(data);
goto end;
}
if (LEDbrightness>=141 && LEDbrightness<=168){
data=248;
Wire.write(data);
goto end;
}
if (LEDbrightness>=167 && LEDbrightness<=196){
data=252;
Wire.write(data);
goto end;
}
if (LEDbrightness>=197 && LEDbrightness<=224){
data=254;
Wire.write(data);
goto end;
}
if (LEDbrightness>=225){
data=255;
Wire.write(data);
goto end;
}
end:{
}
}
=================================================================================================
Code on pi:
# -*- coding: utf-8 -*-
#!/usr/bin/env python
#pool automation
import smbus
import RPi.GPIO as GPIO
import time
import sys
import commands
import logging
import logging.handlers
sys.path.append('/Library_pyton/display_420/')
import RPi_I2C_driver

bus = smbus.SMBus(1) # for RPI version 1, use “bus = smbus.SMBus(0)”
arduino= 0x04 # This is the address we setup in the Arduino Program
lcd = RPi_I2C_driver.lcd()
SDI = 11 #DS
RCLK = 12 #ST
SRCLK = 13 #SH
relay1= 29 #pump slow speed
relay2= 31 #pump high speed
relay3= 32 #solar off
relay4= 33 #solar on
DATA = 0 #A on arduino
counterclockwise = 0 #open valve for solar panel
clockwise = 1 #close valve for solar panel
pump_status = "on" #default state for pump on 1st start
pump_speed = 'High' #default speed for pump on 1st start

WhichLeds = [0xff,0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x00]

def setup():
GPIO.setmode(GPIO.BOARD) # Number GPIOs by its physical location
GPIO.setwarnings(False)
GPIO.setup(SDI, GPIO.OUT)
GPIO.setup(RCLK, GPIO.OUT)
GPIO.setup(SRCLK, GPIO.OUT)
GPIO.setup(relay1, GPIO.OUT)
GPIO.setup(relay2, GPIO.OUT)
GPIO.setup(relay3, GPIO.OUT)
GPIO.setup(relay4, GPIO.OUT)
GPIO.output(SDI, GPIO.LOW)
GPIO.output(RCLK, GPIO.LOW)
GPIO.output(SRCLK, GPIO.LOW)
GPIO.setup(relay1, GPIO.HIGH)
GPIO.setup(relay2, GPIO.HIGH)
GPIO.setup(relay3, GPIO.HIGH)
GPIO.setup(relay4, GPIO.HIGH)

def writeNumber(value):
bus.write_byte(arduino, value)
return -1

def readNumber():
number = bus.read_byte(arduino)
return number

def hc595_in(dat):
for bit in range(len(WhichLeds)-1, -1, -1):
GPIO.output(SDI, 0x80 & (dat << bit))
GPIO.output(SRCLK, GPIO.HIGH)
time.sleep(0.001)
GPIO.output(SRCLK, GPIO.LOW)

def hc595_out():
GPIO.output(RCLK, GPIO.HIGH)
time.sleep(0.001)
GPIO.output(RCLK, GPIO.LOW)

def check_light():
global number
number = refresh()
if number >= 220 and clockwise == 1:
turnon_solar()
if number <= 50 and counterclockwise == 1:
turnoff_solar()

def refresh():
global number
number = bus.read_byte(arduino)
hc595_in(number)
hc595_out()
lcd.lcd_display_string_pos('Light output ', 4, 0)
lcd.lcd_display_string_pos(str(readNumber()), 4, 13)
time.sleep(0.2)
return number


Thanks in advance for any help.... I was on a roll... Now I need help.

asandford
Posts: 1998
Joined: Mon Dec 31, 2012 12:54 pm
Location: Waterlooville

Re: RPI 2B to Arduino pro mini

Thu Feb 11, 2016 9:59 pm

A few suggestions:
- Use the code tags whe you post code on the forum as it makes it easier to read, and preserves formatting (button on the message editor).

Code: Select all

[code]
[/code]
- Replace all the "if LEDbrightness code" in sendData() with a switch (aka case) block (something that python lacks), example here
- Build the Pi code a bit at a time and get that bit working, then build on that.
- Not sure why you hard code a return of -1 here, I'd return the result of the bus.write call so you can test for errors (if you really want to hard code a "Return Code", then "0" usually signals success) .

Code: Select all

def writeNumber(value):
bus.write_byte(arduino, value)
return -1
- You have loads of functions defined, where's the main body code?

Return to “Advanced users”