hexagon5un / AVR-Programming

Code examples for the book "Make: AVR Programming"
http://littlehacks.org/AVR-Programming
MIT License
725 stars 340 forks source link

Chapter5 Serialloopback. "Strange characters" #33

Open Folkert-2 opened 6 years ago

Folkert-2 commented 6 years ago

Testing serial loopback with the listing in Example 5.1 results in "strange" characters being returned. Entering "a" results in the following LED pattern: 01001111, which is capital "O". Typing "c" for example results in LED pattern 01001110, which is capital "N". The message "hello World" is displayed as ú‹…m:ºê+ë. When connecting USB-serial converter Rx and Tx, characters are returned correctly. The program was successfully flashed into an Atmega 168. I have no idea where to start looking for possible causes. Any ideas from your side? Thanks in advance, Folkert

fivdi commented 6 years ago

I've seen similar issues with serial communication when the internal calibrated RC oscillator is used as a clock source. The the internal calibrated RC oscillator provides an approximate 8.0MHz clock not a precise 8.0MHz clock. It was possible to resolve the issue by tweaking the value in the OSCCAL register which is used to trim the calibrated internal RC oscillator.

If it's any help, I typically use the below program to search for values of OSCCAL that function correctly. The program waits to receive a character from a terminal emulator and depending on the character received it will transmit either 1024, 10240, or 1 character back to the terminal emulator. The program then sends the value of the OSCCAL register in decimal to the terminal emulator. If the value of OSCCAL is good, the characters sent back to the terminal emulator will also be good and display correctly, if not, junk will be displayed. The value of OSCCAL is then decremented by one and the program waits until it received the next character and repeats the above process. Typically I'll just keep hitting the character 't' in the terminal emulator looking for good values for OSCCAL.

#include <avr/io.h>
#include <avr/power.h>
#include <util/delay.h>

#define LED      PB0
#define LED_DDR  DDRB
#define LED_PORT PORTB

#define USART_BAUDRATE 9600
#define UBRR_VALUE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)

#define set_bit(sfr, bit) (_SFR_BYTE(sfr) |= (1 << bit))
#define clear_bit(sfr, bit) (_SFR_BYTE(sfr) &= ~(1 << bit))
#define toggle_bit(sfr, bit) (_SFR_BYTE(sfr) ^= (1 << bit))

void usart_init() {
  UBRR0 = UBRR_VALUE;
  UCSR0B = (1 << RXEN0) | (1 << TXEN0);
  UCSR0C = (1 << UCSZ00) | (1 << UCSZ01); // 8 bits, no parity, 1 stop bit
}

void usart_send(uint8_t ch) {
  set_bit(LED_PORT, LED);
  while (!(UCSR0A & (1 << UDRE0)));
  UDR0 = ch;
  clear_bit(LED_PORT, LED);
}

uint8_t usart_receive(void) {
  while(!(UCSR0A & (1 << RXC0)));
  return UDR0;
}

void send_chars(uint16_t count) {
  uint8_t ch = 'a';

  while (count != 0) {
    usart_send(ch);

    if (ch == 'z') {
      ch = 'a';
    } else {
      ++ch;
    }

    --count;
  }
}

void print_byte(uint8_t byte) {
  usart_send('0' + (byte / 100)); /* Hundreds */
  usart_send('0' + ((byte / 10) % 10)); /* Tens */
  usart_send('0' + (byte % 10)); /* Ones */
}

void send_osccal() {
  usart_send(' ');
  usart_send('(');
  print_byte(OSCCAL);
  usart_send(')');
  usart_send(' ');
}

int main(void) {
  clock_prescale_set(clock_div_1); // 8Mhz clock
  usart_init();

  set_bit(LED_DDR, LED); // set LED pin for output

  while (1) {
    uint8_t command = usart_receive();

    switch (command) {
      case 'o':
        send_chars(1024);
        send_osccal();
        break;

      case 't':
        send_chars(10240);
        send_osccal();
        break;

      case 'b':
      default:
        usart_send(command);
        send_osccal();
        break;
    }

    OSCCAL -= 1;
  }
}
Folkert-2 commented 6 years ago

