LoRa Access Point 1.5.2018

Dependencies:   mbed ds3231 SX1276Lib_LoRa_Access_Point

Revision:
3:7a3ddda464bf
Parent:
2:0499e1d037a5
Child:
4:e20eb5efd859
--- a/RFM95W.cpp	Mon Apr 23 10:30:01 2018 +0000
+++ b/RFM95W.cpp	Mon Apr 23 21:28:36 2018 +0000
@@ -18,15 +18,18 @@
 
 RFM95W::RFM95W()
     : radio(NULL),
-      indicationLed(LED)
+      indicationLed(LED_PIN),
+      noise(NOISE_PIN)
 {
-//     messageNumbers ={[0 ... 254] = NULL};
     for(uint16_t i=0; i<MAX_DEVICES;i++)
-         messageNumbers[i]=NULL;
+        messageNumbers[i]=NULL;
     memset(receivedMessage, '\0', sizeof(receivedMessage));
     ledState = 0;
     timeOnAirSec = 0.3;
     indicationLed = 1;
+    messageNumber = GATEWAY_ID;
+    sendCounter = 0;
+    receivedAck = false;
 };
 
 void RFM95W::OnLedTick()
@@ -41,54 +44,113 @@
     ledState++;
 }
 
+void RFM95W::SendMessage()
+{
+    snprintf((char *)ack, 3, "%c%c%c",GATEWAY_ID, sendBuffer[0], messageNumber);
+    radio.Send( sendBuffer, 10 );       // poslem len 10 bajtov
+}
+
 void RFM95W::SendAck(uint8_t addr, uint8_t messageNumber)
 {
     uint8_t ack[3];
-    snprintf((char *)ack, sizeof(ack), "%d%d%c", addr, GATEWAY_ID, messageNumber);
+    snprintf((char *)ack, sizeof(ack), "%c%c%c", addr, GATEWAY_ID, messageNumber);
     pc.printf("Sending Ack : %s \r\n",ack);
     radio.Send(ack, 3);
 };
 
