arduino-libraries / MKRWAN

An Arduino library for sending and receiving data using LoRaWAN protocol and LoRa® radios.
https://www.arduino.cc
GNU Lesser General Public License v3.0
88 stars 60 forks source link

Support Class C #4

Open sabas1080 opened 6 years ago

sabas1080 commented 6 years ago

Hi @sandeepmistry

It is device and library support Class C?

thanks

facchinm commented 6 years ago

Hi @sabas1080 , the firmware on the Murata module fully supports Class C; the library doesn't, at the moment, but it's trivial to add it (the AT command is ATCLASS=C). Leaving this open so we can close it as soon as we add the command or a way to access it.

sabas1080 commented 6 years ago

December 2017

AN4967 Application note

"1. Only class A is supported with this release version."

examples of at commands on i cube lrwan

Here Source

facchinm commented 6 years ago

Mmmmh, it looks like ClassC-like behaviour is implemented here https://github.com/arduino/mkrwan1300-fw/blob/bd1878dbcd8212ce87fb810a3af08e7adb9a929b/Middlewares/Third_Party/Lora/Mac/LoRaMac.c#L2705 . I'll contact ST for a clarification on the documentation side.

mjunior-fitec commented 5 years ago

Hello @facchinm , I know this issue is more than one year old, but it still not clear to me. Does the MKRWAN1300 supports class C? The current library has the command to change the class(configureClass() function which sends a "AT+CLASS=" to the Murata), but it always return false on my tests. I try calling it with CLASS_A, CLASS_B and CLASS_C as the parameter, before or after a sucessful join. Same result always. My board has up to date firmware 1.1.9 and my lib is the latest, 1.0.10 version.

mjunior-fitec commented 5 years ago

Taking a brief look in the code it seems to be implemented in the at_DeviceClass_set function.

It is in the at.c file:

ATEerror_t at_DeviceClass_set(const char *param)
{
  MibRequestConfirm_t mib;
  LoRaMacStatus_t status;

  mib.Type = MIB_DEVICE_CLASS;
  switch (param[0])
  {
    case 'A':
    case 'B':
    case 'C':
      /* assume CLASS_A == 0, CLASS_B == 1, etc, which is the case for now */
      mib.Param.Class = (DeviceClass_t)(param[0] - 'A');
      status = LoRaMacMibSetRequestConfirm(&mib);
      CHECK_STATUS(status);
      break;
    default:
      return AT_PARAM_ERROR;
  }

  return AT_OK;
}

I think this is the farest I can go. Any ideas??? Thanks.

facchinm commented 5 years ago

This firmware is based on ST stack, version 1.1.2 . Latest one (1.2.1) supports all 3 classes, and there's not documentation anymore on which classes the older version supported. As far as I remember, class A and C are supported in the current fw, and should be invoked like AT+CLASS=A or AT+CLASS=C .

mjunior-fitec commented 5 years ago

Thanks for answering me @facchinm. Everything is working. The problem on my tests was that I was calling the configureClass() function right after the modem.begin() or the modem.joinOTAA attempt. I am not sure about the details but adding a delay(500) solves the issue. My MKRWAN1300 is working just fine on LoRaWAN class C.

Thanks again.

AB-informatica-service commented 4 years ago

hello @mjunior-fitec I can't set mkr wan 1300 in class c you could post a sketch example thanks

pykoon commented 4 years ago

Hi, you can look my code

  _DEBUG_PRINT("Module : ");      _DEBUG_PRINTLN(modem->version());
  _DEBUG_PRINT("Device EUI is: ");           _DEBUG_PRINTLN(modem->deviceEUI());
  delay(100);
  modem->configureClass(CLASS_C);
  delay(100); 
  modem->dutyCycle(true); 
  delay(50); 
  appKey = CRYPTO;
  appEui = CRYPTO;  
  appKey.trim();
  appEui.trim();
  connected = modem->joinOTAA(appEui, appKey);  
  if (!connected) {
    _DEBUG_PRINTLN("/!\\ LoRa : link error   !");
  }

Receive :

int receiv()
{
  int i=0;
  memset(receiv_frame,0,100);
  while (modem->available()) 
  {
    receiv_frame[i++] = modem->read();
  }
  #ifdef _DEBUG
    _DEBUG_PRINT("<<< Frame : ");
    for(int j=0; j<i;j++) _DEBUG_PRINT2(receiv_frame[j], HEX);
    _DEBUG_PRINTLN(" >>>");
  #endif

  if(i) action(); // Todo....

  return i;
}
AB-informatica-service commented 4 years ago

