Need some advice with my Arduino-FPGA communication code

Hey guys, I have a big problem with my code. I'm using an arduino nano with an Artix 7 FPGA, what i was doing is to communicate the FPGA with arduino using UART. For what reason? To send data from an ADT7420 sensor on FPGA to Arduino.

It works, i receive the data from FPGA with my code, using interruptions and programming uart from zero (no use of uart library) and the result it is showed on a LCD display, but when i try to add other sensors like MQ7 or MG811, it send me an error like this:

"HardwareSerial0.cpp.o (symbol from plugin): In function Serial': (.text+0x0): multiple definition of __vector_18'"

This is my code:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include "CO2Sensor.h"
#include "MQ7.h"

//MG811 configuration
CO2Sensor co2Sensor(A0, 0.99, 100);

//MQ7 configuration
MQ7 mq7(A1,5.0);

// LCD configuration
LiquidCrystal_I2C lcd(0x27, 16, 2); // Adjust address as needed (commonly 0x27 or 0x3F)

volatile byte lowerByte = 0;
volatile byte upperByte = 0;
volatile bool dataReady = false;

void setup() {

  // LCD initialization
  Serial.begin(9600);
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Temp: ");
  lcd.setCursor(0, 1);
  lcd.print("CO:");
  lcd.setCursor(7, 1);
  lcd.print("CO2:");
  // UART setup
  unsigned int ubrr = F_CPU / 16 / 9600 - 1;  // Calculate UBRR value for 9600 baud
  UBRR0H = (ubrr >> 8);
  UBRR0L = ubrr;
  UCSR0B = (1 << RXEN0) | (1 << RXCIE0);  // Enable receiver and RX interrupt
  UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); // 8 data bits, no parity, 1 stop bit

  sei();  // Enable global interrupts
}

void loop() {
  // Check if data is ready to be processed
  if (dataReady) {
    // Combine the two bytes into a 12-bit value
    int combinedValue = (lowerByte << 4) | upperByte;
    combinedValue &= 0x0FFF; // Mask to ensure only 12 bits

    // Calculate integer and fractional parts
    int integerPart = (combinedValue >> 4) & 0xFF;  // The upper 8 bits
    float fractionalPart = (combinedValue & 0x0F) * 0.0625; // The lower 4 bits multiplied by 0.0625

    //CO sensor
    float co_value=mq7.getPPM();

    //CO2 sensor
    int co2_value = co2Sensor.read();

    // Print the temperature on the LCD
    lcd.setCursor(6, 0); // Move cursor to start of temperature display
    lcd.print(integerPart);
    lcd.print(".");
    lcd.print(fractionalPart * 10000, 0); // Print fractional part as an integer (multiplied by 100 for 2 decimal places)
    lcd.setCursor(3, 1);
    lcd.print(co_value);
    lcd.setCursor(11, 1);
    lcd.print(co_value);
    // Print other values

    // Reset the flag
    dataReady = false;
  }
}

// ISR for receiving UART data
ISR(USART_RX_vect) {
  static bool receivingUpperByte = false;

  // Read the received byte from the USART Data Register
  byte receivedByte = UDR0;

  if (!receivingUpperByte) {
    // Store the lower byte
    lowerByte = receivedByte;
    receivingUpperByte = true;
  } else {
    // Store the upper byte and set the flag to indicate data is ready
    upperByte = receivedByte;
    receivingUpperByte = false;
    dataReady = true;
  }
}

A friend told me to stop using nano and try using arduino Mega. Is it necessary to change the hardware? or i can do something on my code? (if there are some mistakes explaining my problem, it is because i don't use my english over years ago xD)

I do not know which libraries you exactly use (you don't provide information how they can be installed) but those libraries probably include Arduino.h which in turn includes HardwareSerial.h which uses the interrupt that you have claimed and hence you have a conflict.

If you go the hard way for serial, you will need to go that hard way for everything serial related.

Hey. Thanks, the MQ7 is on arduino libraries, the CO2 master is from a github and i manually install it, be sure that i use them before to check how they work and check their .cpp file and you are right, they both use Arduino.H... before coming here i check the Atmega 328p datasheet and it seems i just occupied the register from the USART Hardware, maybe that is the problem. Im checking now the Atmega 2560 datasheet to check if it has more other USARTs so i can use them to communicate the MQ7 and the MG811

does the FPGA use a custom serial TTL protocol that requires your to program the UART registers in the nano (I am assuming it is a classic nano)
if the FPGA uses standard TTL serial I would suggest you switch to a microcontroller which has multiple hardware serial interfaces, e.g. a Mega, ESP32, etc
I would tend to use an ESP32 which has onboard WiFi, Bluetooth Classic and BLE, plenty of IO for your sensors, memory, etc and is lower cost than a mega

make sure you test each sensor in a separate program before attempting to implement th complete system

Yeah, my plan was to switch to a better microcontroller, the problem is I put in the title of my project that i will use arduino for this, now i can't change that fact. I bought a mega yesterday, but i didn't use a mega in all my life so i can't say i know how to use its other serials for the sensors hahaha

have a look at MultiSerialMega

1 Like

ty Horace, i will give it a look

Yes you can, just use the big black pence icon at the top of your first post and change the title to what ever you want.

1 Like

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