quinta-feira, 20 de janeiro de 2022

PROGRAMANDO WISOL LOM204 COM VISUINO E ACESSANDO CAYENNE

  

IMPORTANTE: Opção NÃO OFICIAL da WISOL, indicamos uso do KEIL C

VERSÃO BETA - SPI 2 não implementado

O objetivo deste BLOG é demonstrar como é possível programar o módulo WISOL LOM204A02 via VISUINO e assim utilizá-lo como OPENCPU (atualmente programado com o KEIL C).

IMPORTANTE: Opção NÃO OFICIAL da WISOL, indicamos uso do KEIL C




O exemplo gerará 3 COORDENADAS (x,y,z) (simulando um acelerômetro) a cada 20 segundos e então fará a publicação do Payload (formato Cayenne) no servidor loraWAN TTN e então encaminhado para um servidor myDevices para visualização. No exemplo, foi utilizado o  KIT LOM204A02 da Wisol, e como gateway LoraWAN um Dragino modelo LG308 e servidor TTN.

TTN
The Thing Network

A Rede de Coisas (TTN) é uma iniciativa iniciada pela sociedade civil holandesa. O objetivo é ter redes LoRaWAN instaladas em todas as cidades do mundo. Ao interconectar essas redes locais, a TTN quer construir uma infra-estrutura mundial para facilitar uma Internet das Coisas (IoT) pública.

A The Things Network (TTN) é o servidor IoT na nuvem utilizado nesse projeto. É um dos servidores gratuitos para LoRaWAN mais utilizados, com mais de 90 mil desenvolvedores, mais de 9 mil gateways de usuários conectados à rede ao redor do mundo e mais de 50 mil aplicações em funcionamento.

A TTN comercializa nós e gateways LoRa e provê treinamento individual e coletivo para empresas e desenvolvedores que desejam utilizar o LoRa. Possui uma comunidade bem ativa nos fóruns, sempre colaborando e ajudando a resolver problemas, além de prover diversos meios de integrar a TTN com a aplicação que se deseja usar. Possui integração nativa com diversas aplicações como: Cayenne (utilizado nesse trabalho), Hypertext Transfer Protocol (HTTP), permitindo ao usuário realizar uplink para um gateway e receber downlink por HTTP, OpenSensors e EVRYTHNG . Caso o usuário queira criar sua própria aplicação, a TTN disponibiliza Application Programming Interface (API) para uso com Message Queuing Telemetry Transport (MQTT) e diversos Software Developer Kits (SDK) para uso com as linguagens Python, Java , Node.Js , NODE-RED e Go

A rede TTN utiliza o protocolo LoRaWAN objetivando uma cobertura em longo alcance para os dispositivos da rede, caracterizando-a assim com uma Wide Area Network (WAN). Devido ao baixo consumo de energia e ao uso da tecnologia LoRa, é chamada de LPWAN (Low Power Wide Area Network). O grande diferencial da TTN é seu estabelecimento como uma rede aberta (open-source) e colaborativa (crowd-sourced), onde qualquer usuário pode contribuir instalando um gateway em sua residência.

Os elementos da TTN são classificados como: 

• Endpoints (nós): Os dispositivos responsáveis pela camada de sensoriamento da rede, o endpoint LoRaWAN. Podem coletar informações através de sensores e também acionar dispositivos/máquinas via atuadores. São configurados através de uma das três classes distintas do protocolo LaRaWAN; 

• Gateways: Elementos responsáveis por concentrar e processar as informações enviadas pelos endpoints. Os gateways em geral estão conectados a internet, seja por WiFi/Ethernet ou 3G/4G em locais remotos. Mesmo que uma mesma rede LoRaWAN tenha diferentes objetivos, baseados em aplicações distintas, os gateways possuem o objetivo comum de fornecer a maior área de cobertura possível; 

• Aplicações: Conectar e interligar os diferentes dispositivos da rede TTN para o fornecimento de informações gerais sobre a coleta de dados dos dispositivos.

VISUINO
O Visuino é o mais recente software inovador da Mitov Software. Um ambiente de programação visual que permite programar suas placas Arduino.
Os componentes encontrados no software Visuino representam seus componentes de hardware e você poderá criar e projetar facilmente seus programas usando arrastar e soltar. Nenhum equipamento ou hardware é necessário para executar o software no modo de design. Depois de ter concluído o design, você pode conectar o upload da placa Arduino e executá-lo.

Para aquelas pessoas que não são fortes em escrever código, em seguida, projetar, compilar e criar programas Arduino nunca foi tão fácil! Por que perder tempo criando código quando já se faz todo o trabalho duro para você? Você tem sua placa Arduino e um ótimo design de hardware, veja-a rodando em minutos, não em horas!

A missão da empresa é simplificar o mundo conectado, fornecendo ferramentas que permitam a criação de soluções de IoT agnósticas de dispositivos e conectividade para edifícios inteligentes, agricultura inteligente, rastreamento de ativos e outras verticais de IoT. MyDevices está sediada em Los Angeles, CA. Para mais informações, visite www.myDevices.com

Formato Cayenne

CayenneLPP é um formato projetado por myDevices para integrar os nódulos LoRaWan em sua plataforma IoT. Ele é usado para enviar dados de sensores de forma embalada para a plataforma The Things Network
O formato CayenneLPP é uma maneira bastante otimizada de enviar dados de sensores sobre conexão de baixa taxa de bits, como LoRa. Você pode encontrar, provavelmente, uma maneira melhor para o seu projeto específico, mas CayenneLPP é um formato standarized e comprovado que embala dados de forma suficiente.

Enfim, é um formato simplificado de payload para envio para TTN com intuito de usar o menos de Banda de transmissão. No servidor é decodificado este payload e identificado os sensores encapsulados, veja:

