Big ESP32 / SX127x topic part 1

Hi,
Just beginning with using the things network.
But how do I start with the heltec lora esp32 dev board?
I just want to use an example, but I get an error.

"\Arduino\libraries\TheThingsNetwork\src/TheThingsNetwork.h:9:26: fatal error: avr/pgmspace.h: No such file or directory"

show your whole code (and format it ) pls

I have the Heltec esp32 LoRa 868MHz dev board.

#include <TheThingsNetwork.h>
#include <TheThingsMessage.h>

// Set your AppEUI and AppKey
const char *appEui = "XXXXXXXXXXXXXXX";
const char *appKey = "XXXXXXXXXXXXXXXXXXXXXXXX";

#define loraSerial Serial1
#define debugSerial Serial

// Replace REPLACE_ME with TTN_FP_EU868 or TTN_FP_US915
#define freqPlan TTN_FP_EU868

TheThingsNetwork ttn(loraSerial, debugSerial, freqPlan);

devicedata_t data = api_DeviceData_init_default;

#include <SPI.h>

#include <Wire.h>
#include "SSD1306.h"
#include "images.h"

// Pin definetion of WIFI LoRa 32
// HelTec AutoMation 2017 support@heltec.cn
#define SCK     5    // GPIO5  -- SX127x's SCK
#define MISO    19   // GPIO19 -- SX127x's MISO
#define MOSI    27   // GPIO27 -- SX127x's MOSI
#define SS      18   // GPIO18 -- SX127x's CS
#define RST     14   // GPIO14 -- SX127x's RESET
#define DI00    26   // GPIO26 -- SX127x's IRQ(Interrupt Request)

#define BAND    433E6  //you can set band here directly,e.g. 868E6,915E6
#define PABOOST true

unsigned int counter = 0;

SSD1306 display(0x3c, 4, 15);
String rssi = "RSSI --";
String packSize = "--";
String packet ;

void logo()
{
  display.clear();
  display.drawXbm(0, 5, logo_width, logo_height, logo_bits);
  display.display();
}

void setup()
{
  pinMode(16, OUTPUT);
  pinMode(25, OUTPUT);

  digitalWrite(16, LOW);    // set GPIO16 low to reset OLED
  delay(50);
  digitalWrite(16, HIGH); // while OLED is running, must set GPIO16 in high

  display.init();
  display.flipScreenVertically();
  display.setFont(ArialMT_Plain_10);
  logo();
  delay(1500);
  display.clear();

  SPI.begin(SCK, MISO, MOSI, SS);



  loraSerial.begin(57600);
  debugSerial.begin(9600);

  // Wait a maximum of 10s for Serial Monitor
  while (!debugSerial && millis() < 10000)
    ;

  debugSerial.println("-- STATUS");
  ttn.showStatus();

  debugSerial.println("-- JOIN");
  ttn.join(appEui, appKey);

  // Select what fields to include in the encoded message
  data.has_motion = true;
  data.has_water = false;
  data.has_temperature_celcius = true;
  data.has_temperature_fahrenheit = true;
  data.has_humidity = true;





  display.drawString(0, 0, "LoRa Initial success!");
  display.display();
  delay(1000);
}

void loop()
{
  display.clear();
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.setFont(ArialMT_Plain_10);

  display.drawString(0, 0, "Sending packet: ");
  display.drawString(90, 0, String(counter));
  display.display();


  debugSerial.println("-- LOOP");

  // Read the sensors
  data.motion = true;
  data.water = 682;
  data.temperature_celcius = 30;
  data.temperature_fahrenheit = 86;
  data.humidity = 97;

  // Encode the selected fields of the struct as bytes
  byte *buffer;
  size_t size;
  TheThingsMessage::encodeDeviceData(&data, &buffer, &size);

  ttn.sendBytes(buffer, size);



  counter++;
  digitalWrite(25, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(25, LOW);    // turn the LED off by making the voltage LOW
  
delay(5000);                       // wait for a second
}

Are you sure you selected the right board in the menu ?

That error mentioning “avr” sounds like you are still trying to build for an arduino - or any other boards using AVR µControllers.

I have selected the Heltec_WiFi_lora _32 board

Hi - not sure what is happening in your code. The TTN-OTAA and TTN-ABP examples work with the MicroChip RN2483 module that has a serial connection. I suggest you try the LMiC code. Below is a working example…

#include <lmic.h>
#include <hal/hal.h>
#include <SPI.h>
#include <U8x8lib.h>

#define BUILTIN_LED 25

// the OLED used
U8X8_SSD1306_128X64_NONAME_SW_I2C u8x8(/* clock=*/ 15, /* data=*/ 4, /* reset=*/ 16);

// 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] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0xB3, 0x70 };
void os_getArtEui (u1_t* buf) {
  memcpy_P(buf, APPEUI, 8);
}

// This should also be in little endian format, see above.
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.
// The key shown here is the semtech default key.
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);
}

