//********************************************************************************************* // RangeTest_Gateway (to be used with an RFGateway or similar Moteino) // Adapted from Gateway firmware sketch // Acts as a listener for testing RF performance, in tandem with a RangeTest_Transmitter //********************************************************************************************* // Copyright Felix Rusu 2021, http://www.LowPowerLab.com/contact //********************************************************************************************* #include //https://www.github.com/lowpowerlab/rfm69 #include //https://www.github.com/lowpowerlab/rfm69 #include //https://github.com/olikraus/u8g2/wiki/u8g2reference fonts:https://github.com/olikraus/u8g2/wiki/fntlistall #include //i2c scanner: https://playground.arduino.cc/Main/I2cScanner #include //easy string manipulator: http://arduiniana.org/libraries/pstring/ #include //easy C++ style output operators: http://arduiniana.org/libraries/streaming/ //********************************************************************************************* // *********** IMPORTANT SETTINGS - YOU MUST CHANGE/ONFIGURE TO FIT YOUR HARDWARE ************* //********************************************************************************************* #define NODEID 1 //unique for each node on same network #define NETWORKID 100 //the same on all nodes that talk to each other #define FREQUENCY RF69_915MHZ //others: RF69_433MHZ, RF69_868MHZ, match to radio variant on your Moteino/board #define ENCRYPTKEY "sampleEncryptKey" #define IS_RFM69HW_HCW //assumes RFM69 HCW/HW, remove if you have RFM69 W/CW #define ENABLE_ATC //comment out to disable AUTO TRANSMISSION CONTROL (ie. always transmit at max power) //********************************************************************************************* #define SERIAL_BAUD 500000 //this works with 0% error on all LowPowerLab boards, for SAMD it is irrelevant #define LED LED_BUILTIN #define BUZZER 6 //*********************************************************************************************************** #define OLED_BAUD 1600000 //fast i2c clock #define OLED_ADDRESS 0x3C //i2c address on most small OLEDs U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); //*********************************************************************************************************** #define LED_HIGH digitalWrite(LED, HIGH) #define LED_LOW digitalWrite(LED, LOW) #ifdef ENABLE_ATC RFM69_ATC radio; #else RFM69 radio; #endif #ifdef SERIAL_BAUD #define DEBUG(input) Serial.print(input) #define DEBUGln(input) Serial.println(input) #define DEBUGHex(input) Serial.print(input, HEX) #define DEBUGFlush() Serial.flush() #else #define DEBUG(input) #define DEBUGln(input) #define DEBUGHex(input) #define DEBUGFlush() #endif #define MSG_MAX_LEN 30 //don't need more for testing purposes #define HISTORY_LEN 9 //hold this many past messages - to display on OLED at small font size byte OLEDfound=false; char buff[61]; PString Pbuff(buff, sizeof(buff)); //easy string manipulator byte ackCount=0; byte lastMessageIndex = HISTORY_LEN; byte historyLength = 0; uint16_t senderID; int rxRSSI; typedef struct { char msg[MSG_MAX_LEN]; int rssi; uint16_t from; byte pinged; byte pingedOK; } Message; Message * messageHistory = new Message[HISTORY_LEN]; void setup() { pinMode(BUZZER, OUTPUT); pinMode(LED, OUTPUT); Serial.begin(SERIAL_BAUD); radio.initialize(FREQUENCY,NODEID,NETWORKID); #ifdef IS_RFM69HW_HCW radio.setHighPower(); #endif radio.encrypt(ENCRYPTKEY); DEBUG(F("Listening at ")); DEBUG(radio.getFrequency()); DEBUGln(F(" Hz..")); DEBUGln(buff); Pbuff = F("Listening at "); Pbuff.print(radio.getFrequency()); Pbuff.print(F("Hz...")); DEBUGln(buff); delay(1000); //Wire apparently needs 50ms Wire.begin(); Wire.beginTransmission(OLED_ADDRESS); byte error = Wire.endTransmission(); if (error == 0) { DEBUG(F("OLED FOUND at 0x")); DEBUGln(OLED_ADDRESS); u8g2.begin(); u8g2.setDisplayRotation(U8G2_R2); //if required (inside/custom mount?) u8g2.setBusClock(OLED_BAUD); OLEDfound = true; } else { DEBUGln(F("NO OLED found...")); } DEBUGFlush(); u8g2.clearBuffer(); u8g2.setFont(u8g2_font_8x13B_tf); u8g2.setCursor(0,10); u8g2.print("OLED PKT CAPTURE"); u8g2.sendBuffer(); delay(1000); } void loop() { if (radio.receiveDone()) { LED_HIGH; senderID = radio.SENDERID; rxRSSI = radio.RSSI; DEBUG('[');DEBUG(senderID);DEBUG(F("] ")); DEBUG((char*)radio.DATA); DEBUG(F(" [RX_RSSI:"));DEBUG(rxRSSI);DEBUG(F("]")); Pbuff = ""; Pbuff.print(radio.SENDERID); Pbuff.print(' '); Pbuff.print((char*)radio.DATA); Pbuff.print(' '); Pbuff.print(radio.RSSI); if (radio.ACKRequested()) { radio.sendACK(); if (++ackCount%3==0) { DEBUG(F(" Pinging [")); DEBUG(senderID); DEBUG(F("]:")); delay(3); //need this when sending right after reception .. ? //if (radio.sendWithRetry(senderID, "ACK TEST", 8, 0)) { // 0 = only 1 attempt, no retries if (radio.sendWithRetry(senderID, "ACK TEST", 8)) { DEBUG(F("OK!")); Pbuff.print(" OK"); } else { DEBUG(F("nothing")); Pbuff.print(" NOK"); } } } DEBUGln(); saveToHistory(buff); DEBUGln(); if (OLEDfound) draw(); DEBUGln(); LED_LOW; } //LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); } void draw() { u8g2.clearBuffer(); u8g2.setFont(u8g2_font_tom_thumb_4x6_tf); byte offset=0; for (byte i=lastMessageIndex+1; i