CayenneLPP lpp(100);

float Acc_x;
float Acc_y;
float Acc_z;

void printVariables()
{
    lpp.reset();
    lpp.addAccelerometer(4, Acc_x, Acc_y, Acc_z);
}

PS: código 4 = Coordenadas X,Y,Z de um acelerômetro.

O Cayenne Low Power Payload (LPP) fornece uma maneira conveniente e fácil de enviar dados sobre redes LPWAN, como LoRaWAN. O Cayenne LPP está em conformidade com a restrição de tamanho de carga, que pode ser reduzida para 11 bytes, e permite que o dispositivo final envie vários dados de sensor ao mesmo tempo.

Para usar o CayenneLPP Payload Formatter, o dispositivo deve enviar cargas binárias compatíveis com Cayenne. Para placas compatíveis com Arduino, a documentação sobre a alteração do seu Esboço Arduino para codificar dados com CayenneLPP pode ser encontrada na Documentação Cayenne da The Things Network. Informações gerais sobre a Carga De Carga CayenneLPP estão disponíveis no Repositório De Github CayenneLPP.

Uma vez configurado seu dispositivo para enviar cargas compatíveis com CayenneLPP, habilitar o CayenneLPP Payload Formatter adicionará um decoded_payload objeto a mensagens de uplink do seu dispositivo.

Por exemplo, os seguintes dados binários:

[0x3, 0x67, 0x01, 0x10, 0x05, 0x67, 0x00, 0xFF] produzirá as seguintes uplink_message:

{
  "uplink_message": {
    "f_port": 8,
    "f_cnt": 113,
    "frm_payload": "A2cBEAVnAP8=",
    "decoded_payload": {
      "temperature_3": 27.200000762939453,
      "temperature_5": 25.5
    },
  }
}

Biblioteca


Inclui decodificador totalmente invertido em JavaScript, adequado para implementações com NodeRED ou TTN, por exemplo.

Ao usar o decodificador, você deve instalar a biblioteca ArduinoJson 6.X. Você pode encontrá-lo tanto nos gerentes de bibliotecas Arduino.

Como utilizar LoRaWAN no VISUINO ?

Através do Custom Code do Visuino você pode incluir código em C/C++ 

Baixe o VISUINO PRO e instale


Foi Criado, não oficialmente , um VCOMP (Virtual Component) para o LOM204,  o qual pode ser baixado aqui.


Copie para a PASTA

C:\Users\Usuario\Documents\Arduino\libraries\Mitov\Visuino

Agora baixe o projeto


Abra o projeto!




Atenção, o VISUINO instalará o SDK "STM32" em 

C:\Users\Usuario\AppData\Local\Arduino15\packages

Podes apagar, deixe o baixado pela IDE do Arduino, para que faça referência ao SDK oficial do STM32.

C:\Users\Usuario\AppData\Local\Arduino15\packages\STMicroelectronics

Configurando Credenciais do TTN



LMIC LoRaWAN  Stack


Aqui você pode incluir o LMIC LoRaWAN Stack (colocado junto com as funções do programa Arduino)
//Cayenna PAYLOAD CayenneLPP lpp(100); // // For normal use, we require that you edit the sketch to replace FILLMEIN // with values assigned by the TTN console. However, for regression tests, // we want to be able to compile these scripts. The regression tests define // COMPILE_REGRESSION_TEST, and in that case we define FILLMEIN to a non- // working but innocuous value. // #ifdef COMPILE_REGRESSION_TEST # define FILLMEIN 0 #else # warning "You must replace the values marked FILLMEIN with real values from the TTN control panel!" # define FILLMEIN (#dont edit this, edit the lines that use FILLMEIN) #endif static osjob_t sendjob; //Trick uint8_t mydata[128]; char mydata_Aux[128]; // Schedule TX every this many seconds (might become longer due to duty // cycle limitations). const unsigned TX_INTERVAL = 20; // Pin mapping const lmic_pinmap lmic_pins = { .nss = RADIO_NSS, .rxtx = RADIO_ANT_SWITCH_HF, .rst = RADIO_RESET, .dio = {RADIO_DIO_0, RADIO_DIO_1, RADIO_DIO_2}, }; float Acc_x; float Acc_y; float Acc_z; void printVariables() { lpp.reset(); lpp.addAccelerometer(4, Acc_x, Acc_y, Acc_z); } void printHex2(unsigned v) { v &= 0xff; if (v < 16) Serial.print('0'); Serial.print(v, HEX); } void onEvent (ev_t ev) { Serial.print(os_getTime()); Serial.print(": "); switch(ev) { case EV_SCAN_TIMEOUT: Serial.println(F("EV_SCAN_TIMEOUT")); break; case EV_BEACON_FOUND: Serial.println(F("EV_BEACON_FOUND")); break; case EV_BEACON_MISSED: Serial.println(F("EV_BEACON_MISSED")); break; case EV_BEACON_TRACKED: Serial.println(F("EV_BEACON_TRACKED")); break; case EV_JOINING: Serial.println(F("EV_JOINING")); break; case EV_JOINED: Serial.println(F("EV_JOINED")); { u4_t netid = 0; devaddr_t devaddr = 0; u1_t nwkKey[16]; u1_t artKey[16]; LMIC_getSessionKeys(&netid, &devaddr, nwkKey, artKey); Serial.print("netid: "); Serial.println(netid, DEC); Serial.print("devaddr: "); Serial.println(devaddr, HEX); Serial.print("AppSKey: "); for (size_t i=0; i<sizeof(artKey); ++i) { if (i != 0) Serial.print("-"); printHex2(artKey[i]); } Serial.println(""); Serial.print("NwkSKey: "); for (size_t i=0; i<sizeof(nwkKey); ++i) { if (i != 0) Serial.print("-"); printHex2(nwkKey[i]); } Serial.println(); } // Disable link check validation (automatically enabled // during join, but because slow data rates change max TX // size, we don't use it in this example. LMIC_setLinkCheckMode(0); break; /* || This event is defined but not used in the code. No || point in wasting codespace on it. || || case EV_RFU1: || Serial.println(F("EV_RFU1")); || break; */ case EV_JOIN_FAILED: Serial.println(F("EV_JOIN_FAILED")); break; case EV_REJOIN_FAILED: Serial.println(F("EV_REJOIN_FAILED")); break; case EV_TXCOMPLETE: Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)")); if (LMIC.txrxFlags & TXRX_ACK) Serial.println(F("Received ack")); if (LMIC.dataLen) { Serial.print(F("Received ")); Serial.print(LMIC.dataLen); Serial.println(F(" bytes of payload")); } // Schedule next transmission os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send); break; case EV_LOST_TSYNC: Serial.println(F("EV_LOST_TSYNC")); break; case EV_RESET: Serial.println(F("EV_RESET")); break; case EV_RXCOMPLETE: // data received in ping slot Serial.println(F("EV_RXCOMPLETE")); break; case EV_LINK_DEAD: Serial.println(F("EV_LINK_DEAD")); break; case EV_LINK_ALIVE: Serial.println(F("EV_LINK_ALIVE")); break; /* || This event is defined but not used in the code. No || point in wasting codespace on it. || || case EV_SCAN_FOUND: || Serial.println(F("EV_SCAN_FOUND")); || break; */ case EV_TXSTART: Serial.println(F("EV_TXSTART")); break; case EV_TXCANCELED: Serial.println(F("EV_TXCANCELED")); break; case EV_RXSTART: /* do not print anything -- it wrecks timing */ break; case EV_JOIN_TXCOMPLETE: Serial.println(F("EV_JOIN_TXCOMPLETE: no JoinAccept")); break; default: Serial.print(F("Unknown event: ")); Serial.println((unsigned) ev); break; } } void do_send(osjob_t* j){ // Check if there is not a current TX/RX job running if (LMIC.opmode & OP_TXRXPEND) { Serial.println(F("OP_TXRXPEND, not sending")); } else { // Prepare upstream data transmission at the next possible time. printVariables(); LMIC_setTxData2(1, lpp.getBuffer(), lpp.getSize(), 0); Serial.println(F("Packet queued")); } // Next TX is scheduled after TX_COMPLETE event. }


