How to read LoRa Messages in Serial monitor via heltec esp32 - c++

I am new to the esp32 and LoRa messaging.
I am following the two examples in the heltect esp32 lora library.
The two modules I am using to send and receive data have an oled display... and I print their values to the serial monitor. The data values appear on the oled display but they are random characters in the serial monitor like this... "⸮⸮3⸮⸮JS⸮⸮⸮⸮⸮J)⸮⸮".
My question is how can I receive data from the sender in string/float/integer like form so I can perform logic on them. I am new to c++ and lora so any help is welcome.
I am pretty sure this(the first code block directly below this paragraph) is the piece of code responsible for printing the received message, but it is not printing in any type of format I can work with even when I change the "char" dtype to String.
while (LoRa.available()) {
Serial.print((char)LoRa.read());
}
Receiver Code
/*
Check the new incoming messages, and print via serialin 115200 baud rate.
by Aaron.Lee from HelTec AutoMation, ChengDu, China
成都惠利特自动化科技有限公司
www.heltec.cn
this project also realess in GitHub:
https://github.com/Heltec-Aaron-Lee/WiFi_Kit_series
*/
#include "heltec.h"
#define BAND 915E6 //you can set band here directly,e.g. 868E6,915E6
void setup() {
//WIFI Kit series V1 not support Vext control
Heltec.begin(true /*DisplayEnable Enable*/, true /*Heltec.LoRa Disable*/, true /*Serial Enable*/, true /*PABOOST Enable*/, BAND /*long BAND*/);
}
void loop() {
// try to parse packet
int packetSize = LoRa.parsePacket();
if (packetSize) {
// received a packet
Serial.print("Received packet '");
// read packet
while (LoRa.available()) {
Serial.print((char)LoRa.read());
}
// print RSSI of packet
Serial.print("' with RSSI ");
Serial.println(LoRa.packetRssi());
}
}
Sender Code
/*
Basic test program, send date at the BAND you seted.
by Aaron.Lee from HelTec AutoMation, ChengDu, China
成都惠利特自动化科技有限公司
www.heltec.cn
this project also realess in GitHub:
https://github.com/Heltec-Aaron-Lee/WiFi_Kit_series
*/
#include "heltec.h"
#define BAND 915E6 //you can set band here directly,e.g. 868E6,915E6
int counter = 0;
void setup() {
//WIFI Kit series V1 not support Vext control
Heltec.begin(true /*DisplayEnable Enable*/, true /*Heltec.LoRa Disable*/, true /*Serial Enable*/, true /*PABOOST Enable*/, BAND /*long BAND*/);
}
void loop() {
Serial.print("Sending packet: ");
Serial.println(counter);
// send packet
LoRa.beginPacket();
/*
* LoRa.setTxPower(txPower,RFOUT_pin);
* txPower -- 0 ~ 20
* RFOUT_pin could be RF_PACONFIG_PASELECT_PABOOST or RF_PACONFIG_PASELECT_RFO
* - RF_PACONFIG_PASELECT_PABOOST -- LoRa single output via PABOOST, maximum output 20dBm
* - RF_PACONFIG_PASELECT_RFO -- LoRa single output via RFO_HF / RFO_LF, maximum output 14dBm
*/
LoRa.setTxPower(14,RF_PACONFIG_PASELECT_PABOOST);
LoRa.print("hello ");
LoRa.print(counter);
LoRa.endPacket();
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(1000); // wait for a second
}

Perhaps, the serial monitor is configured with the wrong Baud Rate? In my case, default in IDE was 9600, but ESP32 sent with 115200. You can change the Baud Rate in a combobox in the serial monitor.

Related

How would I get the nrFToolbox for BLE app to use Arduino code written using the ArduinoBLE library?

