Montag, 11. August 2014

[Raspberry, Arduino] First Project

Now its the first weekend of my vacation and i thought it would be a great idea to play around with some "toys" (my wife would say) i bought a while ago.

So i have:

  • Raspberry pi B
  • Arduino Uno rev3
  • analog temperature sensor
  • breadboard
  • a lot of wires :-)

First of all installed raspbian on the raspberry. Raspbian was downloaded from the official raspberry side and written to the sd card. Not that hard.

Arduino and the sensor


First i started with the arduino and the analog sensor.
The TMP36 sensor has three connections,
  1. 5V
  2. GND
  3. Analog 0 (A0)
Its quite easy when everything was connected i startet the first programm:

int sensorPin = 0; // to use A 0
void setup()
{ Serial.begin(9600);  // baud rate for serial console
} 
void loop()  {
 int reading = analogRead(sensorPin);  // read the sensor
 float voltage = reading * 5.0;
 voltage /= 1024.0; 
 Serial.print(voltage); Serial.println(" volts");
 float temperatureC = (voltage - 0.5) * 100 ;  
 Serial.print(temperatureC); Serial.println(" degrees C"); // print to console
  delay(5000);

The program will write the actual temperature to the serial console.

Raspberry and Arduino

So, now i would like to have the output on my raspberry pi. Taking a look around i found the idea to connect it via i2c.

The connection raspberry <---> arduino is as follows

SDA <---> A 4
SDL <---> A 5
GND <---> GND

Now we need to install i2c-devel and python-smbus on the raspberry. Arduino just needs to include Wire.h.
Please see the guide above for the single steps.

What you need on Arduino side is basically:
#include <Wire.h>
#define SLAVE_ADDRESS 0x04
for gettint and recieving data you need
Wire.onReceive(receiveData);
 Wire.onRequest(sendData);
 I wrote a combination from the old script and a new one, maybe you get the idea
#include 
 
#define SLAVE_ADDRESS 0x04
int output = 0;
int input = 0;
int state = 0;
int sensorPin = 0;
 
double temp;
double c1;
double c2;
 
void setup() {
 pinMode(13, OUTPUT);
 // initialize i2c as slave
 Wire.begin(SLAVE_ADDRESS);
 Serial.begin(9600);
 
 // define callbacks for i2c communication
 Wire.onReceive(receiveData);
 Wire.onRequest(sendData);
}
 
 
 void loop(){
  delay (1000);
  double c1 = GetExtTemp();
  double c2 = GetIntTemp();
  Serial.print(c1); Serial.print(" : ");Serial.println(c2);
 }
 
// callback for received data
void receiveData(int byteCount){
 
 while(Wire.available()) {
  input = Wire.read();
  Serial.print(input);Serial.println(" in");
  if (input == 1){
   if (state == 0){
    digitalWrite(13, HIGH); // set the LED on
    state = 1;
   } else{
    digitalWrite(13, LOW); // set the LED off
    state = 0;
   }
  }
 
  if(input == 2) {
   output = (int)c1;
   Wire.write(output);
  }
  
  if(input == 3) {
   output = (int)c2;
  }
  
 }
}
 
// callback for sending data
void sendData(){
 Wire.write(output);
}
 
// Get the internal temperature of the arduino
double GetExtTemp(void)
{
 delay (100);
 int reading = analogRead(sensorPin);
 double voltage = reading * 5.0;
 voltage /= 1024.0;
 double temperatureC = (voltage - 0.5) * 100 ;
 temp = temperatureC;
 return (temp);
}

double GetIntTemp(void)
{
 unsigned int wADC;
 double t;
 ADMUX = (_BV(REFS1) | _BV(REFS0) | _BV(MUX3));
 ADCSRA |= _BV(ADEN); // enable the ADC
 delay(20); // wait for voltages to become stable.
 ADCSRA |= _BV(ADSC); // Start the ADC
 while (bit_is_set(ADCSRA,ADSC));
 wADC = ADCW;
 t = (wADC - 324.31 ) / 1.22;
 return (t);
}
On raspberry side you can do (python):
import smbus
bus = smbus.SMBus(1)
deviceaddy = 4x04 // same addy as above
bus.read_byte_data(deviceaddy, 2) // 1,2,3 should work
With the arduino programm above you should be able to recieve:


  1. Switch LED ON/OFF
  2. Get external tempereature from analog sensor
  3. get internal arduino temperature

Update: Well, i killed it somewhere, i dont get an correct data on my raspberry while the arduino serial output is all good. If someone has an hint :-)