static uint8_t mydata[] = "Hi";
static osjob_t sendjob;

// Schedule TX every this many seconds (might become longer due to duty
// cycle limitations).
const unsigned TX_INTERVAL = 30;

// Pin mapping
const lmic_pinmap lmic_pins = {
  .nss = 18,
  .rxtx = LMIC_UNUSED_PIN,
  .rst = 14,
  .dio = {26, 33, 32},
};

void onEvent (ev_t ev) {
  Serial.print(os_getTime());
  u8x8.setCursor(0, 5);
  u8x8.printf("TIME %lu", os_getTime());
  Serial.print(": ");
  switch (ev) {
case EV_SCAN_TIMEOUT:
  Serial.println(F("EV_SCAN_TIMEOUT"));
  u8x8.drawString(0, 7, "EV_SCAN_TIMEOUT");
  break;
case EV_BEACON_FOUND:
  Serial.println(F("EV_BEACON_FOUND"));
  u8x8.drawString(0, 7, "EV_BEACON_FOUND");
  break;
case EV_BEACON_MISSED:
  Serial.println(F("EV_BEACON_MISSED"));
  u8x8.drawString(0, 7, "EV_BEACON_MISSED");
  break;
case EV_BEACON_TRACKED:
  Serial.println(F("EV_BEACON_TRACKED"));
  u8x8.drawString(0, 7, "EV_BEACON_TRACKED");
  break;
case EV_JOINING:
  Serial.println(F("EV_JOINING"));
  u8x8.drawString(0, 7, "EV_JOINING");
  break;
case EV_JOINED:
  Serial.println(F("EV_JOINED"));
  u8x8.drawString(0, 7, "EV_JOINED ");

  // Disable link check validation (automatically enabled
  // during join, but not supported by TTN at this time).
  LMIC_setLinkCheckMode(0);
  break;
case EV_RFU1:
  Serial.println(F("EV_RFU1"));
  u8x8.drawString(0, 7, "EV_RFUI");
  break;
case EV_JOIN_FAILED:
  Serial.println(F("EV_JOIN_FAILED"));
  u8x8.drawString(0, 7, "EV_JOIN_FAILED");
  break;
case EV_REJOIN_FAILED:
  Serial.println(F("EV_REJOIN_FAILED"));
  u8x8.drawString(0, 7, "EV_REJOIN_FAILED");
  //break;
  break;
case EV_TXCOMPLETE:
  Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));
  u8x8.drawString(0, 7, "EV_TXCOMPLETE");
  digitalWrite(BUILTIN_LED, LOW);
  if (LMIC.txrxFlags & TXRX_ACK) {
    Serial.println(F("Received ack"));
    u8x8.drawString(0, 7, "Received ACK");
  }
  if (LMIC.dataLen) {
    Serial.println(F("Received "));
    u8x8.drawString(0, 6, "RX ");
    Serial.println(LMIC.dataLen);
    u8x8.setCursor(4, 6);
    u8x8.printf("%i bytes", LMIC.dataLen);
    Serial.println(F(" bytes of payload"));
    u8x8.setCursor(0, 7);
    u8x8.printf("RSSI %d SNR %.1d", LMIC.rssi, LMIC.snr);
  }
  // Schedule next transmission
  os_setTimedCallback(&sendjob, os_getTime() + sec2osticks(TX_INTERVAL), do_send);
  break;
case EV_LOST_TSYNC:
  Serial.println(F("EV_LOST_TSYNC"));
  u8x8.drawString(0, 7, "EV_LOST_TSYNC");
  break;
case EV_RESET:
  Serial.println(F("EV_RESET"));
  u8x8.drawString(0, 7, "EV_RESET");
  break;
case EV_RXCOMPLETE:
  // data received in ping slot
  Serial.println(F("EV_RXCOMPLETE"));
  u8x8.drawString(0, 7, "EV_RXCOMPLETE");
  break;
case EV_LINK_DEAD:
  Serial.println(F("EV_LINK_DEAD"));
  u8x8.drawString(0, 7, "EV_LINK_DEAD");
  break;
case EV_LINK_ALIVE:
  Serial.println(F("EV_LINK_ALIVE"));
  u8x8.drawString(0, 7, "EV_LINK_ALIVE");
  break;
default:
  Serial.println(F("Unknown event"));
  u8x8.setCursor(0, 7);
  u8x8.printf("UNKNOWN EVENT %d", 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"));
u8x8.drawString(0, 7, "OP_TXRXPEND, not sent");
  } else {
// Prepare upstream data transmission at the next possible time.
LMIC_setTxData2(1, mydata, sizeof(mydata) - 1, 0);
Serial.println(F("Packet queued"));
u8x8.drawString(0, 7, "PACKET QUEUED");
digitalWrite(BUILTIN_LED, HIGH);
  }
  // Next TX is scheduled after TX_COMPLETE event.
}