For reference, I am using the Arduino Nano 33 BLE Sense board.
At the moment, I can get the nrFToolbox app to recognize the board as a Bluetooth device, but that's about it. I would like to able to use the app to get data about the temperature and display it.
#include <Arduino_LPS22HB.h> //Pressure sensor, documentation found on https://www.arduino.cc/en/Reference/ArduinoLPS22HB
#include <Arduino_HTS221.h> //Temperature sensor, documentation found on https://www.arduino.cc/en/Reference/ArduinoHTS221
#include <ArduinoBLE.h> //Bluetooth LE sensor, documentation found on https://www.arduino.cc/en/Reference/ArduinoBLE
// Service for the BLE module, using a 128-bit UUID.
BLEService TestService("32BC370F-88AF-4928-B8AB-9B56902FA670");
//TODO: BLE temperature characteristic
//TODO: BLE humidity characteristic
//TODO: BLE pressure characteristic
void setup() {
// put your setup code here, to run once:
Serial.begin(9600); //Initialize the serial connection
while(!Serial); //Will pause until a serial connection is established.
if (!BARO.begin() ) { //Initialize the barometer
Serial.println("Unable to initialize the barometer, stopping.");
while (1);
}
if (!HTS.begin() ) { //Initialize the Temperature & Humidity sensor
Serial.println("Unable to initialize the temp/humidity sensor, stopping.");
while (1);
}
if (!BLE.begin() ) { //Initialize the bluetooth module
Serial.println("Unable to initialize the bluetooth module, stopping");
while (1);
}
/* Set a local name for the BLE device
This name will appear in advertising packets
and can be used by remote devices to identify this BLE device
The name can be changed but maybe be truncated based on space left in advertisement packet
*/
BLE.setLocalName("TestDevice");
BLE.setAdvertisedService(TestService); // add the service UUID
}
void loop() {
// put your main code here, to run repeatedly:
Serial.print("Temperature: ");
Serial.print(HTS.readTemperature(FAHRENHEIT));
Serial.print(" -- Humidity: ");
Serial.print(HTS.readHumidity() );
Serial.print(" -- Pressure: ");
Serial.println(BARO.readPressure() );
delay(1000);
}

ESP8266 I2C slave does not acknowledge data

I have a TM4C123 processor acting as a I2C master and a ESP8266 as a slave. For the ESP I am using the Arduino IDE with ESP8266 support installed at version 2.5.2, which should support the I2C slave mode. However, I can't get it to work. Even with the Arduino slave_receiver example, the slave does not acknowledge (ACK) the master's requests which I am displaying on a scope.
To make sure I am using the right address at least once, I implemented an address sweep on the master. And to make sure I am using the right pins on the ESP I implemented the master mode on the ESP first and did a pin sweep with an I2C slave device. So I am fairly certain neither of this can be the problem.
I am using the Olimex Mod-wifi board, with SDA Pin 12 and SCL Pin 13 (Schematic here)
Can someone help me on this? Here is my code:
// Wire Slave Receiver
// by devyte
// based on the example by Nicholas Zambetti <http://www.zambetti.com>
// Demonstrates use of the Wire library
// Receives data as an I2C/TWI slave device
// Refer to the "Wire Master Writer" example for use with this
// This example code is in the public domain.
#include <Wire.h>
#define SDA_PIN 12
#define SCL_PIN 13
const int16_t I2C_SLAVE = 0x12;
void setup() {
Serial.begin(115200); // start serial for output
Wire.begin(SDA_PIN, SCL_PIN, I2C_SLAVE); // new syntax: join i2c bus (address required for slave)
Wire.onReceive(receiveEvent); // register event
}
void loop() {
delay(1000);
Serial.println("Loop");
}
// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(size_t howMany) {
(void) howMany;
while (1 < Wire.available()) { // loop through all but the last
char c = Wire.read(); // receive byte as a character
Serial.print(c); // print the character
}
int x = Wire.read(); // receive byte as an integer
Serial.println(x); // print the integer
}
I had a compareable issue with the ESP8266. It was no problem sending data between the Arduino Nano (Slave) to the ESP8266 (Master) via I²C. But when I switch the modes (Arduino Nano = Master and ESP8266 = Slave) the Wire example doesn't work.
My workaround for this issue was to reduce the I²C working frequence from 100kHz to about 20kHz.

