How can i communicate OpenMV with Arduino using UART in real time without data loss

I’m using an openMV to communicate with an Arduino Mega 2560, but during UART communication data is easily lost and I need precision to read data in real time, can anyone help me?

OpenMV code :

import sensor, image, time
from pyb import UART

uart = UART(1, 19200, timeout_char=200)
uart.init(19200, bits=8, parity=None, stop=1)

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)

clock = time.clock()

while(True):
    uart.write('a')
    time.sleep_ms(500)

Arduino Code :

char read;

void setup() {
  Serial.begin(9600);
  Serial2.begin(19200);

}

void loop() {
  if(Serial2.available() > 0)
  {
    read = Serial2.read();
    Serial.println(read);
    
  }

}

I’m using pin2 from openMV to send it to RX2 from arduino

But the data ends up being lost during real-time UART communication.

It doesn’t look like data is getting lost; it is corrupted. Do both devices share a common ground?

I’m using a battery that powers the Arduino and OpenMV, the Arduino and OpenMV gnds are connected to the battery, does this affect anything? Would it be better to connect a direct gnd between the Arduino and the OpenMV
?

As long as they both reference the same ground, it should work.

If the rate at which the camera is sending uart data matches the rate at which it’s being printed on the screen by the Arduino, but the characters are wrong, then this implies there’s some signal corruption, which would be due to a lack of ground between the two boards.

I have another question. I wanted when openMV sent the data, the Arduino would interrupt and read this data, but when I did that it interrupted but was unable to read the data from openMV, so I tested the same code but between two arduinos and it worked, but between OpenMV and Arduino it didn’t work.

Arduino Code :

String receivedData = "";
boolean newData = false;

void setup() {
  Serial.begin(9600);

  Serial.setTimeout(10); 
  attachInterrupt(digitalPinToInterrupt(0), serialEvent, RISING);
}

void loop() {
  if (newData) {
    Serial.print("Dados recebidos: ");
    Serial.println(receivedData);

    receivedData = "";
    newData = false;
  }
}

void serialEvent() {
  while (Serial.available()) {

    char c = Serial.read();

    receivedData += c;

    if (c == '\n') {
      newData = true; 
      break; 
    }
  }
}

OpenMV Code :

import time
import pyb

uart = pyb.UART(1, 9600)  

while True:
    uart.write("Hello, Arduino!\n")
    time.sleep(1)

Uh, you’re using the same serial port for debugging and talking to the OpenMV Cam. This won’t work.

The first piece of code you had posted made more sense.

Thank you, on Monday I will do a test to fix these problems and I will tell you the results

I did this, but the error persists

I’m not sure what the error would be then… the UART definitely works fine. I can only think it’s an electrical or wiring issue. Your code looks more or less fine. Please pass the timeout_char=100 as the example code specifies when creating the UART.

Also, I would not use a baud rate of 9600 ever anymore. Make 115200 you min. 9600 bps means each character takes over a millisecond to send.

I removed all the wires from the openMV and left only the communication wire and it worked and i change the P2 to P1

Hi, I wrote an RPC library explicitly to solve issues folks have with comms: openmv/openmv-arduino-rpc: Remote Procedure/Python Call Library for Arduino (github.com). I’d prefer to only provide help support for folks using this as it handles all types of crazy software stuff you need to do.

Generally, if you want to do two processor comms you should invest in one of these: Saleae Logic Analyzers. It’s expensive but one of the most valuable tools on my bench. It saves you so much time that the investment will be paid off instantly with how much sanity is restored.

This stuff is very hard to debug otherwise.

1 Like

I made this code that reads the Arduino’s UART 3 by interrupting it, but I can only read one character, can you help?

Arduino Code:

char data;

void setup() 
{
  Serial.begin(115200);

  initUART3();

  sei();
}

void loop() 
{
  Serial.println(data);
}


void initUART3() {
  uint16_t ubrr_value = 8;  
  UBRR3H = (ubrr_value >> 8) & 0xFF;
  UBRR3L = ubrr_value & 0xFF;

  UCSR3C = (1 << UCSZ31) | (1 << UCSZ30);

  UCSR3B = (1 << RXEN3) | (1 << TXEN3) | (1 << RXCIE3);
}


ISR(USART3_RX_vect)
{
  data = UDR3;
}

OpenMV code :

import sensor, image, time
from pyb import UART

uart = UART(1, 115200, timeout_char=100)
uart.init(115200)

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)

clock = time.clock()

while(True):
    uart.write("11")

On the OpenMV Cam H7/H7 Plus this code sends a character at 115200 bps via UART3:

import time
from pyb import UART

# Always pass UART 3 for the UART number for your OpenMV Cam.
# The second argument is the UART baud rate. For a more advanced UART control
# example see the BLE-Shield driver.
uart = UART(3, 115200, timeout_char=200)

while True:
    uart.write("Hello World!\r")
    time.sleep_ms(10)

UART1 is on a different set of pins and uses P1.

import time
from pyb import UART

# Always pass UART 3 for the UART number for your OpenMV Cam.
# The second argument is the UART baud rate. For a more advanced UART control
# example see the BLE-Shield driver.
uart = UART(1, 115200, timeout_char=200)

while True:
    uart.write("Hello World!\r")
    time.sleep_ms(10)

I cannot provide help with code that you are doing on the Arduino with register level access.