1

I'm pretty new to programming in C, but getting used to registers and the way communication in C works. Since UART using the official Arduino read() / write() creates a high delay in passing commands through, I tried to translate this Arduino sketch into pure C. (and because I've time to play around, haha)

My ebike's controller and display are communicating using UART. I tried to read the commands and react to speed changes or brake signals, but first of all I need to get rid of this huge delay in updating the display.

I'm using an Robodyn Mega 2560 PRO (Embed), which has 4x hardware serial ports. In the first step I tried to read what's coming in and forward it to the other port. Shouldn't be to hard to implement in C, right?

void setup() {
  Serial1.begin(1200);  // BBSHD controller  @RX18 TX19
  Serial2.begin(1200);  // Display DP-C18    @TX16 RX17
}

void loop() {
  if (Serial2.available()) {
    Serial1.write(Serial2.read());
  }
  if (Serial1.available()) {
    Serial2.write(Serial1.read());
  }
}

That's what I programmed in Atmel Studio 7 so far. I used the C example from ATmega640/1280/1281/2560/2561 - Complete Datasheet (Search for USART_Receive and USART_Transmit) and this guide Simple Serial Communications With AVR libc

Currently I can compile and flash it the 2560, but the communication is not being forwarded. I don't know what the default settings are, that Arduino with Serial uses. Which mode, number of stop bits, .. Is there anything obvious I'm missing?

#define F_CPU 16000000UL
#define BAUD 1200

#include <avr/io.h>
#include <stdio.h>
#include <util/setbaud.h>

void uart_init(void) {
    /* Serial1 controller */
    UBRR1H = UBRRH_VALUE;
    UBRR1L = UBRRL_VALUE;
    /* Serial2 display */
    UBRR2H = UBRRH_VALUE;
    UBRR2L = UBRRL_VALUE;

    /* 8-bit data, 1stop bit*/
    UCSR1C = (1<<UCSZ11) | (1<<UCSZ10);
    UCSR2C = (1<<UCSZ21) | (1<<UCSZ20);

    /* Enable RX and TX */
    UCSR1B = (1<<RXEN1) | (1<<TXEN1);
    UCSR2B = (1<<RXEN2) | (1<<TXEN2);
}

int main(void) {

    uart_init();

    while(1) {
        if (!(UCSR1A & (1<<RXC1))) {        /* Only if data is received */
            while (!(UCSR1A & (1<<UDRE1))); /* Wait for empty transmit buffer */
            UDR2 = UDR1;                    /* Put data into buffer, sends the data */
        }

        if (!(UCSR2A & (1<<RXC2))) {        /* Only if data is received */
            while (!(UCSR2A & (1<<UDRE2))); /* Wait for empty transmit buffer */
            UDR1 = UDR2;                    /* Put data into buffer, sends the data */
        }
    }
}
Tomblarom
  • 1,429
  • 1
  • 15
  • 38
  • 1
    is your baudrate ok? can u post your variable declaration? :) – Alberto Merciai Apr 06 '20 at 10:14
  • I was able to find the issue. The logic in the while loop didn't make sense. I had to remove the negation and read the display before controller, since the display is "asking" the controller for updates. It's only reacting to it. ;) – Tomblarom Apr 06 '20 at 14:00
  • 2
    sound's great! good luck! ;) maybe if u post your solution would be great! – Alberto Merciai Apr 06 '20 at 15:23
  • 1
    Actually, this looks like C++, not like C. Many people are quite sloppy about this, but it's about two different (and often incompatible) languages. – HelpingHand Apr 15 '20 at 18:31

0 Answers0