Hello, my code is receiving data from another device and I am trying to display it on an LCD. Its is a 20x4 LCD and i have it hooked up to the I2c connections and those connections are hooked up with a Qwiic cable.
void OnDataRecv(const uint8_t *mac_addr,const uint8_t* data, int data_len) {
char macStr[18];
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
if(data_len != 2*sizeof(float))
{
Serial.println("I haven't received 8 bytes of gps data.");
return;
}
const float* gpsData = reinterpret_cast<const float*>(data);
float currentPos[2] = {MYCOORDINATES};
float radius = 3956.6;
const float two = 2.0;
float delta_lat = radians(currentPos[0] - gpsData[0]);
float delta_lon = radians(currentPos[1] - gpsData[1]);
float a = sq(sin(delta_lat/two)) + cos(radians (gpsData[0])) * cos(radians (currentPos[0])) * sq(sin(delta_lon/two));
float c = two * asin(sqrt(a));
float d = radius * c;
Serial.print("Latitude: ");
Serial.println(gpsData[0],8);
Serial.print("Longitude: ");
Serial.println(gpsData[1],8);
Serial.print("Distance: ");
Serial.println(d,8);
}
void loop() {
i2cSendValue(gpsData[0]);
}
void i2cSendValue(float value)
{
Wire.beginTransmission(DISPLAY_ADDRESS1); // transmit to device #1
Wire.write('|'); //Put LCD into setting mode
Wire.write('-'); //Send clear display command
Wire.print("Lat: ");
Wire.print(value);
Wire.endTransmission(); //Stop I2C transmission
}
The error I get is that the gpsData was not declared in this scope. I am not sure what the next steps are. Where it says MYCOORDINATES, its just my inputted coordinates.
When i use this example
#include <Wire.h>
#define DISPLAY_ADDRESS1 0x72 //This is the default address of the OpenLCD
int cycles = 0;
void setup()
{
Wire.begin(); //Join the bus as master
//By default .begin() will set I2C SCL to Standard Speed mode of 100kHz
//Wire.setClock(400000); //Optional - set I2C SCL to High Speed Mode of 400kHz
Serial.begin(115200); //Start serial communication at 9600 for debug statements
Serial.println("OpenLCD Example Code");
//Send the reset command to the display - this forces the cursor to return to the beginning of the display
Wire.beginTransmission(DISPLAY_ADDRESS1);
Wire.write('|'); //Put LCD into setting mode
Wire.write('-'); //Send clear display command
Wire.endTransmission();
}
void loop()
{
cycles++; //Counting cycles! Yay!
// Serial.print("Cycle: "); //These serial.print statements take multiple miliseconds
// Serial.println(cycles);
i2cSendValue(cycles); //Send the four characters to the display
delay(50); //The maximum update rate of OpenLCD is about 100Hz (10ms). A smaller delay will cause flicker
}
//Given a number, i2cSendValue chops up an integer into four values and sends them out over I2C
void i2cSendValue(int value)
{
Wire.beginTransmission(DISPLAY_ADDRESS1); // transmit to device #1
Wire.write('|'); //Put LCD into setting mode
Wire.write('-'); //Send clear display command
Wire.print("Cycles: ");
Wire.print(value);
Wire.endTransmission(); //Stop I2C transmission
}
The code works on my display if that helps
Cross posted in Displays.
Cross posted in Displays
Yeah i know, i was hoping more people view it
Cross posting wastes members time when multiple members give the same advice on different threads. And it does not make you any friends as cross posting is very much discouraged. See #13 in the how to use this forum sticky.
Sorry about that.
The error message that I am getting is
"SlaveWORKING:90:14: error: 'gpsData' was not declared in this scope
i2cSendValue(gpsData[0]);"
Also, to display whatever I want, does it need to be in the void loop?
Is that the complete sketch?
Where do you declare the gpsData array?
void OnDataRecv(const uint8_t *mac_addr,const uint8_t* data, int data_len) {
...
const float* gpsData = reinterpret_cast<const float*>(data);
...}
void loop() {
i2cSendValue(gpsData[0]);
}
gpsData is only visible to OnDataRecv
Look up "scope"
Yeah so the array comes in from the other device, I am trying to display it on a LCD. There is more to the sketch. The entire code is
#include <TinyGPS++.h>
#include <math.h>
#include <esp_now.h>
#include <WiFi.h>
#include <Wire.h>
#define CHANNEL 1
#define DISPLAY_ADDRESS1 0x72
float radius_of_earth = 6371;
// Init ESP Now with fallback
void InitESPNow() {
WiFi.disconnect();
if (esp_now_init() == ESP_OK) {
Serial.println("ESPNow Init Success");
}
else {
Serial.println("ESPNow Init Failed");
ESP.restart();
}
}
// config AP SSID
void configDeviceAP() {
char* SSID = "Slave_1";
bool result = WiFi.softAP(SSID, "Slave_1_Password", CHANNEL, 0);
if (!result) {
Serial.println("AP Config failed.");
} else {
Serial.println("AP Config Success. Broadcasting with AP: " + String(SSID));
}
}
void setup() {
Serial.begin(115200);
//Set device in AP mode to begin with
WiFi.mode(WIFI_AP);
configDeviceAP();
Serial.print("AP MAC: "); Serial.println(WiFi.softAPmacAddress());
InitESPNow();
esp_now_register_recv_cb(OnDataRecv);
}
void OnDataRecv(const uint8_t *mac_addr,const uint8_t* data, int data_len) {
char macStr[18];
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
if(data_len != 2*sizeof(float))
{
Serial.println("I haven't received 8 bytes of gps data.");
return;
}
const float* gpsData = reinterpret_cast<const float*>(data);
float currentPos[2] = {47.9395695279039,-99.76240193843842};
float radius = 3956.6;
const float two = 2.0;
float delta_lat = radians(currentPos[0] - gpsData[0]);
float delta_lon = radians(currentPos[1] - gpsData[1]);
float a = sq(sin(delta_lat/two)) + cos(radians (gpsData[0])) * cos(radians (currentPos[0])) * sq(sin(delta_lon/two));
float c = two * asin(sqrt(a));
float d = radius * c;
Serial.print("Latitude: ");
Serial.println(gpsData[0],8);
Serial.print("Longitude: ");
Serial.println(gpsData[1],8);
Serial.print("Distance: ");
Serial.println(d,8);
}
void loop() {
}
Im not sure how to use the scope for it since the data thats coming in is the data I am trying to display and the data is always changing.
You changed the code from your original post. Is it giving the same error?
No this is the working code but it is displaying on the serial monitor. I am trying to display the results into a i2c LCD. I tried to implement the example code that I posted earlier because that worked with my LCD.
So you want to combine the LCD code with the last code that you posted?
Here are a couple tutorials on combining codes.
Combining sketches.
Merging code.
Give it a shot and post the results. If you have trouble, describe the issue and post any error messages verbatim.
Sorry, I think that I understand, now.
Im not sure how to use the scope for it
evanmars was not talking about an oscilloscope. He meant scope as in the visibility and lifetime of a variable. In the code in your original post the gpsData variable is declared in the OnDataRecv function so is only visible inside of that function. When you try to access the variable outside of OnDataRecv (in loop()) it does not exist so the out of scope error.
Yes exactly,
Since I am trying to code the LCD part in the loop, I just don’t really know how to code the inbound coordinates into the LCD. When I was trying to use the information from onDataRec, it doesn’t let me outside that void.
Because you declared the gpsData variable inside the onDataRecv function, it only exists inside that function. (It's a function, not a "void" btw).
If you declared it outside of all the functions, it'd be a "global" variable, and would be accessible to all functions.
This is part of a subject called variable scope.
How would I declare it if the info is getting imported inside that function?
Please read the page on scope that I linked. You need to know the meaning of the terms global and local scope.
OK. You could make a copy gpsData into variables that have global scope and use that to send to the LCD.
First declare variables in global scope to hold the values.
Serial.println("AP Config Success. Broadcasting with AP: " + String(SSID));
}
}
float latitude = 0;
float longitude = 0;
float distance = 0;
void setup() {
Then in the OnDataRecv function give those variables values
latitude = gpsData[0];
longitude = gpsData[1];
distance = d;
Serial.print("Latitude: ");
Serial.println(gpsData[0],8);
Serial.print("Longitude: ");
Serial.println(gpsData[1],8);
Serial.print("Distance: ");
Serial.println(d,8);
Then you can use latitude, longitude and distance in your function to print to the LCD.
So another issue that is happening with the code is that
#include <TinyGPS++.h>
#include <math.h>
#include <esp_now.h>
#include <WiFi.h>
#include <Wire.h>
#define CHANNEL 1
#define DISPLAY_ADDRESS1 0x72
float radius_of_earth = 6371;
float latitude=0;
float longitude = 0;
float distance = 0;
// Init ESP Now with fallback
void InitESPNow() {
WiFi.disconnect();
if (esp_now_init() == ESP_OK) {
Serial.println("ESPNow Init Success");
}
else {
Serial.println("ESPNow Init Failed");
ESP.restart();
}
}
// config AP SSID
void configDeviceAP() {
char* SSID = "Slave_1";
bool result = WiFi.softAP(SSID, "Slave_1_Password", CHANNEL, 0);
if (!result) {
Serial.println("AP Config failed.");
} else {
Serial.println("AP Config Success. Broadcasting with AP: " + String(SSID));
}
}
void setup() {
Wire.begin();
Serial.begin(115200);
//Set device in AP mode to begin with
WiFi.mode(WIFI_AP);
configDeviceAP();
Serial.print("AP MAC: "); Serial.println(WiFi.softAPmacAddress());
InitESPNow();
esp_now_register_recv_cb(OnDataRecv);
Wire.beginTransmission(DISPLAY_ADDRESS1);
Wire.write('|'); //Put LCD into setting mode
Wire.write('-'); //Send clear display command
Wire.endTransmission();
}
void OnDataRecv(const uint8_t *mac_addr,const uint8_t* data, int data_len) {
char macStr[18];
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
if(data_len != 2*sizeof(float))
{
Serial.println("I haven't received 8 bytes of gps data.");
return;
}
const float* gpsData = reinterpret_cast<const float*>(data);
float currentPos[2] = {47.9395695279039,-99.76240193843842};
latitude = gpsData[0];
longitude = gpsData[1];
float radius = 3956.6;
const float two = 2.0;
float delta_lat = radians(currentPos[0] - gpsData[0]);
float delta_lon = radians(currentPos[1] - gpsData[1]);
float a = sq(sin(delta_lat/two)) + cos(radians (gpsData[0])) * cos(radians (currentPos[0])) * sq(sin(delta_lon/two));
float c = two * asin(sqrt(a));
float d = radius * c;
Serial.print("Latitude: ");
Serial.println(gpsData[0],8);
Serial.print("Longitude: ");
Serial.println(gpsData[1],8);
Serial.print("Distance: ");
Serial.println(d,8);
}
void loop() {
Wire.beginTransmission(DISPLAY_ADDRESS1); // transmit to device #1
Wire.write('|'); //Put LCD into setting mode
Wire.write('-'); //Send clear display command
Wire.print("Latitude: ");
Wire.print(latitude,7);
delay(50);
Wire.endTransmission();
}
I mean im not getting a coding error, but when I add anything besides
Wire.print("Latitude: ");
Wire.print(latitude,7);
The LCD goes blank. Any reason of that?
I tried to add the longitude and the screen doesn't display anything