Use Hardware RX pin as an interrupt pin of arduino

I want to use hardware RX pin of Arduino as interrupt pin. If there is any data available on RX pin, an interrupt signal will be generated, call a callback function to read incoming serial data.I don't want my loop() function constant reading on serial port. I am using this code but my interrupt is not triggered.I also tried by removing digitalPintointerrupt() but getting no response.
`#include <SoftwareSerial.h>
const byte interruptPin = 0;//In arduino MEGA RX 19. TX 18
String msg = "";//Incomming message
#define Line_RX 3 //UART RX
#define Line_TX 2 //UART TX
SoftwareSerial mySerial (Line_TX, Line_RX); //initialize software serial
void setup() {
// put your setup code here, to run once:
Serial.begin(19200);
mySerial.begin(19200);
attachInterrupt(digitalPinToInterrupt(interruptPin), serial_read, HIGH);
}//end setup
void loop() {
// put your main code here, to run repeatedly:
}//end loop
void serial_read(){
char _bite;
sei();//Disable hardware interrupts for a moment
while(Serial.available()>0){
delay(1);//Do not delete this delay
if(Serial.available()>0){
_bite = (char)Serial.read();
msg += _bite;
if(_bite == '\n'){
mySerial.print(msg);//Do what you print your message
msg = "";//Clean message for new one
break;
}//end if
}//end if
}//end while
cli();//re-enabling hardware interrupts
}//en
d serial_read`
sei() ENABLES interrupts, while cli() disables them. Your comments suggest you have them backwards. Perhaps there are other problems, but these instructions are certainly not consistent with your intentions.
If you want to get lower-level, consider a pure interrupt-driven design like:
ISR (USART0_UDRE_vect)
{
// Send next byte and increment pointer
UDR0 = *ub_outptr++;
// Pointer wrapping
if (ub_outptr >= UART_buffer + BUFF_SIZE)
ub_outptr = UART_buffer;
// If buffer is empty: disable interrupt
if(--ub_buffcnt == 0)
UCSR0B &= ~(1 << UDRIE0);
}
I know this takes you out of the Arduino library stuff, so this may not be ideal for you. But it works (the example is for sending data, as I have an active project where the microcontroller sends data to an LCD display. Just an example in AVR-GCC C.)
Try my NeoHWSerial. It is a modified version of the Arduino core class, HardwareSerial, the class used for Serial, Serial1, etc. It adds the ability to register a callback for each received character.

Arduino not reading float level switch signal

