RFM69HW data bridge to ESP8266 WiFi

Started by fapuc, February 09, 2015, 05:36:40 PM

fapuc

Good Morning,
I did some tests with RFM69HW on "Moteino board" very well.
But I would make a bridge to WiFi modules ESP8266.
My problem is to switch off the WiFi module for the time necessary to receive data from RFM69 at 868MHZ that otherwise the conteporaneità drastically reduces the reception signal RSSI of RFM69.
Tried with code attached, but without satisfactory results.
In my opinion it would be a useful thing true integration also ardware
unique form board of new " Moteino WiFi" that supports both connections, 433/868 MHZ and 2.4GHZ WiFi
// *********************************************************************************
//  OK compilato con ide 1.0.6 x Moteino seleziona tipo arduino = uno !!
//  Prima configurato con tools  ESP8266 Config v1.0.0.0 V. 9600 b/s
//  solo STA ,Set mode, single, e SIID e PWD
// ******************************************************************* [email protected]
// Arduino with Wi-Fi module ESP8266 sending data to Xively
// Programm is based on http://www.seeedstudio.com/wiki/WiFi_Serial_Transceiver_Module
// Programm is based on esp8266_test.ino at https://gist.github.com/vindolin/d7f99c9a5855d29ce938
// Arduino serial is used for programming and debuging
// ESP8266 firmware needs to be updated for example to 0.922 that supports 9600 speed https://nurdspace.nl/ESP8266
// ******************************************************************* [email protected]
// Questo sopra perch  lib <SoftwareSerial.h> supporta max velocit  = 9600 speed.
// Firmware nativo con cui arrivati moduli 0.9.2.4  sono gi  ok per 9600 speed.
// ******************************************************************* [email protected]
// EPS8266 is connected via arduino software serial at 9600 speed
// keyboard shortcuts: CRTRL+U = upload , CTRL+SJHIFT+M open Serial monitor

#include <SoftwareSerial.h>
#include <stdlib.h>
#define LED_PIN 9               //   9 x moteino Led a bordo per arduino standard
#define CH_PD_PIN 4    			// 
#define RST_PIN 5      			//  
SoftwareSerial dbgSerial(6, 7); // 6 ,7 x moteino  RX, TX   a questi pin connesso TX, RX,  di  ESP8266 (modulo WiFi) + GND 
//************
#include <RFM69.h>
#include <SPI.h>
#include <SPIFlash.h>
#define NODEID      1
#define NETWORKID   100
#define FREQUENCY   RF69_868MHZ //Match this with the version of your Moteino! (others: RF69_433MHZ, RF69_868MHZ)
#define KEY         "thisIsEncryptKey" //has to be same 16 characters/bytes on all nodes, not more not less!
#define LED         9
#define SERIAL_BAUD 9600
#define ACK_TIME    30  // # of ms to wait for an ack
#define IS_RFM69HW    //uncomment only for RFM69HW! Leave out if you have RFM69W!

RFM69 radio;
SPIFlash flash(8, 0xEF30); //EF40 for 16mbit windbond chip
bool promiscuousMode = false; //set to 'true' to sniff all packets on the same network



typedef struct {		
  int           nodeId; 				//store this nodeId
  unsigned long uptime; 				//uptime in ms
  float         temperature;   			//temperature maybe?
} Payload;
Payload theData;




void sendData(String); 
float temperature, humidity;
String temperature_s, humidity_s;
String test="                                  ";  // used for storing temporary things
char buffer[10]; 								   // used for temporary things
bool connects=false;

void setup() {
    Serial.begin(SERIAL_BAUD);
  delay(10);
  radio.initialize(FREQUENCY,NODEID,NETWORKID);
  radio.setHighPower(); //uncomment only for RFM69HW!
  //radio.encrypt(KEY);
  //radio.promiscuous(promiscuousMode);
  char buff[50];
  sprintf(buff, "\nListening at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
  Serial.println(buff);
  if (flash.initialize())
    Serial.println("SPI Flash Init OK!");
  else
    Serial.println("SPI Flash Init FAIL! (is chip present?)");
  
  
  
  
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);  // green LED should go on when data are sent and off after success
  pinMode(CH_PD_PIN, OUTPUT);
  pinMode(RST_PIN, OUTPUT);
  
  
  dbgSerial.begin(9600);
  Serial.begin(9600);
  dbgSerial.setTimeout(2000); 
  Serial.setTimeout(2000);
  
  //sensors.begin();   // **************** per Ds1820
  

  resetESP();                  // reset modulo
}

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Loop*/