hi configured in class c but only works with otaa does not work in abp. I don't know if it's a bug place my code I had to add a time because it is not possible to leave it in contimuo listening. and so it works thanks

/*
  - Verificare se arriva Entrato criptato o no
*/

#include <MKRWAN.h>

LoRaModem modem;

// Uncomment if using the Murata chip as a module
// LoRaModem modem(Serial1);

String appEui = "0";
String appKey = "f936c5f76964b55dee244d4cf469b114";
const int valvola = 0;
const int flussostato = 2;

void setup() {
  pinMode(valvola, OUTPUT);
  pinMode(flussostato, INPUT);

  Serial.begin(115200);
  //while (!Serial);
  Serial.println("Console avviata");
  // change this to your regional band (eg. US915, AS923, ...)
  if (!modem.begin(EU868)) {
    Serial.print("Errore set modem 868");
    //Lempeggia LED ROSSO VELOCE se il modulo non riesce ad avviarsi
    digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
    delay(300);                       // wait for 300 millisecond
    digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
    delay(300);
    while (1) {}
  };
  Serial.println("Connessione modem effetuata");
  modem.configureClass(CLASS_C);

  int connected;

  appEui.trim();
  appKey.trim();
  Serial.println("Tento la connessione");
  connected = modem.joinOTAA(appEui, appKey);

  if (!connected) {
    Serial.println("NESSUNA CONNESSIONE");
    //Lempeggia LED ROSSO LENTO se il modulo non riesce ad avviarsi
    digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
    delay(1000);                       // wait for a second
    digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
    delay(1000);
    while (1) {}
  }
  Serial.println("Connessione effettuata");

  delay(5000);

  int err;
  modem.setPort(1);
  modem.beginPacket();
  modem.print("Entrato");
  err = modem.endPacket(true);
  if (err > 0) {
    Serial.println("messaggio inviato");
    //MESSAGGIO INVIATO
    //Lempeggia LED ROSSO leggermente veloce per tre volte
    digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)      PRIMO LAMPEGGIO
    delay(200);                       // wait for 3 second
    digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
    delay(200);
    digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)      SECONDO LAMPEGGIO
    delay(200);                       // wait for 3 second
    digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
    delay(200);
    digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)      TERZO LAMPEGGIO
    delay(200);                       // wait for 3 second
    digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
    delay(200);
  } else {
    Serial.println("Messaggio NON inviato");
    //MESSAGGIO NON INVIATO
    //RESTA LED ROSSO ACCESO FISSO SE NON COMUNICA
    digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  }
}

void loop() {
  delay(1000);
  if (!modem.available()) {
    return;
  } else {
    char rcv[64] = "";
    int i = 0;
    while (modem.available()) {
      rcv[i % 64] = (char)modem.read();
      ++i;
    }

    String messagio = rcv;
    Serial.println(messagio);

    if (messagio == "ON" ) {
      digitalWrite(valvola, HIGH);
      Serial.println("Valvola aperta");

      delay(30000);
      int statoFlussostato = digitalRead(flussostato);
      if (statoFlussostato == HIGH) {
        String msg = "Conferma apertura valvola";
        modem.setPort(1);
        modem.beginPacket();
        modem.print(msg);
        modem.endPacket(true);
      } else {
        String msg = "Errore";
        modem.setPort(1);
        modem.beginPacket();
        modem.print(msg);
        modem.endPacket(true);
      }
    }

    if (messagio == "OFF" ) {
      digitalWrite(valvola, LOW);
      Serial.println("Valvola chiusa");
      delay(30000);
      int statoFlussostato = digitalRead(flussostato);
      if (statoFlussostato == LOW) {
        String msg = "Conferma chiusura valvola";
        modem.setPort(1);
        modem.beginPacket();
        modem.print(msg);
        modem.endPacket(true);
      } else {
        String msg = "Errore";
        modem.setPort(1);
        modem.beginPacket();
        modem.print(msg);
        modem.endPacket(true);
      }
    }
  }
}
ceceghini commented 3 years ago

hi configured in class c but only works with otaa does not work in abp. I don't know if it's a bug place my code I had to add a time because it is not possible to leave it in contimuo listening. and so it works thanks

Ciao, vedo che scrivi dall'italia. Sei riuscito a far funzionare arduino mkr 1310 in class C.... a me non funziona propio grazie cesare

LasaleFamine commented 3 years ago

Hi there, I'm looking for Class C support too. Is it possible to have an official example about Class C?