Go Down

Topic: Wireless control of Arduino with RPi (Read 376 times) previous topic - next topic

ChrisHigs

I currently have a Raspberry Pi logging temperatures to a database received from two Arduinos sending their data with nRF24L01 modules. I want to extend the system so the Pi can control other Arduinos using a web interface on the Pi but I'm not sure how to implement it.

I have my TempReceiver program  running on the Pi continuously listening for data. I'm not sure where to go from there. Do I interact with that program somehow? Run another program when the web interface requests something? Can I run another program to send something to an Arduino while the receiver program is also running?

Can you post the scripts how you collect data from multiple transmiters, please?

ChrisHigs

Yeah, no problem. The code on the Arduino is pretty straight forward. Each device has an ID, takes the temp and sends it to node 0.

The code on the Pi is a bit of a cobbled together mess. Receives the data, works out the ID, opens a file to write to but also saves it to a sqlite database and outputs it to the screen.

Arduino code:

Code: [Select]

#include <OneWire.h>
#include <DallasTemperature.h>
#include "LowPower.h"
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>


//Device specific stuff
int device=2;
const uint16_t this_node = 02;

DeviceAddress Probe01 = {
  0x28, 0xFF, 0x1E, 0x2A, 0x68, 0x14, 0x04, 0xCB
};
//End device specific stuff

int led=13;
int battery=A0;




#define ONE_WIRE_BUS 2





OneWire oneWire(ONE_WIRE_BUS);


DallasTemperature sensors(&oneWire);



RF24 radio(9,10);                    // nRF24L01(+) radio attached using Getting Started board

RF24Network network(radio);          // Network uses that radio

const uint16_t other_node = 00;       // Address of the other node in Octal format


struct payload_t {                  // Structure of our payload
  float temp;
  int voltage;
  int deviceNum;
};

int counter=1;

void setup(void)
{
  sensors.begin();
  sensors.setResolution(12);
  SPI.begin();
  radio.begin();
  network.begin(/*channel*/ 90, /*node address*/ this_node);
  pinMode(led, OUTPUT);

}

void loop() {
  if (counter==8)
  {
    digitalWrite(led, HIGH);
  
    sensors.requestTemperatures();
    float temp=sensors.getTempC(Probe01);
    int battInt=0;
    battInt=analogRead(battery);
    battInt=analogRead(battery);
  
    if (temp<80)
    {
      radio.powerUp();
      network.update();
      payload_t payload = {
        temp,battInt, device};
    
      RF24NetworkHeader header(/*to node*/ other_node);
      bool ok = network.write(header,&payload,sizeof(payload));
       //if (ok)
       //   Serial.println("ok.");
       // else
       //   Serial.println("failed.");
      radio.powerDown();
    }
    counter=1;
    digitalWrite(led, LOW);
  }
  else
  {
    counter++;
  }


  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
}




Raspberry Pi code:

Code: [Select]

#include <cstdlib>
#include <dirent.h>
#include <iostream>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sqlite3.h>
#include <signal.h>
#include <RF24/RF24.h>
#include <RF24Network/RF24Network.h>
#include <ctime>
#include <stdio.h>
#include <time.h>
#include <sstream>
#include <sys/time.h>

int8_t volatile keepRunning = 1;

// Pointer to Sqlite3 DB - used to access DB when open
sqlite3 *db = NULL;
// Path to DB file - same dir as this program's executable
char *dbPath = "/var/www/sqlTemplog.db";
// DB Statement handle - used to run SQL statements
sqlite3_stmt *stmt = NULL;


FILE *f;

int counter=1;

int8_t recordTemp(int devID, double tempC) {
 char *sql = "INSERT INTO temps( id, timestamp, temp) VALUES(?,datetime('now'), ?)";
 if(!sqlite3_prepare_v2(db, sql, strlen(sql), &stmt, NULL)== SQLITE_OK)
 {
        fprintf(stderr, "MEhhdfsd: %s\n", sqlite3_errmsg(db));
    }
 
     sqlite3_bind_int(stmt, 1, devID);
     sqlite3_bind_double(stmt, 2, tempC);
     sqlite3_step(stmt);  // Run SQL INSERT
     sqlite3_reset(stmt); // Clear statement handle for next use
 return 0;
}



void intHandler() {
    printf("\nStopping...\n");
    keepRunning = 0;
}


//struct dataStruct{

 // unsigned long ms;
 // unsigned long counter;
 // float temp;

//}myData;

/**
 * g++ -L/usr/lib main.cc -I/usr/include -o main -lrrd
 **/
//using namespace std;

// CE Pin, CSN Pin, SPI Speed

// Setup for GPIO 22 CE and GPIO 25 CSN with SPI Speed @ 1Mhz
//RF24 radio(RPI_V2_GPIO_P1_22, RPI_V2_GPIO_P1_18, BCM2835_SPI_SPEED_1MHZ);

// Setup for GPIO 22 CE and CE0 CSN with SPI Speed @ 4Mhz
//RF24 radio(RPI_V2_GPIO_P1_15, BCM2835_SPI_CS0, BCM2835_SPI_SPEED_4MHZ);