byte ackCount=0;
void loop() {

    //humidity = 50 + random(100)/2.1;        //  genera dati da inviare casualmente *************
    // temperature=20- random(100)/3.1;       //  genera dati da inviare casualmente *************
                                              //  da implementare un sensore vero !!!
    //process any serial input
  

  if (radio.receiveDone())
  {
   // Serial.print('[');Serial.print(radio.SENDERID, DEC);Serial.print("] ");
      Serial.print("[da nodeID ");
      Serial.print(radio.SENDERID, DEC);
    //Serial.print(radio.TARGETID, DEC);
      Serial.print("] ");

    Serial.print(" [RX_RSSI:");Serial.print(radio.readRSSI());Serial.print("]");
    if (promiscuousMode)
	{
      Serial.print("to [");Serial.print(radio.TARGETID, DEC);Serial.print("] ");
    }
	
    if (radio.DATALEN != sizeof(Payload))
      Serial.print("Invalid payload received, not matching Payload struct!");
    else
    {
      theData = *(Payload*)radio.DATA; //assume radio.DATA actually contains our struct and not something else
      //Serial.print(" nodeId=");
      //Serial.print(theData.nodeId);
      //Serial.print(" uptime=");
      //Serial.print(theData.uptime);
      Serial.print("temperature = ");
      Serial.print(theData.temperature);
    
    
  
     }
    
    Serial.println();
    Blink(LED,3);
    }
  
  
  
  
  
  
  
  
  
  
  
  Serial.flush();dbgSerial.flush();
  digitalWrite(CH_PD_PIN, 1); // bring up ESP8266 from power-down mode. It resets.
  Serial.println("Waking up...");
  Serial.println(dbgSerial.readString());
  
  resetESP();		     // reset modulo
  //networksAround();        // disabilitato il Retrieving the list of visible network
  init_wifi();
  
 
      //Serial.println(sensors.getTempCByIndex(0));  
      //int T = sensors.getTempCByIndex(0);
      //float T = sensors.getTempCByIndex(0);
      //float temperatuee = sensors.getTempCByIndex(0);
      Serial.print (" gradi C = ");
      Serial.println (temperature);
      delay(300); 
  
  
  xively_put(temperature, humidity) ;
  
  
  dbgSerial.println("AT+CIPCLOSE");
  digitalWrite(CH_PD_PIN, 0);  // activate PD power-down pin of ESP8266 !!  AUMENTARE IL TEMPO  PER RICEVERE TRAMITE 868 MHZ
  Serial.println("sleeping...");
  
  
  delay(1000);                 //  aumentato delay  ********************************************
  
    

}


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Loop*/




void init_wifi() {                                                  // connessione modulo WiFi al router e ottiene indirizzo IP

//  dbgSerial.flush(); 
//  Serial.flush(); 
  Serial.println("Connecting to AP");
  Serial.println(dbgSerial.readString());

      sendData("AT+CWJAP=\"SSID\",\"PASSWORD\"");                   // connect to router "SSID", "passwd"
  //  sendData("AT+CWJAP=\"OpenWrt\",\"\"");                        // connect to router "SSID", "passwd" x router "Open"
      delay(4000);                                                  //**********************aggiunto

  for (int n=0;n<10;n++){                                           // 10 tentativi per ottenere indirizzo ip

			sendData("AT+CIFSR");  											// ask what IP address is obtained from router 
			delay(500);                                                    //**********************aggiunto
     
			//if (dbgSerial.find("192")) {Serial.print("got IP address: 192"); Serial.println(dbgSerial.readString()); //modifica x mia rete 10.11.12.x
			if (dbgSerial.find("10")) {Serial.print("got IP address: 10"); Serial.println(dbgSerial.readString());   //modifica x mia rete 10.11.12.x
    
				connects=true; 			
				break;
    }
    else{
      connects=false; 
      Serial.println("can not get IP address");
    }
  }

Serial.print("connects=");
Serial.println(connects);
  if (connects==false){
    resetESP();
  }

}




/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
bool xively_put(float temperature, float humidity) {
  digitalWrite(LED_PIN, HIGH);

  dbgSerial.println("AT+CIPSTART=\"TCP\",\"64.94.18.120\",80");     // connsssione a internet delle cose !! [XIVELY]
  Serial.println("AT+CIPSTART=\"TCP\",\"64.94.18.120\",80");

  if(dbgSerial.find("Linked")) {
    Serial.println("Linked!");
  }

  delay(5000);                                                     //**********************aggiunto
  temperature_s=dtostrf(temperature,2,2,buffer);
  Serial.println(temperature_s);
  humidity_s=dtostrf(humidity,2,2,buffer);
  Serial.println(humidity_s);


  String data="PUT /v2/feeds/63063 HTTP/1.1\r\n"            
    "User-Agent: ESP8266\r\n"
    "Host: atomar.de\r\n"
    "Content-Type: application/json\r\n"
    "Content-Length: 136\r\n"
    "X-ApiKey: apikey ************************************\r\n"
    "\r\n"  
    "{\"version\":\"1.0.0\", \"datastreams\": [{\"id\": \"temperature\", \"current_value\": \"0      \"}, {\"id\": \"humidity\", \"current_value\": \"0      \"}]}\n";


  for(int i = 0; i < temperature_s.length(); i++) {
    data[259 + i] = temperature_s[i];
  }

  for(int i = 0; i < humidity_s.length(); i++) {
    data[307 + i] = humidity_s[i];
  }



  test="AT+CIPSEND=";   //length of message to be sent
  test+=data.length();
  sendData(test);     
  Serial.println(data); 
  dbgSerial.println(data); // send data away

  if(dbgSerial.find("X-Request-Id: ")) {                // analyse response from Xively server
    Serial.print("success X-Request-Id ");
    String request_id = dbgSerial.readStringUntil('\n');
    Serial.println(request_id);
    digitalWrite(LED_PIN, LOW);
    return true;
  } 
  else {
    Serial.println("no success to upload :(");
    return false;
  }
}



/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void networksAround(){

  dbgSerial.flush();
  for (int i=1;i<5;i++){
    sendData("AT+CWLAP");                     //Retrieving the list of visible network.
    delay(5000);
    Serial.println(dbgSerial.readString());   //+ CWLAP: <ecn>, <ssid>, <rssi> [, <mode>]    
  }
}



/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void resetESP(){
  digitalWrite(CH_PD_PIN, HIGH);       //power up 
  Serial.println("Resetting Wi-Fi"); 
  digitalWrite(RST_PIN, LOW); 
  delay(100); 
  digitalWrite(RST_PIN, HIGH); 
  delay(1000);
  sendData("AT+RST");
  delay(2000);
  if (dbgSerial.find("Ready")) Serial.println("Module is ready");
  else Serial.println("Module has no response.");    

  sendData("AT+CWMODE=1");   //single connection
  delay(500);

}




/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void sendData(String sendAway){
  dbgSerial.println(sendAway);
  Serial.println(sendAway);
}


void Blink(byte PIN, int DELAY_MS)
{
  pinMode(PIN, OUTPUT);
  digitalWrite(PIN,HIGH);
  delay(DELAY_MS);
  digitalWrite(PIN,LOW);
}

Felix

FYI you should not try to power the ESP8266 from the Moteino.

fapuc

it is true,
ESP8266 WiFi module is powered separately by its regulator to +3.3 Vcc with LM317 from battery outdoor + 8Vcc
I think the problem is in the code, that does not allow any  open windows of poweOFF WiFi ESP8266
waiting to receive data from another "Moteino remote" with temperature sensor on 866Mhz.
I tried with a cycle of waiting but I did not succeed after
code [------
dbgSerial.println ("AT + CIPCLOSE");
digitalWrite (CH_PD_PIN, 0); // Activate PD power-down pin of ESP8266 !!

.....the type
for (int n = 0; n <10; n ++)
print ...

in place of the current
delay (1000);

RFM69 the reception of a valid data should activate Interupt,
sometimes it happens but RSSI signal is very low -90 -100dBm

without [RS8266 WiFi] reception given RSSI of RFM69 jumps to -26 dbm
I hope I explained.
sorry for my poor english.

Rawze

#3
- I am planning on doing just this. The ESP8266's have come a long way and I have a few ESP8266-12F modules with the Arduino boot-loader on them. I have tested them for several days and at first, I was very impressed with them. I even started to re-think the Moteino network I have here, looking at possibly replacing them with all ioT ESP8266 modules. I got one of them up and running and wanted to put it into a motion light I have here out at the end of my driveway as a test. I went about taking the light apart and looked inside at the now very dusty Moteino in it that has just simply worked flawlessly. I pulled it out and realized right away that I would have to do some things to get this new ioT device up to working with this light.

This is when reality set in...

- I was going to loose the nice temp sensor built into the Moteino, and I really liked having it in all my devices. I also had 2 analog channels i needed, one for the solar light level off the solar panel, and the other for battery level. Moteino,.. no problem,... ESP8266?-- wha? only one analog? -- Grrr... and then comes the control for the light. The moteino is pwm and it is really cool to flash the motion light super bright a couple times quickly, simulating that it is taking your picture, then come on at normal brightness and fade to preserve battery life. All easily done right in the moteino,... grrr ... now I have to bit-bang a simulated pwm signal? -- yuk!

- There is one thing I want badly for all my Moteino projects though. I want to be able to collect all the io states and data into an sql database on my server. This would be great for data logging and for having an app for the phone and/or PC to tell them to do things (like flash/turn on that security light in the middle of the night from the phone). I also want to be able to stack commands out to them to run in sequence. The database would be great for doing this type of stuff, or displaying a data graph of the last months worth of solar data. Definitely something I want, and I don't want a Pi for it. I want to use the PC-based server I already have going to run it.

A bridge...

- All of the various Moteinos around my place here are programmed half-duplex. They receive on one common frequency and transmit on another. In a central location, with a 12-foot high antenna and a wall-powered Moteino Mega,... I have a hi-powered repeater to do all the broadcasting and heavy lifting of signals. It is also out of the way of any RF exposure to people or interference from other devices. Set up this way, all of the various moteinos, battery or otherwise, all they have to do is transmit low-power weak signals to that repeater that is so easy to reach with its high antenna. The repeater then re-transmits everything it hears, as its rx and tx frequencies are reversed so that all the devices hear very strongly, what each other are saying. Works fantastic and it even helps eliminate data collisions and other issues on a busy network.

--- The Idea struck me.... Instead of sticking that ESP8266 in that security light, how about wiring it to the repeater with i2c instead. I could forward any requests/commands and have it store all the data to/from the moteinos into the database directly to the wifi.  Send it all through the repeater both ways. --- Now, I can have that robust mysql database handle all of the traffic and data, and even make an app to load up a sequence of commands to all my Moteino minions!,.. Muaahah,.. I see some serious potential here, and it will only take one of the 8266s.

Instead of trying to make analog or bit-bang some pwm, I don't care how cheap those 8266s are, the solution I have is much better for me. ... Let that 8266 bit-bang away at i2c (seems to do that well, I tested it), and send to/from the database over the wifi And better yet --- Let the Moteinos do the actual work because that is what they do best. They just work and have analog, native pwm, SPI, and I don't need to add hardware just to read a battery voltage, solar level, and temp at the same time.

-- I say,...

Moteino's and the RFM69 RULES AND IS KING of wireless control!. Those 8266's have their place, but it ain't in no battery box with weather sensors and a security light. I would have to tripple the solar panel size to handle the hog of current it needs too. The heck with that!>  Where they would shine is to be in something that has a plug-in outlet to handle their power-hungry transmitter and talk to a Moteino if they want to do anything useful beyond a couple of digital IO's.

Just my own thoughts, no one has to agree.