Node with ESP8266 and RFM95W

@davemee

The reserved pins on the module are clearly the programming pins for the ICD.

The LoRa and LoRaWAN code can be ported from IBM-LMIC or Semtech and flashed onto the PIC with minimal changes only related to the HAL.

For large quantities if one wants to run own code inside the PIC, then it is a viable option.

You would of course loose certification but maybe you are not concerned about that.

Davemee - Why not ask your friendly Microchip salesman to bundle an 8-pin PIC12 to run the application and drive the RN2483 UART. It costs next to nothing, and isn’t much bigger than a regulator or bulk capacitor.

Just in case it helps anyone getting here given this topic’s title: Arduino LoRaWAN sketches for the Ideetron Nexus board.

The Nexus board is not an ESP8266, but an Atmel ATMEGA328P with RFM95W or RFM98W. I’ve not used it, nor the above sketches.

@rvweert, what’s your final setup with the ESP8266 and RFM95W?

I recognized that the TTN gateway will not be available soon and that Microchip RN2483 is out of stock. Just too have something working in short time I found out that a very cheap and simple experimental setup with an single_channel_gateway, https://github.com/tftelkamp/single_chan_pkt_fwd
built on RPI and SX1272, and a node built on ESP-12 (ESP8266) and SX1272 is possible.

matthijs presented an updated version of arduino-lmic library 29 days ago. https://github.com/matthijskooijman/arduino-lmic.
The code will compile for ESP8266 in Arduino IDE without problem and with some small modification as below it is possible to force transmission to only one channel, the same channel as the single-channel-gateway is listening on. The pin mapping can also leave dio3 unused as I will not use the FSK channel at all, this means that I can use the serial port for input of new data for transmission.

// Pin mapping
const lmic_pinmap lmic_pins = {
.nss = 15,
.rxtx = LMIC_UNUSED_PIN,
.rst = 16,
.dio = {5, 4, LMIC_UNUSED_PIN},

SX1272 dio2 → GND // Only used for PSK, not used in my case

//Changes in Arduino code, setup

// configures the minimal channel set.
LMIC_setupChannel(0, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
LMIC_setupChannel(1, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
LMIC_setupChannel(2, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
LMIC_setupChannel(3, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
LMIC_setupChannel(4, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
LMIC_setupChannel(5, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
LMIC_setupChannel(6, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
LMIC_setupChannel(7, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
LMIC_setupChannel(8, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band

// LMIC_setupChannel(1, 868300000, DR_RANGE_MAP(DR_SF12, DR_SF7B), BAND_CENTI); // g-band
// LMIC_setupChannel(2, 868500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
// LMIC_setupChannel(3, 867100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
// LMIC_setupChannel(4, 867300000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
// LMIC_setupChannel(5, 867500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
// LMIC_setupChannel(6, 867700000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
// LMIC_setupChannel(7, 867900000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
// LMIC_setupChannel(8, 868800000, DR_RANGE_MAP(DR_FSK, DR_FSK), BAND_MILLI); // g2-band
// TTN defines an additional channel at 869.525Mhz using SF9 for class B

I was struggling very much to get an ESP-12-E and a RFM95 to work together and run LMIC, and transmit a packet to TTN. The biggest issue I had was figuring out which pins on the ESP should be grounded, and which should be pulled high. And when and in which order. I finally got the whole thing working yesterday.

In this post I’ll give an outline of how I connected everything. Next time I will hopefully summarize what I had to do to get the software side working, as different library versions caused some headaches.

The ESP8266 module I have is this one: http://www.esp8266.com/wiki/doku.php?id=esp8266-module-family#esp-12-e_q

My final connection diagram looks like this:

Things to take note of:

  • The ESP should be powered from an external 3.3 volt source, not via USB. Big capacitors are needed to suppress the spikes of current the ESP module needs during startup. USB does not like big caps on its voltage lines.
  • The ground connection of the ESP should be connected to your power supply and the USB-UART (FTDI) board.
  • Note the pull-up and pull-down resistors on pins GPIO0, GPIO2, GPIO15, EN and Reset of the ESP module. This is very important for the ESP to boot up into the correct mode, as well as the SPI slave select line to work.
  • To boot the module up in programming mode, hold down switch “Program”, then press and release switch “Reset”, and then release switch “Program”. After a successful program, press and release the Reset switch to boot up into normal mode.
9 Likes

As I mentioned in my previous post, I also had a number of software issues to sort out before my ESP+RFM95 node worked. Here is a step-by-step guide of the steps I was able to reproduce to get a working node.

Go to https://github.com/things4u/LoRa-Thing and download zip file.
Unzip.
Copy “esp-lmic-v1.5” to your Arduino sketch folder.
Copy “libraries/base64” to the libraries folder in your Arduino sketch folder.

Go to https://github.com/tftelkamp/arduino-lmic-v1.5 and download zip file.
Unzip.
Copy folder to the libraries folder in your Arduino sketch folder.
Inside this folder go to src/lmic/config.h and comment out line 10 (//#define CFG_sx1272_radio 1) and uncomment line 11 (#define CFG_sx1276_radio 1).

Open Arduino IDE 1.6.7
Go to Tools, Board, Boards Manager. Install “esp8266 by ESP8266 Community”.
(Arduino IDE may need a restart)
Go to Tools, Board and choose Generic ESP8266 module

Open esp-lmic-v1.5.ino from the folder which you copied to your Arduino sketch folder in the first step.
Comment out line 32: //#include <ESP.h>
Line 33 should not start with a capital letter: #include <base64.h>
Change line 59 to your device address.

The sketch should now compile without errors.

Follow the procedure in my previous post to program and reset the ESP8266 module.

If you open the Arduino serial monitor at 115200, you should see the following messages (or similar) after a couple of seconds:

Starting
os_init() finished
LMIC_reet() finished
LMIC_setSession() finished
LMICsetAddrMode() finished
Init done
Time: 21
Send, txCnhl: 0
Opmode check: ok
Event EV_TXCOMPLETE, time: 34

After about two minutes you should see the following text (or similar) appear:

Time: 141
Send, txCnhl: 7
Opmode check: ok
Event EV_TXCOMPLETE, time: 154

Every two minutes a packet is sent to TTN. You can check on the TTN API if this is the case.

Some observations and guesses why the code does not work out of the box:

  • It seems like there are multiple Arduino libraries for the ESP family of modules. I chose the one that is listed in the boards manager, as it is the easiest to find/install/update and thus the most likely one for a beginner to use. The original author of the esp-lmic example sketch likely used a different version, and therefore had to include ESP.h.
  • There are numerous LMIC libraries around. I tested quite a few, but the only one I could get to compile was the one linked to in step 2. Some of the newer versions of the library does not handle the ESP correctly in their precompiler directives. Some are also using a different ESP-Arduino library.
5 Likes

Just got the things4u esp8266 sketch working with the Modtronix inair9b here in US915 land, with an esp8266-03 (NOT recommended, just what I had laying around while the Wemos D1 mini is on order) - which took a bit of a hardware trick to use GPIO0&2 for DIO0&1 - namely, power on with GPIO0&2 disconnected, then plug it into DIO0&1, believe it or not that works!

Next, it looks like the LMiC library starts from a random channel 0 thru 63 (902.3 + chnl*0.2 MHz) and walks up to 63 then starts over from 0. Just stuck a horrible hack in lmic.cpp to fix it on channel 57 (913.7) - well, after the first transmission on channel 0, then update my single channel gateway and the temperature node.

Now TTN REST reports:
“data_plain”: “Hello ESP8266 world!”

Learning LoRaWAN and LMiC is going to take me a while :frowning:

You could also add a loop in your own sketch, calling LMIC_disableChannel(i).

(And remember, for a real node, don’t send text.)

In my previous post about the software setup to program an ESP8266, I missed one step.

After installing the Arduino IDE, you have to go to File->Preferences, and next to Additional Boards Manager URLs, add the following URL: http://arduino.esp8266.com/staging/package_esp8266com_index.json

Now in Tools -> Board: -> Boards Manager, search for ESP, and choose to install esp8266 by ESP8266 Community version 2.2.0-rc1


Another issue I encountered was that my ESP module constantly crashed with an exception:

Exception (3):
epc1=0x401003e9 epc2=0x00000000 epc3=0x00000000 excvaddr=0x400248c9 depc=0x00000000

Which translated to:

calloc at /opt/arduino-1.6.7/hardware/esp8266com/esp8266/cores/esp8266/umm_malloc/umm_malloc.c line 1682

After a very long search I found a sollution that worked: http://wifiesp.com/?p=14

Basically I had to add this block of code at the start of my setup function:

uint16_t s,res;

os_printf("Erasing sectors\n");
for (s=0x70;s<=0x7F; s++)
{
  res = spi_flash_erase_sector(s);
  os_printf("Sector erased 0x%02X. Res %d\n",s,res);
}
2 Likes

I just found these 2 items. They look like a match made in heaven (for this particular topic).
Does anyone have experience with this combination?

It is a ESP8266 in an Arduino formfactor with an Arduino-Lora-module.

A combination of:


(the version on Ali is already a newer version mine is 1.1)

Anyone?

1 Like

I was lucky enough to receive the first revision of the Dragino LoRa board: it simply works.

As it is basically an RFM95 breakout it should work together with the ESP, you might want to consider the V1.2 board as that is more flexible w.r.t. the breakouts. It was revised based on inputs from people on this forum to make it more flexible see the dragino wiki for the difference in appearance.

For ESP8266 LMIC stack see messages above.

That actually didn’t work for me.

Huh, turns out the lmic.cpp LMIC_disableChannel(u1_t channel) for CFG_us915 I got from https://github.com/things4u/LoRa-Thing/tree/master/libraries/lmic-v1.5 is broken - for

struct lmic_t {
#elif defined(CFG_us915)
u2_t channelMap[(72+MAX_XCHANNELS+15)/16]; // enabled bits

that should be an array of 5 16 bit values (80 bits, to cover 74 total channels), which when initialized is:
LMIC.channelMap[0] = 0xFFFF 16
LMIC.channelMap[1] = 0xFFFF 32
LMIC.channelMap[2] = 0xFFFF 48
LMIC.channelMap[3] = 0xFFFF 64
LMIC.channelMap[4] = 0x00FF 72 bits

However, LMIC_disableChannel() for CFG_us915 is modulo 4???
LMIC.channelMap[channel/4] &= ~(1<<(channel&0xF));

should be 16. As it is, when you disable channel 4, you actually get 20!
4: channelMap[0]: ffff
channelMap[1]: ffef 1110 1111 wtf??

LMIC_disableChannel(8) turns off the bit for 40, etc. Changed it to:

LMIC.channelMap[channel/16] &= ~(1<<(channel&0xF));

in my little test file and got expected results - will try it out in the actual code later tonight.

See also Matthijs’ version, which also has some more documentation.

Verified it came from IBM like that! http://www.research.ibm.com/labs/zurich/ics/lrsc/lmic.html

Pretty sure that’s a bug from the source.

has the same bug:

void LMIC_disableChannel (u1_t channel) {
if( channel < 72+MAX_XCHANNELS )
LMIC.channelMap[channel/4] &= ~(1<<(channel&0xF));
}

That 4 should be a 16 to get the right byte of the array - only affects CFG_us915.

4 Likes

It looks like the 6 pin connector of the Lora shield might be right on top of the ESP module. Is that an issue or do the boards fit nicely?

Hi Jac,

You are right the connector for SPI is directly above (2mm) the ESP-antenna but they fit nicely.
It seems that I have to do a little bit resoldering of a few “jumpers” ( I have version 1.1 of the Dragino Board so no nice jumpers -bought it 6 weeks ago-)… but then it should fit the Wemos D1 like a glove.

I am taking small steps and at this moment I am trying to test the Dragino with an Arduino Uno first (afterwards I will resolder the jumpers on the Dragino)…

1 Like

Verified - fixed /4 changed to /16 in LMIC_disableChannel() for CFG_us915 and now it works, only sends on my single channel gateway frequency of 913.7:


Disabling channel: 53
Disabling channel: 54
Disabling channel: 55
Disabling channel: 56
Disabling channel: 58
Disabling channel: 59
Disabling channel: 60
Disabling channel: 61
Disabling channel: 62
Disabling channel: 63
Disabling channel: 64
Disabling channel: 65
Disabling channel: 66
Disabling channel: 67
Disabling channel: 68
Disabling channel: 69
Disabling channel: 70
Disabling channel: 71
Disabling channel: 72
Init done
Time: 0
Send, txCnhl: 0
Opmode check: ok
Event EV_TXCOMPLETE, time: 10
Time: 30
Send, txCnhl: 57
Opmode check: ok
Event EV_TXCOMPLETE, time: 40
Time: 60
Send, txCnhl: 57
Opmode check: ok
Event EV_TXCOMPLETE, time: 70
Time: 90
Send, txCnhl: 57
Opmode check: ok
Event EV_TXCOMPLETE, time: 101
Time: 120
Send, txCnhl: 57
Opmode check: ok

Thanks!

1 Like

This seems promissing:


(very small form-factor ESP-Wemos)

Made a shield for the ESP dev Board with the RFM module. Have some testing and soldering to do but should come in handy for small nodes.


1 Like