Hey I am trying to set up a project at the moment, I have a float level switch connected to pin 2 of my Arduino board, the other end is connected to the 5v in on the arduino.
I want to have the software display a message when the switch goes high but at the moment it goes straight to the message and I know that the switch is not set high as I have it in my hand.
In future it will send a text message when the signal goes high, being used for flood monitoring using a float level switch.
#include "SIM900.h"
#include <SoftwareSerial.h>
#include "sms.h"
SMSGSM sms;
//To change pins for Software Serial, use the two lines in GSM.cpp.
int numdata;
boolean started=false;
char smsbuffer[160];
char n[20];
int closed=0;//Sets initial signal to 0
const int switchPin = 2;
int switchState = 0; // current state of the button
int lastswitchState = 0; // previous state of the button
void setup()
{
//Serial connection.
Serial.begin(9600);
Serial.println("GSM Shield for Flood Early Warning System \n");
pinMode(switchPin, INPUT);
//Start configuration of shield with baudrate.
//For http uses is recommended to use 4800 or slower.
}
void loop() {
closed=digitalRead(switchPin);
// compare the buttonState to its previous state
if (switchState != lastswitchState) {
// if the state has changed, increment the counter
if (switchState == HIGH) {
// if the current state is HIGH then the button
// wend from off to on:
Serial.println("on");
} else {
// if the current state is LOW then the button
// wend from on to off:
Serial.println("off");
}
// Delay a little bit to avoid bouncing
delay(50);
}
// save the current state as the last state,
//for next time through the loop
lastswitchState = switchState;
if (closed == HIGH) {
Serial.println ("Switch signal received");
if (gsm.begin(2400)){
Serial.println("\n status=READY");
started=true;
}
else Serial.println("\n status=IDLE");
if(started){
//Enable this two lines if you want to send an SMS.
if (sms.SendSMS("0871234567", "Arduino SMS"))//Number you wish to text and the message to be sent
Serial.println("\nSMS sent OK");//Alert for Serial monitor once sms sent
}
}
}
You should connect your input pin to GND via a 10KOhm resistor. See https://www.arduino.cc/en/Tutorial/DigitalPins :
"This also means however, that pins configured as pinMode(pin, INPUT) with nothing connected to them, ... will report seemingly random changes in pin state, picking up electrical noise from the environment, or capacitively coupling the state of a nearby pin. ".
And https://www.arduino.cc/en/Reference/DigitalRead :
If the pin isn't connected to anything, digitalRead() can return either HIGH or LOW (and this can change randomly).
In other words, when your switch is open, the input pin is not in a defined state (either on or off). By adding a pulldown resistor (a 10 KOhm resistor between your input pin and GND, the resistor "pulls down" (=toward the ground) your pin, unless the switch is closed, in which case the connection to +5V prevails (because it is a direct connection, without a resistor).

Receiving a sms from a specific number

I am working on a project where my Arduino ATMEGA328 interfaced in SIM900 GSM Shield will receive an sms from the specific number.
I was able to receive the message. But I want my GSM to only receive from a specific number. For example, i only want to receive from +639123456789 number only. Numbers like +639111112222 and +639998887777 and other will be discarded. Can anyone can help me?
EDIT: This is my code.
#include <SoftwareSerial.h>
#include <string.h>
char inchar; // Will hold the incoming character from the GSM shield
String s = "";
SoftwareSerial SIM900(2, 3);
void setup()
{
Serial.begin(9600);
// wake up the GSM shield
SIM900power();
SIM900.begin(9600);
delay(20000); // give time to log on to network.
SIM900.print("AT+CMGF=1\r"); // set SMS mode to text
delay(100);
SIM900.print("AT+CNMI=2,2,0,0,0\r");
// blurt out contents of new SMS upon receipt to the GSM shield's serial out
delay(100);
Serial.println("Ready...");
}
void SIM900power()
// software equivalent of pressing the GSM shield "power" button
{
digitalWrite(9, HIGH);
delay(1000);
digitalWrite(9, LOW);
delay(7000);
}
void loop()
{
if(SIM900.available() > 0)
{
if(SIM900.find("+639123456789 ") && SIM900.find("AUTO"))
{
Serial.println("AUTOMATIC asd");
SIM900.println("AT+CMGD=1,4");
}
}
}
I was able to receive the message. But I want my GSM to only receive
from a specific number.
Do you wish to stop the GSM from receiving SMS from unknown numbers, or do you want to output to serial when the conditions are met?
If it's the former, you may want to talk to your network provider, and consider the architectures pitfalls in this approach.
It immediately deletes the message once it does not satisfies the
condition
On that same if condition where you discard the sms if not sent from numXXX,
add an
else{
SIM900.print("AT+CNMI=2,2,0,0,0\r");
Serial.println("AUTOMATIC asd");
SIM900.println("AT+CMGD=1,4");
// or write high to led pin if that's what you want.......
}
Of course, it would help if we could see that sketch...