void setup() {

  Serial.begin(115200);

  u8x8.begin();
  u8x8.setFont(u8x8_font_chroma48medium8_r);
  u8x8.drawString(0, 1, "LoRaWAN LMiC");

  SPI.begin(5, 19, 27);

  // LMIC init
  os_init();
  // Reset the MAC state. Session and pending data transfers will be discarded.
  LMIC_reset();

  // Start job (sending automatically starts OTAA too)
  do_send(&sendjob);

  pinMode(BUILTIN_LED, OUTPUT);
  digitalWrite(BUILTIN_LED, LOW);
}

void loop() {
  os_runloop_once();
}
3 Likes

Only now getting error:

Arduino\libraries\arduino_797014\src\hal\hal.cpp:223:71: error: 'fdev_setup_stream' was not declared in this scope

     fdev_setup_stream (&uartout, uart_putchar, NULL, _FDEV_SETUP_WRITE);

exit status 1
Error compiling for board Heltec_WIFI_LoRa_32.                                                                       ^

Ok, so I don’t recognise the Arduino library referenced in the error. Have you renamed the one from http://github.com/matthijskooijman/arduino-lmics ?

Yeah I took the one from Manage Library…

Tried to import this manually and this was successful. So maybe there is some error in the library that the Arduino IDE profited?

Just glad you found something that works!

Now the next step… Figuring out what this code does exactly :sweat_smile:

1 Like

Just tried the deep sleep mode of the heltec esp32 lora board and measured power consumption. The result is 12mA in deep sleep and 50mA in “normal” mode. I thought that power consumption is much lower. Any idea how to lower it down? This little led is alway blinking too. I don’t know how much power it consumes. But I can’t belief that this is the main reason.

This is my little test-program:

RTC_DATA_ATTR int bootCount = 0;

void setup() {
  Serial.begin(115200);
  delay(1000); //Take some time to open up the Serial Monitor

  //Increment boot number and print it every reboot
  ++bootCount;
  Serial.println("Boot number: " + String(bootCount));

  esp_sleep_enable_ext0_wakeup(GPIO_NUM_0, 0); //1 = High, 0 = Low
  pinMode(GPIO_NUM_0, INPUT);
}

void loop(){
  int buttonState = digitalRead(GPIO_NUM_0);

  if (buttonState == HIGH) {
    Serial.println("Stay online for 5 seconds");
    delay(5000);
    Serial.println("Going to sleep now");
    esp_deep_sleep_start();
  } 
}
1 Like

Did you connect a battery? Then it would be charging it, which obviously explains the power consumption. Without a battery it might still be trying to detect a battery all the time; I’ve no clue but @Epyon posted some schematics earlier in this topic.

I am powering the esp32 using 4 AA batteries via the 5V and GND pin. I don’t have the correct JST connector right now.

Okay, it seems that my 5V are used to run the charging-unit MCP73831. Perhaps it is the main power consumer. I will retry my measurement im I have mi LiPo battery attached. I’m still waiting for my micro JST adapters :wink:

Wondering if one could somehow fool that charging thing into thinking a fully charged battery is attached. But again, I have no clue…

Extract from http://ww1.microchip.com/downloads/en/DeviceDoc/20001984g.pdf

So if I get it right shorting the “prog” pin to the Input power supply should disable the charger ?

Also the datasheet says the input current should be a maximum of 200 μA when no battery or charge complete. So this might not be @rmh78 current hog in sleep mode…

Best to use a high value series resistor (e.g. 10k) between PROG and VDD to limit leakage current, or better just remove the current programming resistor if you’re never going to use it.

I received my 868Mhz TTGO order, and was pleasantly surprised to get a pair while the sale seemed to be for one only. At 12.36 € shipping included that’s a real bargain.

Seller link : https://www.aliexpress.com/item/868MHz-915MHz-SX1276-ESP32-LoRa-0-96-Inch-Blue-OLED-Display-Bluetooth-WIFI-Lora-Kit-32/32840258107.html

Some unboxing pictures eye candy :
TTGO_boxesTTGO_contentTTGO_bottomTTGO_topTTGO_zoom_ESP32

It seems to use a different battery charger, which I believe is an LTC4054 :
TTGO_zoom_LTC4054

First test against my Lopy one channel gateway is positive, using LMIC and the same pin mapping as for the Heltec version as described earlier in BIG ESP32 / SX127x topic part 1 by @nicbkw - and originally @bluejedi :
TTGO_testing

What puzzles me is I can’t see anything looking like a wifi antenna anywhere on the board. I’ll have to test if it works…

2 Likes