Aqui foi necessário referenciar os #include do  LMIC LoRaWAN Stack (incluido no Topo do código Arduino)

#include <lmic.h> #include <hal/hal.h> #include <ArduinoJson.h> #include <CayenneLPP.h>

Aqui algumas inicializações do LMIC LoRaWAN Stack (modifique conforme sua BAND)
(Chamadas no Setup() do código Arduino)

//LOM204 pinMode(RADIO_TCXO_VCC_PIN,OUTPUT); digitalWrite(RADIO_TCXO_VCC_PIN,HIGH); //LOM204 Serial.begin(9600); Serial.println(F("Starting")); // LMIC init os_init(); // Reset the MAC state. Session and pending data transfers will be discarded. LMIC_reset(); LMIC_setClockError(MAX_CLOCK_ERROR * 1 / 100); LMIC_selectSubBand(1); //FSB2 start in 0 // Start job (sending automatically starts OTAA too) do_send(&sendjob);


Algumas configurações extras de GPIOS do LOM204 (Chamadas no Setup() do código Arduino)

pinMode(RADIO_TCXO_VCC_PIN,OUTPUT); digitalWrite(RADIO_TCXO_VCC_PIN,HIGH); pinMode(RADIO_ANT_SWITCH_PIN_RX,OUTPUT); digitalWrite(RADIO_ANT_SWITCH_PIN_RX,HIGH);



Selecionando entradas x,y,z para receber RANDOM (componente do VISUINO)



Acc_x = AValue;

Acc_y = AValue;

Acc_z = AValue;

Finalmente a inclusão no Loop() do Arduino

os_runloop_once();

Abaixo  o código completo

//---------------------------------------------- // // Sketch Generated by Visuino // www.visuino.com // //------------------ Source -------------------- // // lorawanDynamicCayenne.visuino // //---------------------------------------------- #define VISUINO_STMDUINO HardwareSerial Serial1(PB4, PB3); #include <OpenWire.h> #include <Mitov.h> #include <Mitov_StandardSerial.h> #include <lmic.h> #include <hal/hal.h> #include <ArduinoJson.h> #include <CayenneLPP.h> #include <Mitov_Text.h> #include <Mitov_BinaryGenerators.h> #include <Mitov_Counter.h> #include <Mitov_RandomGenerator.h> //Cayenna PAYLOAD CayenneLPP lpp(100); // // For normal use, we require that you edit the sketch to replace FILLMEIN // with values assigned by the TTN console. However, for regression tests, // we want to be able to compile these scripts. The regression tests define // COMPILE_REGRESSION_TEST, and in that case we define FILLMEIN to a non- // working but innocuous value. // #ifdef COMPILE_REGRESSION_TEST # define FILLMEIN 0 #else # warning "You must replace the values marked FILLMEIN with real values from the TTN control panel!" # define FILLMEIN (#dont edit this, edit the lines that use FILLMEIN) #endif static osjob_t sendjob; //Trick uint8_t mydata[128]; char mydata_Aux[128]; // Schedule TX every this many seconds (might become longer due to duty // cycle limitations). const unsigned TX_INTERVAL = 20; // Pin mapping const lmic_pinmap lmic_pins = { .nss = RADIO_NSS, .rxtx = RADIO_ANT_SWITCH_HF, .rst = RADIO_RESET, .dio = {RADIO_DIO_0, RADIO_DIO_1, RADIO_DIO_2}, }; float Acc_x; float Acc_y; float Acc_z; void printVariables() { lpp.reset(); lpp.addAccelerometer(4, Acc_x, Acc_y, Acc_z); } void printHex2(unsigned v) { v &= 0xff; if (v < 16) Serial.print('0'); Serial.print(v, HEX); } void onEvent (ev_t ev) { Serial.print(os_getTime()); Serial.print(": "); switch(ev) { case EV_SCAN_TIMEOUT: Serial.println(F("EV_SCAN_TIMEOUT")); break; case EV_BEACON_FOUND: Serial.println(F("EV_BEACON_FOUND")); break; case EV_BEACON_MISSED: Serial.println(F("EV_BEACON_MISSED")); break; case EV_BEACON_TRACKED: Serial.println(F("EV_BEACON_TRACKED")); break; case EV_JOINING: Serial.println(F("EV_JOINING")); break; case EV_JOINED: Serial.println(F("EV_JOINED")); { u4_t netid = 0; devaddr_t devaddr = 0; u1_t nwkKey[16]; u1_t artKey[16]; LMIC_getSessionKeys(&netid, &devaddr, nwkKey, artKey); Serial.print("netid: "); Serial.println(netid, DEC); Serial.print("devaddr: "); Serial.println(devaddr, HEX); Serial.print("AppSKey: "); for (size_t i=0; i<sizeof(artKey); ++i) { if (i != 0) Serial.print("-"); printHex2(artKey[i]); } Serial.println(""); Serial.print("NwkSKey: "); for (size_t i=0; i<sizeof(nwkKey); ++i) { if (i != 0) Serial.print("-"); printHex2(nwkKey[i]); } Serial.println(); } // Disable link check validation (automatically enabled // during join, but because slow data rates change max TX // size, we don't use it in this example. LMIC_setLinkCheckMode(0); break; /* || This event is defined but not used in the code. No || point in wasting codespace on it. || || case EV_RFU1: || Serial.println(F("EV_RFU1")); || break; */ case EV_JOIN_FAILED: Serial.println(F("EV_JOIN_FAILED")); break; case EV_REJOIN_FAILED: Serial.println(F("EV_REJOIN_FAILED")); break; case EV_TXCOMPLETE: Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)")); if (LMIC.txrxFlags & TXRX_ACK) Serial.println(F("Received ack")); if (LMIC.dataLen) { Serial.print(F("Received ")); Serial.print(LMIC.dataLen); Serial.println(F(" bytes of payload")); } // Schedule next transmission os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send); break; case EV_LOST_TSYNC: Serial.println(F("EV_LOST_TSYNC")); break; case EV_RESET: Serial.println(F("EV_RESET")); break; case EV_RXCOMPLETE: // data received in ping slot Serial.println(F("EV_RXCOMPLETE")); break; case EV_LINK_DEAD: Serial.println(F("EV_LINK_DEAD")); break; case EV_LINK_ALIVE: Serial.println(F("EV_LINK_ALIVE")); break; /* || This event is defined but not used in the code. No || point in wasting codespace on it. || || case EV_SCAN_FOUND: || Serial.println(F("EV_SCAN_FOUND")); || break; */ case EV_TXSTART: Serial.println(F("EV_TXSTART")); break; case EV_TXCANCELED: Serial.println(F("EV_TXCANCELED")); break; case EV_RXSTART: /* do not print anything -- it wrecks timing */ break; case EV_JOIN_TXCOMPLETE: Serial.println(F("EV_JOIN_TXCOMPLETE: no JoinAccept")); break; default: Serial.print(F("Unknown event: ")); Serial.println((unsigned) ev); break; } } void do_send(osjob_t* j){ // Check if there is not a current TX/RX job running if (LMIC.opmode & OP_TXRXPEND) { Serial.println(F("OP_TXRXPEND, not sending")); } else { // Prepare upstream data transmission at the next possible time. printVariables(); LMIC_setTxData2(1, lpp.getBuffer(), lpp.getSize(), 0); Serial.println(F("Packet queued")); } // Next TX is scheduled after TX_COMPLETE event. } // This EUI must be in little-endian format, so least-significant-byte // first. When copying an EUI from ttnctl output, this means to reverse // the bytes. For TTN issued EUIs the last bytes should be 0xD5, 0xB3, // 0x70. static const u1_t PROGMEM APPEUI[8]={ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8);} // This should also be in little endian format, see above. //88 57 1D FF FE EE 8C 64 static const u1_t PROGMEM DEVEUI[8]={ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8);} // This key should be in big endian format (or, since it is not really a // number but a block of memory, endianness does not really apply). In // practice, a key taken from ttnctl can be copied as-is. //48 4F 68 92 5E 6E 4C 82 E0 6C 9A EF CA 37 86 EA static const u1_t PROGMEM APPKEY[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; void os_getDevKey (u1_t* buf) { memcpy_P(buf, APPKEY, 16);} // Shared Component Member Variables namespace ComponentVariables { class { public: bool Value1 : 1; bool Value2 : 1; bool Value3 : 1; bool Value4 : 1; bool Value5 : 1; bool Value6 : 1; int32_t Value7 : 32; bool Value8 : 1; } BitFields; class Variable1 { public: inline static bool GetValue() { return BitFields.Value1; } inline static void SetValue( bool AValue ) { BitFields.Value1 = AValue; } }; class Variable2 { public: inline static bool GetValue() { return BitFields.Value2; } inline static void SetValue( bool AValue ) { BitFields.Value2 = AValue; } }; class Variable3 { public: inline static bool GetValue() { return BitFields.Value3; } inline static void SetValue( bool AValue ) { BitFields.Value3 = AValue; } }; class Variable4 { public: inline static bool GetValue() { return BitFields.Value4; } inline static void SetValue( bool AValue ) { BitFields.Value4 = AValue; } }; class Variable5 { public: inline static bool GetValue() { return BitFields.Value5; } inline static void SetValue( bool AValue ) { BitFields.Value5 = AValue; } }; class Variable6 { public: inline static bool GetValue() { return BitFields.Value6; } inline static void SetValue( bool AValue ) { BitFields.Value6 = AValue; } }; class Variable7 { public: inline static int32_t GetValue() { return BitFields.Value7; } inline static void SetValue( int32_t AValue ) { BitFields.Value7 = AValue; } }; class Variable8 { public: inline static bool GetValue() { return BitFields.Value8; } inline static void SetValue( bool AValue ) { BitFields.Value8 = AValue; } }; } // ComponentVariables // Arduino Constant Declarations namespace VisuinoConstants { class FloatValue2 { public: inline static constexpr float GetValue() { return 0.5; } }; class FloatValue0 { public: inline static constexpr float GetValue() { return 0.0500000007450581; } }; class FloatValue1 { public: inline static constexpr float GetValue() { return 0; } }; class TextValue0 { public: inline static constexpr const char *GetValue() { return "Count: "; } }; } // VisuinoConstants // Pin Call Declarations namespace PinCalls { class PinCallerReceive0 { public: void Notify( void *_Data ); }; class PinCallerReceive1 { public: void Notify( void *_Data ); }; class PinCallerReceive2 { public: void Notify( void *_Data ); }; class PinCallerReceive3 { public: void Notify( void *_Data ); }; class PinCallerReceive4 { public: void Notify( void *_Data ); }; class PinCallerReceive5 { public: void Notify( void *_Data ); }; } // PinCalls // Call Chains namespace CallChains { class Processed1 { public: inline static uint32_t Count() { return 1; } static void Call(); }; class CanProcess1 { public: inline static uint32_t Count() { return 1; } static void Call( bool & AResult ); }; class Process1 { public: inline static uint32_t Count() { return 1; } static void Call( Mitov::String &AText ); }; } // CallChains // Arduino Board Declarations namespace BoardDeclarations { namespace Types { typedef Mitov::SerialSTM32Port< SERIAL_TYPE, // 0_T_TYPE Serial, // 1_C_TYPE Mitov::ConstantProperty<4, uint32_t, 0 >, // AfterSendingDelay Mitov::ConstantProperty<7, uint32_t, 8 >, // DataBits Mitov::ConstantProperty<3, bool, true >, // Enabled Mitov::ConstantProperty<51, uint32_t, 0>, // FEndTime Mitov::ConstantProperty<50, bool, false>, // FSending Mitov::GenericPin_NoImplementation<5 >, // OutputPin Mitov::ConstantProperty<9, Mitov::TArduinoStandardSerialParity, Mitov::spNone >, // Parity Mitov::ConstantProperty<10, uint32_t, 10 >, // RXPin Mitov::DigitalPin_NoImplementation<2 >, // SendingOutputPin Mitov::ConstantProperty<6, uint32_t, 9600 >, // Speed Mitov::ConstantProperty<8, uint32_t, 1 >, // StopBits Mitov::ConstantProperty<11, uint32_t, 9 > // TXPin > SerialPort0; } // Types namespace Instances { Types::SerialPort0 SerialPort0; } // Instances namespace Types { typedef Mitov::ArduinoSerialInput_String<BoardDeclarations::Types::SerialPort0, BoardDeclarations::Instances::SerialPort0, char *> SerialPort0_Input_IOWStringStream_1; } // Types namespace Instances { Types::SerialPort0_Input_IOWStringStream_1 SerialPort0_Input_IOWStringStream_1; } // Instances namespace Types { typedef Mitov::SerialPort< SERIAL_TYPE, // 0_T_TYPE Serial1, // 1_C_TYPE Mitov::ConstantProperty<4, uint32_t, 0 >, // AfterSendingDelay Mitov::ConstantProperty<7, uint32_t, 8 >, // DataBits Mitov::ConstantProperty<3, bool, true >, // Enabled Mitov::ConstantProperty<51, uint32_t, 0>, // FEndTime Mitov::ConstantProperty<50, bool, false>, // FSending Mitov::GenericPin_NoImplementation<5 >, // OutputPin Mitov::ConstantProperty<9, Mitov::TArduinoStandardSerialParity, Mitov::spNone >, // Parity Mitov::DigitalPin_NoImplementation<2 >, // SendingOutputPin Mitov::ConstantProperty<6, uint32_t, 9600 >, // Speed Mitov::ConstantProperty<8, uint32_t, 1 > // StopBits > SerialPort1; } // Types namespace Instances { Types::SerialPort1 SerialPort1; } // Instances namespace Types { typedef Mitov::ArduinoSerialInput_String<BoardDeclarations::Types::SerialPort1, BoardDeclarations::Instances::SerialPort1, char *> SerialPort1_Input_IOWStringStream_1; } // Types namespace Instances { Types::SerialPort1_Input_IOWStringStream_1 SerialPort1_Input_IOWStringStream_1; } // Instances } // BoardDeclarations // Custom Code Declarations namespace CustomCode { class TCustomCodeLoraWAN_Stack1 { public: // Inputs inline void __Inputs_o_0_o_Receive( Mitov::String AValue ) { AValue.toCharArray(mydata_Aux,128); for(uint8_t i=0;i<AValue.length();i++) mydata[i] = mydata_Aux[i]; //String S = String(mydata_Aux); //Serial.println(S); } inline void __Inputs_o_1_o_Receive( int32_t AValue ) { Acc_x = AValue; } inline void __Inputs_o_2_o_Receive( int32_t AValue ) { Acc_y = AValue; } inline void __Inputs_o_3_o_Receive( int32_t AValue ) { Acc_z = AValue; } public: void SystemInit(); public: void SystemStart(); public: void SystemLoopUpdateHardware(); }; class TArduinoCustomCodeInputTextElement1 { public: void InputPin_o_Receive( void *_Data ); }; class TArduinoCustomCodeInputIntegerElement1 { public: void InputPin_o_Receive( void *_Data ); }; class TArduinoCustomCodeInputIntegerElement2 { public: void InputPin_o_Receive( void *_Data ); }; class TArduinoCustomCodeInputIntegerElement3 { public: void InputPin_o_Receive( void *_Data ); }; class TCustomCodeLoraWAN_Setup_Globals1 { }; } // CustomCode // Declarations namespace Declarations { namespace Types { typedef CustomCode::TCustomCodeLoraWAN_Stack1 CustomCodeLoraWAN_Stack; } // Types namespace Instances { Types::CustomCodeLoraWAN_Stack CustomCodeLoraWAN_Stack; } // Instances namespace Types { typedef CustomCode::TArduinoCustomCodeInputTextElement1 TArduinoCustomCodeInputTextElement1; } // Types namespace Instances { Types::TArduinoCustomCodeInputTextElement1 TArduinoCustomCodeInputTextElement1; } // Instances namespace Types { typedef CustomCode::TArduinoCustomCodeInputIntegerElement1 TArduinoCustomCodeInputIntegerElement1; } // Types namespace Instances { Types::TArduinoCustomCodeInputIntegerElement1 TArduinoCustomCodeInputIntegerElement1; } // Instances namespace Types { typedef CustomCode::TArduinoCustomCodeInputIntegerElement2 TArduinoCustomCodeInputIntegerElement2; } // Types namespace Instances { Types::TArduinoCustomCodeInputIntegerElement2 TArduinoCustomCodeInputIntegerElement2; } // Instances namespace Types { typedef CustomCode::TArduinoCustomCodeInputIntegerElement3 TArduinoCustomCodeInputIntegerElement3; } // Types namespace Instances { Types::TArduinoCustomCodeInputIntegerElement3 TArduinoCustomCodeInputIntegerElement3; } // Instances namespace Types { typedef Mitov::FormattedText_Fixed< true, // Clock_IsConnected 1, // Elements Mitov::EmbeddedCallChain<CallChains::CanProcess1 >, // Elements_CanProcess ::CallChains::Process1, // Elements_Process Mitov::EmbeddedCallChain<CallChains::Processed1 >, // Elements_Processed Mitov::ConstantProperty<88, bool, true >, // FModified Mitov::TextPin_EmbeddedPinImplementation<3, ::PinCalls::PinCallerReceive0 > // OutputPin > FormattedText1; } // Types namespace Instances { Types::FormattedText1 FormattedText1; } // Instances namespace Types { typedef Mitov::FormattedTextElementInteger< Declarations::Types::FormattedText1, // 0_TYPE_OWNER Declarations::Instances::FormattedText1, // 1_NAME_OWNER Mitov::ConstantProperty<5, int32_t, 10 >, // Base Mitov::ConstantProperty<88, bool, true >, // FModified Mitov::ConstantProperty<3, char, ' ' >, // FillCharacter Mitov::VariableProperty<6, int32_t, 0 >, // InitialValue Mitov::ConstantProperty<2, uint32_t, 0 > // Length > TArduinoFormattedTextElementInteger1; } // Types namespace Instances { Types::TArduinoFormattedTextElementInteger1 TArduinoFormattedTextElementInteger1; } // Instances Mitov::TFormattedTextStringItemIndexed< ::VisuinoConstants::TextValue0, Declarations::Types::TArduinoFormattedTextElementInteger1, Declarations::Instances::TArduinoFormattedTextElementInteger1 > _o_FormattedText1_o_Indexed0; namespace Types { typedef Mitov::PulseGenerator< Mitov::ConstantPropertyFloat<8, float, ::VisuinoConstants::FloatValue1 >, // Asymmetry Mitov::ConstantProperty<4, bool, true >, // Enabled Mitov::ConstantPropertyFloat<17, float, ::VisuinoConstants::FloatValue1>, // FPhase Mitov::TypedVariable<15, bool, ::ComponentVariables::Variable4 >, // FValue Mitov::ConstantPropertyFloat<7, float, ::VisuinoConstants::FloatValue0 >, // Frequency Mitov::ConstantProperty<5, bool, false >, // InitialValue Mitov::DigitalPin_EmbeddedPinImplementation_ChangeOnly<3, ::PinCalls::PinCallerReceive1, Mitov::TypedVariable<0, bool, ::ComponentVariables::Variable3 > >, // OutputPin Mitov::ConstantPropertyFloat<9, float, ::VisuinoConstants::FloatValue1 >, // Phase Mitov::NestedProperty<14, Mitov::TArduinoGeneratorWhenDisabled< Mitov::ConstantProperty<13, bool, false >, // CompleteCycle Mitov::ConstantProperty<12, bool, true >, // FCycleCompleted Mitov::ConstantProperty<11, bool, false > // Reset > > // WhenDisabled > PulseGenerator1; } // Types namespace Instances { Types::PulseGenerator1 PulseGenerator1; } // Instances namespace Types { typedef Mitov::PulseGenerator< Mitov::ConstantPropertyFloat<8, float, ::VisuinoConstants::FloatValue1 >, // Asymmetry Mitov::ConstantProperty<4, bool, true >, // Enabled Mitov::ConstantPropertyFloat<17, float, ::VisuinoConstants::FloatValue1>, // FPhase Mitov::TypedVariable<15, bool, ::ComponentVariables::Variable5 >, // FValue Mitov::ConstantPropertyFloat<7, float, ::VisuinoConstants::FloatValue2 >, // Frequency Mitov::ConstantProperty<5, bool, false >, // InitialValue Mitov::DigitalPin_DirectBoardPinImplementation<PA2 >, // OutputPin Mitov::ConstantPropertyFloat<9, float, ::VisuinoConstants::FloatValue1 >, // Phase Mitov::NestedProperty<14, Mitov::TArduinoGeneratorWhenDisabled< Mitov::ConstantProperty<13, bool, false >, // CompleteCycle Mitov::ConstantProperty<12, bool, true >, // FCycleCompleted Mitov::ConstantProperty<11, bool, false > // Reset > > // WhenDisabled > PulseGenerator2; } // Types namespace Instances { Types::PulseGenerator2 PulseGenerator2; } // Instances namespace Types { typedef CustomCode::TCustomCodeLoraWAN_Setup_Globals1 CustomCodeLoraWAN_Setup_Globals; } // Types namespace Instances { Types::CustomCodeLoraWAN_Setup_Globals CustomCodeLoraWAN_Setup_Globals; } // Instances namespace Types { typedef Mitov::Counter< Mitov::ConstantProperty<4, bool, true >, // Enabled Mitov::TypedVariable<32, int32_t, ::ComponentVariables::Variable7>, // FCount Mitov::ConstantProperty<6, int32_t, 0 >, // InitialValue Mitov::NestedProperty<14, Mitov::CounterLimit< Mitov::ConstantProperty<13, bool, true >, // RollOver Mitov::ConstantProperty<12, int32_t, 2147483647 > // Value > >, // Value_Max Mitov::NestedProperty<10, Mitov::CounterLimit< Mitov::ConstantProperty<9, bool, true >, // RollOver Mitov::ConstantProperty<8, int32_t, -2147483648 > // Value > >, // Value_Min Mitov::TypedVariable<18, bool, ::ComponentVariables::Variable6 >, // NeedsUpdate Mitov::TypedPin_EmbeddedPinImplementation<3, ::PinCalls::PinCallerReceive2, int32_t >, // OutputPin Mitov::ConstantProperty<17, bool, false > // Reversed > Counter1; } // Types namespace Instances { Types::Counter1 Counter1; } // Instances namespace Types { typedef Mitov::CommonRandomGenerator< float, // 0_TYPE Mitov::RandomIntegerGenerator<int32_t>, // 1_BASE Mitov::ConstantProperty<5, bool, true >, // Enabled Mitov::ConstantProperty<7, int32_t, 10 >, // Value_Max Mitov::ConstantProperty<6, int32_t, 0 >, // Value_Min Mitov::TypedPin_EmbeddedPinImplementation<3, ::PinCalls::PinCallerReceive3, int32_t >, // OutputPin Mitov::ConstantProperty<8, int32_t, 0 > // Seed > RandomIntegerGeneratorX; } // Types namespace Instances { Types::RandomIntegerGeneratorX RandomIntegerGeneratorX; } // Instances namespace Types { typedef Mitov::CommonRandomGenerator< float, // 0_TYPE Mitov::RandomIntegerGenerator<int32_t>, // 1_BASE Mitov::ConstantProperty<5, bool, true >, // Enabled Mitov::ConstantProperty<7, int32_t, 10 >, // Value_Max Mitov::ConstantProperty<6, int32_t, 0 >, // Value_Min Mitov::TypedPin_EmbeddedPinImplementation<3, ::PinCalls::PinCallerReceive4, int32_t >, // OutputPin Mitov::ConstantProperty<8, int32_t, 0 > // Seed > RandomIntegerGeneratorY; } // Types namespace Instances { Types::RandomIntegerGeneratorY RandomIntegerGeneratorY; } // Instances namespace Types { typedef Mitov::CommonRandomGenerator< float, // 0_TYPE Mitov::RandomIntegerGenerator<int32_t>, // 1_BASE Mitov::ConstantProperty<5, bool, true >, // Enabled Mitov::ConstantProperty<7, int32_t, 10 >, // Value_Max Mitov::ConstantProperty<6, int32_t, 0 >, // Value_Min Mitov::TypedPin_EmbeddedPinImplementation<3, ::PinCalls::PinCallerReceive5, int32_t >, // OutputPin Mitov::ConstantProperty<8, int32_t, 0 > // Seed > RandomIntegerGeneratorZ; } // Types namespace Instances { Types::RandomIntegerGeneratorZ RandomIntegerGeneratorZ; } // Instances } // Declarations // Custom Code Implementations namespace CustomCode { void TCustomCodeLoraWAN_Stack1::SystemInit() { pinMode(RADIO_TCXO_VCC_PIN,OUTPUT); digitalWrite(RADIO_TCXO_VCC_PIN,HIGH); pinMode(RADIO_ANT_SWITCH_PIN_RX,OUTPUT); digitalWrite(RADIO_ANT_SWITCH_PIN_RX,HIGH); } void TCustomCodeLoraWAN_Stack1::SystemStart() { //LOM204 pinMode(RADIO_TCXO_VCC_PIN,OUTPUT); digitalWrite(RADIO_TCXO_VCC_PIN,HIGH); //LOM204 Serial.begin(9600); Serial.println(F("Starting")); // LMIC init os_init(); // Reset the MAC state. Session and pending data transfers will be discarded. LMIC_reset(); LMIC_setClockError(MAX_CLOCK_ERROR * 1 / 100); LMIC_selectSubBand(1); //FSB2 start in 0 // Start job (sending automatically starts OTAA too) do_send(&sendjob); } void TCustomCodeLoraWAN_Stack1::SystemLoopUpdateHardware() { os_runloop_once(); } void TArduinoCustomCodeInputTextElement1::InputPin_o_Receive( void *_Data ) { Declarations::Instances::CustomCodeLoraWAN_Stack.__Inputs_o_0_o_Receive( Mitov::String( ( char *)_Data ) ); } void TArduinoCustomCodeInputIntegerElement1::InputPin_o_Receive( void *_Data ) { Declarations::Instances::CustomCodeLoraWAN_Stack.__Inputs_o_1_o_Receive( *( int32_t *)_Data ); } void TArduinoCustomCodeInputIntegerElement2::InputPin_o_Receive( void *_Data ) { Declarations::Instances::CustomCodeLoraWAN_Stack.__Inputs_o_2_o_Receive( *( int32_t *)_Data ); } void TArduinoCustomCodeInputIntegerElement3::InputPin_o_Receive( void *_Data ) { Declarations::Instances::CustomCodeLoraWAN_Stack.__Inputs_o_3_o_Receive( *( int32_t *)_Data ); } } // CustomCode // Type Converters namespace TypeConverters { Mitov::Convert_BinaryToClock<Mitov::TypedVariable<0, bool, ::ComponentVariables::Variable8 >> Converter0; } // TypeConverters // Call Chains namespace CallChains { void Processed1::Call() { Declarations::Instances::TArduinoFormattedTextElementInteger1.Processed(); } void CanProcess1::Call( bool & AResult ) { Declarations::Instances::TArduinoFormattedTextElementInteger1.CanProcess( AResult ); } void Process1::Call( Mitov::String &AText ) { Declarations::_o_FormattedText1_o_Indexed0.Process( AText ); } } // CallChains // Pin Call Declarations namespace PinCalls { void PinCallerConverterReceive1( void *_Data ); } // PinCalls // Pin Call Implementations namespace PinCalls { void PinCallerReceive0::Notify( void *_Data ) { BoardDeclarations::Instances::SerialPort0_Input_IOWStringStream_1.InputPin_o_Receive( _Data ); BoardDeclarations::Instances::SerialPort1_Input_IOWStringStream_1.InputPin_o_Receive( _Data ); Declarations::Instances::TArduinoCustomCodeInputTextElement1.InputPin_o_Receive( _Data ); } void PinCallerReceive1::Notify( void *_Data ) { TypeConverters::Converter0.Convert( _Data, PinCallerConverterReceive1 ); } void PinCallerConverterReceive1( void *_Data ) { Declarations::Instances::FormattedText1.ClockInputPin_o_Receive( _Data ); Declarations::Instances::Counter1.InputPin_o_Receive( _Data ); } void PinCallerReceive2::Notify( void *_Data ) { Declarations::Instances::TArduinoFormattedTextElementInteger1.InputPin_o_Receive( _Data ); } void PinCallerReceive3::Notify( void *_Data ) { Declarations::Instances::TArduinoCustomCodeInputIntegerElement1.InputPin_o_Receive( _Data ); } void PinCallerReceive4::Notify( void *_Data ) { Declarations::Instances::TArduinoCustomCodeInputIntegerElement2.InputPin_o_Receive( _Data ); } void PinCallerReceive5::Notify( void *_Data ) { Declarations::Instances::TArduinoCustomCodeInputIntegerElement3.InputPin_o_Receive( _Data ); } } // PinCalls namespace ComponentsHardware { void SystemUpdateHardware() { Declarations::Instances::CustomCodeLoraWAN_Stack.SystemLoopUpdateHardware(); } } // ComponentsHardware //The setup function is called once at startup of the sketch void setup() { BoardDeclarations::Instances::SerialPort0.SystemInit(); BoardDeclarations::Instances::SerialPort1.SystemInit(); Declarations::Instances::CustomCodeLoraWAN_Stack.SystemInit(); Declarations::Instances::Counter1.SystemInit(); Declarations::Instances::CustomCodeLoraWAN_Stack.SystemStart(); Declarations::Instances::FormattedText1.SystemStart(); Declarations::Instances::TArduinoFormattedTextElementInteger1.SystemStart(); Declarations::Instances::PulseGenerator1.SystemStart(); Declarations::Instances::PulseGenerator2.SystemStart(); Declarations::Instances::Counter1.SystemStart(); Declarations::Instances::RandomIntegerGeneratorX.SystemStartGenerate(); Declarations::Instances::RandomIntegerGeneratorY.SystemStartGenerate(); Declarations::Instances::RandomIntegerGeneratorZ.SystemStartGenerate(); } // The loop function is called in an endless loop void loop() { Declarations::Instances::PulseGenerator1.SystemLoopBegin(); Declarations::Instances::PulseGenerator2.SystemLoopBegin(); Declarations::Instances::RandomIntegerGeneratorX.SystemLoopBegin(); Declarations::Instances::RandomIntegerGeneratorY.SystemLoopBegin(); Declarations::Instances::RandomIntegerGeneratorZ.SystemLoopBegin(); ComponentsHardware::SystemUpdateHardware(); }

Conectando EndDevices com myDevices(TTN )












Conta cayenne (vincular EnDevice)













Certifique-se que LOM204 e programador estejam selecionados, bem como demais parâmetros e então compile.


Transfira o programa  (sempre reset antes o LOM204)


Execução



STM32Programmer

Uma boa opção se tiveres problemas com drivers é instalar.

Fontes:


Dúvidas

suporte@smartcore.com.br


Download

Sobre a SMARTCORE

A SmartCore fornece módulos para comunicação wireless, biometria, conectividade, rastreamento e automação.
Nosso portfólio inclui modem 2G/3G/4G/NB-IoT/Cat.M, satelital, módulos WiFi, Bluetooth, GNSS / GPS, Sigfox, LoRa, leitor de cartão, leitor QR code, mecanismo de impressão, mini-board PC, antena, pigtail, LCD, bateria, repetidor GPS e sensores.

Mais detalhes em www.smartcore.com.br