+float RFM95W::CalculateRandomTime()
+{
+    uint8_t number;
+    while(number == 0) {number = rand() % 1200;}
+    return (timeOnAirSec * (number / 200.0));
+};
+
+void RFM95W::OnCheckAck()
+{
+    if((receivedAck == false) && (sendCounter < MAX_RESENDS))
+    {
+        sendTicker.attach(callback(this,&RFM95W::OnSendAgain), CalculateRandomTime());
+/*        NumberOfFailSends++;
+        if(NumberOfFailSends >=3 )
+        {
+//            MessageAlter = !MessageAlter;           // ????????????????????????????????????????????????????????????????????????????????????????????????????????
+           NumberOfFailSends = 0;
+           sampleTicker.detach();
+           sampleTicker.attach(&onSampleTick,15.0);          // kazdych 15s
+        }
+*/
+    }
+    ackTicker.detach();
+};
+
+void RFM95W::OnSendAgain()
+{
+    SendMessage();
+    sendCounter++;
+    sendTicker.detach();
+};
+
 void RFM95W::OnTxDone( void )
 {
     radio.Sleep();
+    if(sendingAck)
+        sendingAck = false;
+    else
+    {
+        receivedAck = false;
+        ackTicker.attach(callback(this,&RFM95W::OnCheckAck),timeOnAirSec*3);
+    }
     radio.Rx(0);
 };
 
 void RFM95W::OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )
 {
     radio.Sleep();
-//    debug("%d \r\n", payload[0]-'0');
-    if(payload[0]-'0' == GATEWAY_ID) {
+//    debug("%d \r\n", payload[0]);
+    if(payload[0] == GATEWAY_ID) {
+        indicationLed=0;
+        ledTicker.attach(callback(this,&RFM95W::OnLedTick), LED_BLIK_PERIOD);
+        if((size == 3) && (strncmp( ( const char* )payload, ( const char* )ack, 3 ) == 0) ) 
+        {
+            receivedAck = true;
+            pc.printf("Received Ack : %s \r\n",ack);
+            messageNumber++;
+            if(messageNumber>255)
+                messageNumber = 0;
+            radio.Rx(0); 
+            return;
+        } 
+        sendingAck = true; 
         // moje ID - adresa brany, konverzia na cislo     
-        uint8_t MsgFrom = payload[1]-'0';           // konverzia na cislo
-        SendAck(MsgFrom,payload[2]);
-        pc.printf("MSG from : %d , message number received= %d \r\n",MsgFrom,payload[2]);
-        if(payload[2] == messageNumbers[MsgFrom])
+        uint8_t msgFrom = payload[1];           // konverzia na cislo
+        SendAck(msgFrom,payload[2]);
+        pc.printf("MSG from : %c , message number received= %d \r\n",msgFrom,payload[2]);
+        if(payload[2] == messageNumbers[msgFrom])
         {
             pc.printf("--------------------- Ta ista sprava -------------------- \r\n");
+ //           radio.Rx(0);
             return;
         }
-        messageNumbers[MsgFrom] = payload[2];
-        
+        messageNumbers[msgFrom] = payload[2]; 
         payload[2] = 48;        // ASCII hodnota cisla 0
-        pc.printf("Message number saved= %d \r\n",messageNumbers[MsgFrom]);
-        snprintf((char *)receivedMessage, BUFF_SIZE, "%d|%d|%s|\r\n", rssi, snr, payload);
+//        pc.printf("Message number saved= %d \r\n",messageNumbers[MsgFrom]);
+
+        memmove(payload, payload+4, size - 4 + 1);      // orezem prve styri bajty
+
+        snprintf((char *)receivedMessage, BUFF_SIZE, "%d|%d|%d|%d|%s|\r\n", rssi, snr, GATEWAY_ID, msgFrom, payload);
         wifi.SendMessage((char *)receivedMessage);
 //        debug_if( DEBUG_MESSAGE, "> OnRxDone\n\r" );
-        ledTicker.attach(callback(this,&RFM95W::OnLedTick), LED_BLIK_PERIOD);    
-        indicationLed=0;
-      
+  
         return;
     }
-      radio.Rx(0);                  // som zakomentil :P
+    radio.Rx(0);                  // som zakomentil :P
 };
 
 void RFM95W::OnTxTimeout( void )
 {
     radio.Sleep();
     Init();
-    radio.Rx(0);
+//    radio.Rx(0);
 };
 
 void RFM95W::OnRxTimeout( void )
@@ -106,6 +168,14 @@
 
 void RFM95W::OnCadDone( bool channelActivityDetected ){};
 
+void RFM95W::SendValue(uint8_t addr, float value)
+{
+    snprintf((char *)sendBuffer, BUFF_SIZE, "%c%c%c|%.2f|",addr, GATEWAY_ID, messageNumber, value);
+    sendCounter = 0;
+    receivedAck = false;
+    SendMessage();
+};
+
 void RFM95W::Init( void )
 {
     pc.printf( "\n\n\r------- RFM95W GATEWAY -------\n\r" );
@@ -171,7 +241,22 @@
     timeOnAirSec = (radio.TimeOnAir( MODEM_LORA, 10)/1000.0);              // time on air v ms
     pc.printf( "\n\n\r------- Time on air : %f sec. -------\n\r", timeOnAirSec);
     indicationLed = 1;
+    InitRandom();
+    messageNumber = rand();
     radio.Rx(0);
 };
 
-
+void RFM95W::InitRandom()
+{
+    uint32_t seed;
+    uint8_t loops = 3;
+    for (int i=0; i<(32*loops); i++) {
+        seed ^= noise.read_u16();
+        if (seed & 1<31) { // shift left and wrap.
+            seed <<= 1;
+            seed |= 1;
+        } else
+            seed <<= 1;
+    }
+    srand(seed);
+};