I want to make program which read from lora in arduino and receive it to plot the graph in Python. This is my transmit code I sent char value because when I sent it with string, it cannot sent (Idk because of OLED code that I use with or about LoRa sx1278).
So, I want to know
1.Why my code cannot send string?
2.Why in Python, I cannot receive the data from arduino stably?
Here is my code
#include <Wire.h>
#include <MS5611.h>
#include <I2Cdev.h>
#include <MPU6050_6Axis_MotionApps20.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SPI.h>
#include <LoRa.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_MOSI 5
#define OLED_CLK 4
#define OLED_DC 7
#define OLED_CS 8
#define OLED_RESET 6
#define NUM_READINGS 100
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
MS5611 ms5611(0x77);
MPU6050 mpu;
const int ledPin = 13; // Change to the pin where your LED is connected
bool loraMessageSent = false;
int16_t ax, ay, az;
int16_t gx, gy, gz;
int valx, valy, valz;
int x, y, z;
int vx, vy, vz;
char message[25]; // Allocate memory for the message
void setup() {
Serial.begin(9600);
if (!display.begin(SSD1306_SWITCHCAPVCC)) {
Serial.println(F("SSD1306 allocation failed"));
while (1); // Don't proceed, loop forever
}
display.display();
delay(2000);
display.clearDisplay();
if (!ms5611.begin()) {
Serial.println("MS5611 not found, check wiring!");
while (1);
}
Wire.begin();
mpu.initialize();
if (!LoRa.begin(433E6)) { // or 915E6, the MHz speed of your module
Serial.println("Starting LoRa failed!");
while (1);
}
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
valx = map(ax, -17000, 17000, 0, 179);
valy = map(ay, -17000, 17000, 0, 179);
valz = map(az, -17000, 17000, 0, 179);
}
void loop() {
ms5611.read();
int16_t celsius = static_cast<int16_t>(ms5611.getTemperature());
int32_t totalPressure = 0; // Use int32_t for more headroom
for (int i = 0; i < NUM_READINGS; i++) {
ms5611.read();
totalPressure += static_cast<int32_t>(ms5611.getPressure());
delay(10);
}
int32_t avePressure = totalPressure / NUM_READINGS; // Use int32_t
mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
x = map(ax, -17000, 17000, 0, 179);
y = map(ay, -17000, 17000, 0, 179);
z = map(az, -17000, 17000, 0, 179);
vx = x - valx;
vy = y - valy;
vz = z - valz;
Serial.print("Temperature: ");
Serial.print(celsius);
Serial.print(" C Pressure: ");
Serial.print(avePressure);
Serial.print(" hPa");
Serial.print(" Axis X = ");
Serial.print(vx);
Serial.print(" Axis Y = ");
Serial.print(vy);
Serial.print(" Axis Z = ");
Serial.println(vz);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(1, 1);
display.print("Temperature: ");
display.print(celsius);
display.println(" C");
display.print("Pressure: ");
display.print(avePressure);
display.println(" hPa");
display.print("Axis X = ");
display.println(vx);
display.print("Axis Y = ");
display.println(vy);
display.print("Axis Z = ");
display.println(vz);
display.display();
snprintf(message, sizeof(message), "%d,%ld,%d,%d,%d", celsius, avePressure, vx, vy, vz);
if (LoRa.beginPacket()) {
Serial.println(message);
loraMessageSent = LoRa.print(message);
loraMessageSent &= LoRa.endPacket();
} else {
loraMessageSent = false;
}
digitalWrite(ledPin, loraMessageSent ? HIGH : LOW);
}
And here is my receive code in Python
from dash import dcc, html
from dash.dependencies import Input, Output
import plotly.graph_objs as go
import datetime
import serial
import dash
# Create a Dash web application
app = dash.Dash(__name__)
# Define the layout of the web application
app.layout = html.Div([
dcc.Graph(id='temp-graph', config={'displayModeBar': False}),
dcc.Graph(id='pressure-graph', config={'displayModeBar': False}),
dcc.Graph(id='xyz-graph', config={'displayModeBar': False}),
dcc.Interval(
id='graph-update',
interval=1000, # Update the graph every 1 second
n_intervals=0
),
])
# Initialize data lists
time_data = []
temp_data = []
pressure_data = []
x_data = []
y_data = []
z_data = []
# Initialize the serial port connection
ser = serial.Serial('COM4', 9600) # Replace 'COM3' with your actual serial port and baud rate
# Function to update data
def update_data():
# Read data from the serial port
try:
line = ser.readline().decode().strip()
print(line) # Debugging: Print the raw data
# Split the received data by comma
data_values = line.split(",")
if len(data_values) == 5: # Change to 5
new_time = datetime.datetime.now()
try:
new_temp, new_pressure, new_x, new_y, new_z = map(int, data_values)
except ValueError:
print("Error converting values to float")
return # Skip this data point
# Append data to lists
time_data.append(new_time)
temp_data.append(new_temp)
pressure_data.append(new_pressure)
x_data.append(new_x)
y_data.append(new_y)
z_data.append(new_z)
# Keep only the last 10 data points
if len(time_data) > 10:
time_data.pop(0)
temp_data.pop(0)
pressure_data.pop(0)
x_data.pop(0)
y_data.pop(0)
z_data.pop(0)
except Exception as e:
print(f"Error reading from serial port: {e}")
@app.callback([Output('temp-graph', 'figure'),
Output('pressure-graph', 'figure'),
Output('xyz-graph', 'figure')],
[Input('graph-update', 'n_intervals')])
def update_graph(n):
update_data()
print(f"Temperature: {temp_data}")
print(f"Pressure: {pressure_data}")
print(f"X: {x_data}")
print(f"Y: {y_data}")
print(f"Z: {z_data}")
# Create separate Plotly figures for temperature, pressure, and XYZ
temp_fig = go.Figure()
temp_fig.add_trace(go.Scatter(x=time_data, y=temp_data, mode='lines+markers', name='Temperature'))
temp_fig.update_layout(title='Temperature',
xaxis=dict(title='Time'),
yaxis=dict(title='Value'))
pressure_fig = go.Figure()
pressure_fig.add_trace(go.Scatter(x=time_data, y=pressure_data, mode='lines+markers', name='Pressure'))
pressure_fig.update_layout(title='Pressure',
xaxis=dict(title='Time'),
yaxis=dict(title='Value'))
xyz_fig = go.Figure()
xyz_fig.add_trace(go.Scatter(x=time_data, y=x_data, mode='lines+markers', name='X'))
xyz_fig.add_trace(go.Scatter(x=time_data, y=y_data, mode='lines+markers', name='Y'))
xyz_fig.add_trace(go.Scatter(x=time_data, y=z_data, mode='lines+markers', name='Z'))
xyz_fig.update_layout(title='XYZ Values',
xaxis=dict(title='Time'),
yaxis=dict(title='Value'))
return temp_fig, pressure_fig, xyz_fig
if __name__ == '__main__':
app.run_server(debug=False)