Dear Brian. thanks a lot for your comment. I will test your program in the coming days and report back. So far, I still haven't managed to get a correct serial communication. I have tried with an Atmega328 with a 16 Mhz crystal, used a different Usb-serial converter, applied different Baud rates at the converter, and used an external power source.

Folkert-2 commented 6 years ago

Sorry, I did not mean to close this issue. Pushed the wrong button

fivdi commented 6 years ago

If the ATmega328 was configured to use the external 16MHz crystal and serial communication still didn't work correctly then tweaking OSCCAL isn't going to help and the issue is something else.

If you do try the program above it expects the clock to be running at 8MHz so don't forget to specify -DF_CPU=8000000UL on the command line when calling avr-gcc to compile.

Folkert-2 commented 6 years ago

You are probably right. ButI will try out your program on an Atmega128 with internal clock set to 8 Mhz

Folkert-2 commented 6 years ago

Should read: Atmega168

travisgillespie commented 6 years ago

@Folkert-2 Were you ever able to figure out the issue? If not, hope this helps. Start with a fresh copy of the author's code for the serial loopback example.

  1. Open CoolTerm, click Options > Data Bits > 7.

  2. This can also be achieved in Mac Terminal if you have pySerial installed. From root directory type python -m serial.tools.miniterm \<usbserial port path>. Now set to 7 bits. Press ctrl+t then ctrl+h. Press ctrl+t again followed by 7.

Now you are all set!

Folkert-2 commented 6 years ago

Dear Travis

Thanks for asking and for the additional suggestions and material. One thing I discovered is that I used the wrong USB-serial converter. It had a 12 V output. As far as I have checked, the AVR is still ok (ports were functioning) but also with an Arduino as converter, communication didn’t work. I have then abandoned this project and started working on something completely different. I have now bought a 5V converter and some new AVR 168 and will try again soon. I will keep you informed.

Best, Folkert

Von: Travis Gillespie [mailto:notifications@github.com] Gesendet: Sonntag, 18. März 2018 17:10 An: hexagon5un/AVR-Programming Cc: Folkert-2; Mention Betreff: Re: [hexagon5un/AVR-Programming] Chapter5 Serialloopback. "Strange characters" (#33)

@Folkert-2 https://github.com/folkert-2 Were you ever able to figure out the issue? If not, hope this helps. Start with a fresh copy of the author's code for the serial loopback example.

· Make file: The only things you would need to initially check/update are MCU = (e.g. MCU = atmega168), and LIBDIR path to directory AVR-Programming-Library (e.g. LIBDIR = ../../AVR-Programming-Library). Given, F_CPU = 1000000UL, and BAUD = 9600UL. As long as the author's remaining code is untouched for now, you should be able to produce the same results as me.

· LEDs: Double check the wiring on your breadboard. My initial guess is some of the wires are mixed up. Use Figure 3-4 https://photos.app.goo.gl/7H8rbfOTtzjc2qni2 as a reference. Pressing the following keys on your keyboard should produce the corresponding LED patterns: a = 11100001 b = 11100010 c = 11100011

· Serial Monitor: Let's fix those strange characters, they are frustrating. If your terminal software is set to the same baud rate as the microcontroller, then my guess is the program you are using is set to 8 data bits. The simple fix is to set the terminal to 7 bits. The last bullet point will walk you through the setup.

8 bits will work with the transmitByte(serialCharacter); function which is located in the serialLoopback.c file. For example pressing the key a will return a. But, you will see strange characters when using other functions such as printString("Hello World!\r\n");, and printBinaryByte(serialCharacter);.

Play around with it. Replace transmitByte(serialCharacter); with printBinaryByte(serialCharacter);. If you have the LEDs hooked up, you will be able to see both LED pattern and terminal produce the same result.

· Terminal Setup: This can be done with any terminal, I will list a couple options that I use, but since I'm working on a mac follow the link for other terminal options https://learn.sparkfun.com/tutorials/terminal-basics/all .

  1. Open CoolTerm, click Options > Data Bits > 7.

  2. This can also be achieved in Mac Terminal if you have pySerial installed. From root directory type python -m serial.tools.miniterm . Now set to 7 bits. Press ctrl+t then ctrl+h. Press ctrl+t again followed by 7.

Now you are all set!

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/hexagon5un/AVR-Programming/issues/33#issuecomment-374011386 , or mute the thread https://github.com/notifications/unsubscribe-auth/Agv6ld1rwgw87B9g_RIKXEFl4IrkD2ppks5tfobzgaJpZM4Q8K_c . https://github.com/notifications/beacon/Agv6lQNmOlR1dpqqPi_T-oSbu21EiL9Lks5tfobzgaJpZM4Q8K_c.gif


Diese E-Mail wurde von Avast Antivirus-Software auf Viren geprüft. https://www.avast.com/antivirus

Folkert-2 commented 5 years ago

Dear Travis

Sorry for the very late reply. I finally managed to find time for picking this up again. With the proper USB-serial converter (i.e. 5V) everything works fine.

Thanks again for your input.

Best regards, Folkert

Von: Travis Gillespie [mailto:notifications@github.com] Gesendet: Sonntag, 18. März 2018 17:10 An: hexagon5un/AVR-Programming Cc: Folkert-2; Mention Betreff: Re: [hexagon5un/AVR-Programming] Chapter5 Serialloopback. "Strange characters" (#33)

@Folkert-2 https://github.com/folkert-2 Were you ever able to figure out the issue? If not, hope this helps. Start with a fresh copy of the author's code for the serial loopback example.

· Make file: The only things you would need to initially check/update are MCU = (e.g. MCU = atmega168), and LIBDIR path to directory AVR-Programming-Library (e.g. LIBDIR = ../../AVR-Programming-Library). Given, F_CPU = 1000000UL, and BAUD = 9600UL. As long as the author's remaining code is untouched for now, you should be able to produce the same results as me.

· LEDs: Double check the wiring on your breadboard. My initial guess is some of the wires are mixed up. Use Figure 3-4 https://photos.app.goo.gl/7H8rbfOTtzjc2qni2 as a reference. Pressing the following keys on your keyboard should produce the corresponding LED patterns: a = 11100001 b = 11100010 c = 11100011

· Serial Monitor: Let's fix those strange characters, they are frustrating. If your terminal software is set to the same baud rate as the microcontroller, then my guess is the program you are using is set to 8 data bits. The simple fix is to set the terminal to 7 bits. The last bullet point will walk you through the setup.

8 bits will work with the transmitByte(serialCharacter); function which is located in the serialLoopback.c file. For example pressing the key a will return a. But, you will see strange characters when using other functions such as printString("Hello World!\r\n");, and printBinaryByte(serialCharacter);.

Play around with it. Replace transmitByte(serialCharacter); with printBinaryByte(serialCharacter);. If you have the LEDs hooked up, you will be able to see both LED pattern and terminal produce the same result.

· Terminal Setup: This can be done with any terminal, I will list a couple options that I use, but since I'm working on a mac follow the link for other terminal options https://learn.sparkfun.com/tutorials/terminal-basics/all .

  1. Open CoolTerm, click Options > Data Bits > 7.

  2. This can also be achieved in Mac Terminal if you have pySerial installed. From root directory type python -m serial.tools.miniterm . Now set to 7 bits. Press ctrl+t then ctrl+h. Press ctrl+t again followed by 7.

Now you are all set!

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/hexagon5un/AVR-Programming/issues/33#issuecomment-374011386 , or mute the thread https://github.com/notifications/unsubscribe-auth/Agv6ld1rwgw87B9g_RIKXEFl4IrkD2ppks5tfobzgaJpZM4Q8K_c . https://github.com/notifications/beacon/Agv6lQNmOlR1dpqqPi_T-oSbu21EiL9Lks5tfobzgaJpZM4Q8K_c.gif


Diese E-Mail wurde von Avast Antivirus-Software auf Viren geprüft. https://www.avast.com/antivirus