Forum Replies Created
-
AuthorPosts
-
LIM PHANG MOHKeymaster
Guys,
You can now follow the guide here to connect to TTN through OTAA.LIM PHANG MOHKeymasterHi Matthias,
I’m sorry but I should have put this up some time ago. My plan was to include the sleeping portion for a tutorial/guide before posting it up but it seems that I have to do it before this particular issue is solve. When it starts, the code prints out the 64-bit MAC address. Key those in as it is on the TTN dashboard./******************************************************************************* Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman Permission is hereby granted, free of charge, to anyone obtaining a copy of this document and accompanying files, to do whatever they want with them without any restriction, including, but not limited to, copying, modification and redistribution. NO WARRANTY OF ANY KIND IS PROVIDED. This example sends a valid LoRaWAN packet with payload "Hello, world!", using frequency and encryption settings matching those of the The Things Network. This uses OTAA (Over-the-air activation), where where a DevEUI and application key is configured, which are used in an over-the-air activation procedure where a DevAddr and session keys are assigned/generated for use with all further communication. Note: LoRaWAN per sub-band duty-cycle limitation is enforced (1% in g1, 0.1% in g2), but not the TTN fair usage policy (which is probably violated by this sketch when left running for longer)! To use this sketch, first register your application and device with the things network, to set or generate an AppEUI, DevEUI and AppKey. Multiple devices can use the same AppEUI, but each device has its own DevEUI and AppKey. Do not forget to define the radio type correctly in config.h. *******************************************************************************/ #include <lmic.h> #include <hal/hal.h> #include <SPI.h> #include <Wire.h> #define EUI64_CHIP_ADDRESS 0x50 #define EUI64_MAC_ADDRESS 0xF8 #define EUI64_MAC_LENGTH 0x08 #define Serial SerialUSB // 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. u1_t DEVEUI[EUI64_MAC_LENGTH]; void os_getDevEui (u1_t* buf) { memcpy(buf, DEVEUI, EUI64_MAC_LENGTH); } // 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[] = "Hello, world!"; static osjob_t sendjob; // Schedule TX every this many seconds (might become longer due to duty // cycle limitations). const unsigned TX_INTERVAL = 60; // Pin mapping const lmic_pinmap lmic_pins = { .nss = 5, .rxtx = LMIC_UNUSED_PIN, .rst = 3, .dio = {2, 6, 7}, }; 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")); // 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")); break; case EV_JOIN_FAILED: Serial.println(F("EV_JOIN_FAILED")); break; case EV_REJOIN_FAILED: Serial.println(F("EV_REJOIN_FAILED")); break; 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.println(F("Received ")); Serial.println(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; default: Serial.println(F("Unknown event")); break; } } void do_send(osjob_t* j) { digitalWrite(13, HIGH); // 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. LMIC_setTxData2(1, mydata, sizeof(mydata) - 1, 0); Serial.println(F("Packet queued")); } // Next TX is scheduled after TX_COMPLETE event. digitalWrite(13, LOW); } void setDevEui(unsigned char* buf) { Wire.begin(); Wire.beginTransmission(EUI64_CHIP_ADDRESS); Wire.write(EUI64_MAC_ADDRESS); Wire.endTransmission(); Wire.requestFrom(EUI64_CHIP_ADDRESS, EUI64_MAC_LENGTH); // Format needs to be little endian (LSB...MSB) while (Wire.available()) { *buf-- = Wire.read(); } } void setup() { unsigned char count; pinMode(4, OUTPUT); digitalWrite(4, HIGH); pinMode(13, OUTPUT); setDevEui(&DEVEUI[EUI64_MAC_LENGTH - 1]); while (!Serial) {}; Serial.begin(115200); Serial.println(F("Starting")); Serial.print(F("DEVEUI: ")); for (count = 0; count < EUI64_MAC_LENGTH; count++) { Serial.print("0x"); if (DEVEUI[count] <= 0x0F) Serial.print("0"); Serial.print(DEVEUI[count], HEX); Serial.print(" "); } Serial.println(); #ifdef VCC_ENABLE // For Pinoccio Scout boards pinMode(VCC_ENABLE, OUTPUT); digitalWrite(VCC_ENABLE, HIGH); delay(1000); #endif // 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); // Start job (sending automatically starts OTAA too) do_send(&sendjob); } void loop() { os_runloop_once(); }
LIM PHANG MOHKeymasterHi Matthias,
Check your TTN 8-byte DEV EUI. Mine didn’t connect until that gets corrected and same as on the device on OTAA join. Take note of it’s MSB-LSB sequence too. In fact, OTAA is easier (less things to make mistake on the dashboard except the above).
LIM PHANG MOHKeymasterHi Brook,
The input to the charger power management is best pair with a 6V 3W (or higher W) solar panel by connecting it to VIN (DC barrel jack). 6V rated solar panel will provide an input voltage (after diode drop voltage) as close to optimum voltage to the charger. If the sunlight drops, the charger will reduce the current accordingly to prevent the input voltage from collapsing totally.LIM PHANG MOHKeymasterHi Vim,
The guides and links to the codes are all here.
LIM PHANG MOHKeymasterHi Stefan,
“Binary sketch size: 1 108 bytes (of a 30 720 byte maximum)
avrdude: verification error, first mismatch at byte 0x0056
0x7e != 0xfe
avrdude: verification error; content mismatch”If your connection with the FTDI is not properly secured or sometimes before the completion of the upload, you remove/accidentally touch, it could affect the read back of the flash content during the verification stage of upload. The write stage was completed without error, hence the code runs as you would have expected.
Do you have any example code for how to best utilise the battery voltage monitor connected to pin A6?
Here you go:
float readBattery(void) { int count; int adcValue; float batteryVoltage; // Discard 1st reading (inaccurate) adcValue = analogRead(A6); adcValue = 0; // Average battery voltage reading for (count = 0; count < 10; count++) { adcValue += analogRead(A6); } adcValue = adcValue / 10; batteryVoltage = (105.6 * adcValue) / 22528; return batteryVoltage; }
LIM PHANG MOHKeymasterForgot to mention that you will also need to have the DIO pins connection which I presume you already know, just in case. On V2 of the Mini Ultra Pro, it should look like this:
// Pin mapping const lmic_pinmap lmic_pins = { .nss = 5, .rxtx = LMIC_UNUSED_PIN, .rst = 3, .dio = {2, 6, 7}, };
Of course, you can remove the D7 for DIO2 support if not using the FSK mode. On V1 of the Mini Ultra Pro, you can use any free pins (other than D2, D4 & D5) and connect the DIO pins up using wires.
LIM PHANG MOHKeymasterHi Adam,
Sorry if this comes a bit late. Was finalizing the V2 while this question came in. In the midst of writing a tutorial for this.
But, here are the important points that get the example provided by Matthijs Kooijman’s LMIC library running correctly:- Both the Device EUI and Application EUI (both are the 8-bytes key) are displayed as MSB….LSB on the TTN dashboard. But, you must key in as LSB…MSB on the OTAA example.
- Add
LMIC_setClockError(MAX_CLOCK_ERROR * 1 / 100);
afterLMIC_reset();
- Add
#define Serial SerialUSB
if you want to see the debug messages on the USB port.
These are only 3 changes needed to get going.
Some stuff I’ll be adding in the tutorial includes using the EUI64 identification and using the RTC to resides in low power mode while connected to the network. This will serve as a good skeleton firmware for low power application using OTAA to TTN.
- This reply was modified 6 years, 10 months ago by LIM PHANG MOH.
LIM PHANG MOHKeymasterHi,
Is the radio chip select pin being pull high (D5) when these reads are being performed on the serial flash?
We tested every single serial flash on the board to make sure it’s with the correct values.LIM PHANG MOHKeymasterHi,
They are in stock now.
Thanks.LIM PHANG MOHKeymasterYou could use something like SF=11 & BW=125 kHz (few hundred byte per second, have to calculate to get exact number based on few parameters, at SF=12, CR=4/5 & BW=125 kHz, it is 293 bps). With the RFM95W module, it will not work when your data is longer at high SF and small bandwidth range. The crystal on the module is only rated at 10 ppm. At high SF setting and small bandwidth, these tolerance is not enough especially when the data is longer (more than few bytes will easily fail) as the accumulated error due to the tolerance of the crystal.
A TXCO version of the module is very recently released with tolerance of 2 ppm. This is said to resolve the problem at high SF and small bandwidth setting although I don’t think it would work on extreme case like 32.5 kHz at SF=12 still. We are still waiting for the TXCO module to come as it has lead time of 4 weeks.Did the same thin during my masters-thesis. I used so called micaz-nodes and an arduino as LAN-Gateway. Programming in TinyOS was a horror.
Was working on TinyOS back in 2006. Micaz, T-mote Sky, Crossbow and all those jazz. And yes, I have to admit it was horrible to work on it (but if you are from C++ background and understand about thread on Linux it should be okay). Supported radio chip was limited. We were using our custom board based on Micaz (ATmega128+CC2420). Range was very limited at 2.4 GHz and even with power amplifier, it is not even close to a FSK RFM69HCW today. 🙂
LIM PHANG MOHKeymasterDo you have a good example sketch for a small Wireless sensor network?
I have plans to do this but I need to finish a companion product that can add as a gateway, so we can relay data to the cloud. So, currently it is not written yet. As a start, you get use the examples of the server and client to begin with. The server can act as a central/gateway node, while the rest uses the client code as end node.
What settings for setModemConfig would you prefer?
That depends on the range and data rate you want to achieve. When you increase the range (through higher SF setting and smaller bandwidth), the data will become slower and vice versa. With slower but longer range, you would then recommended to send small data package.
What are your application scenario looks like?
LIM PHANG MOHKeymasterYou’ll need a pair of pull-up resistor (2K2 to 10K) to 3.3V on the SDA and SCL lines. The Raspberry Pi pins itself is 3.3V IO. So, no level shifter is required here.
For power, you could use the 5V from the Raspberry Pi wired to the VIN of the Mini Ultra Pro.
LIM PHANG MOHKeymasterAre you trying to put them in place of the Li-Ion place?
If yes, it should NOT be more than 4.2V in total but you should NEVER EVER plug in the USB or VIN when the battery is in place as it will charge the alkaline when you should not.
There is plan for a version for non-rechargeable batteries but no ETA at the moment. This allows people to use (and easily purchase) the battery off the shelf as Li-Ion/Pol has more restriction in air shipping.
LIM PHANG MOHKeymasterHi,
Are you running on a Mac?
It shouldn’t unless there’s a code specific in the sketch that doesn’t use the USB port. Try double press the reset button in quick manner. -
AuthorPosts