// Setup for GPIO 22 CE and CE1 CSN with SPI Speed @ 8Mhz
RF24 radio(RPI_V2_GPIO_P1_15, BCM2835_SPI_CS0, BCM2835_SPI_SPEED_8MHZ);  

RF24Network network(radio);

// Address of our node in Octal format
const uint16_t this_node = 00;

// Address of the other node in Octal format (01,021, etc)
const uint16_t other_node = 01;
const uint16_t clock_node = 03;

//const unsigned long interval = 2000; //ms  // How often to send 'hello world to the other unit

unsigned long last_sent;             // When did we last send?
unsigned long packets_sent;          // How many have we sent already


struct payload_t {                  // Structure of our payload
  float temp;
  uint16_t voltage;
  uint16_t deviceNum;
};

struct payload_temp {
float temp;
};

struct payload_time{
int hours;
int minutes;
int seconds;
};

struct payload_voltage{
uint16_t volts;
};

int main(int argc, char** argv)
{
int rc = sqlite3_open(dbPath, &db);
// If rc is not 0, there was an error
if(rc)
{
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
exit(0);
}
// Refer to RF24.h or nRF24L01 DS for settings

radio.begin();
//radio.setDataRate(RF24_250KBPS);
delay(5);
network.begin(/*channel*/ 90, /*node address*/ this_node);
radio.printDetails();

//uint16_t deviceNumber;


while(keepRunning)
{

network.update();
while ( network.available() )
{    


RF24NetworkHeader header;
network.peek (header);

{
payload_t payload;
network.read(header,&payload,sizeof(payload));
float battVolts = payload.voltage * 0.0033248;


if (payload.voltage>0)
printf("Received payload # %i at %f %fV ",payload.deviceNum,payload.temp, battVolts);
else
printf("Received payload # %i at %f \n", payload.deviceNum, payload.temp);
if (payload.deviceNum==1)
f = fopen( "/home/pi/temp1.log", "a");
else if (payload.deviceNum==2)
f = fopen("/home/pi/temp2.log", "a");
else
f=fopen("/home/pi/volts.log", "a");
recordTemp(payload.deviceNum, payload.temp);


timeval curTime;
gettimeofday(&curTime, NULL);

char TimeString[128];

strftime(TimeString, 80, "%Y-%m-%d %H:%M:%S", localtime(&curTime.tv_sec));

char deviceNum[1];
sprintf(deviceNum, "%i", payload.deviceNum);
fprintf(f, deviceNum);
fprintf(f, ",");

char temp[4];
sprintf(temp, "%f", payload.temp);
fprintf(f, TimeString);
fprintf(f, ",");
fprintf(f, temp);


if (payload.voltage>0)
{
fprintf(f, ",");
char volts[4];
sprintf(volts, "%f", battVolts);
fprintf(f, volts);
//printf(payload.voltage);
}

fprintf(f, "\r\n");
fclose(f);
//printf("Close file\n");
//if (payload.deviceNum==1)counter=1;

if (payload.deviceNum==2)
{
float tempFF=payload.temp;
payload_temp payload = { tempFF };
RF24NetworkHeader header(/*to node*/ clock_node, 'T');
bool ok = network.write(header,&payload,sizeof(payload));
if (ok)
printf(" - sent.\n");
else
printf("\n");
}

}
}


usleep(100000);
//fclose(pFile);
//counter=counter+1;
}
sqlite3_close(db);
return 0;
}



ChrisHigs

#3
Mar 25, 2015, 10:16 pm Last Edit: Mar 25, 2015, 10:19 pm by ChrisHigs
I've got v0.2 of my wireless board up and running. Now clocked at 4MHz so I can run it down to 1.8V. Switching the power to the DS18B20 and radio through the digital pins, and the temp sensor powered by a step up regulator.

Some optimisations to the code, only sends the temp if it has changed, or if 10 minutes has passed.

The only problem with this setup is switching the temperature sensor on and off requires a delay when it first starts up so it can read the temp. So it's running for almost 1 second every time it wakes up.

pieman

I've got v0.2 of my wireless board up and running. Now clocked at 4MHz so I can run it down to 1.8V. Switching the power to the DS18B20 and radio through the digital pins, and the temp sensor powered by a step up regulator.

Some optimisations to the code, only sends the temp if it has changed, or if 10 minutes has passed.

The only problem with this setup is switching the temperature sensor on and off requires a delay when it first starts up so it can read the temp. So it's running for almost 1 second every time it wakes up.
Could you please upload your revised code and a few details of the Pi setup.
I have a couple of the NRF's, several Pi's and lots of Arduinos.
Does the Pi code you provided need compiling on the Pi and if so could you provide the full command line required to do this?

ChrisHigs

Made some more adjustments. Using the 3.3V step up to power it all again now. I thought that was causing my battery problems but it was something else.

The Arduino now shuts down when the sensor is converting the temp, saves a bit of power because it was using delay() before.

I've also got a red LED which I power on for a bit if the sensor's values are out of range or it's not connected.

I'll try and remember what I did with the pi, tidy up the code a bit and try and post it later.

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy