How to use LoRa sx1278 with arduino Atmel atmega328pb Xplained mini?

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)

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.