I did everything. I shutoff the bits to disable the output processing in the termios structure, properly set the baud rate and character size and disabled parity, flush the output and input buffers before sending. Even after all this linux serial still doesn't work the way I want it to. Canonical mode is not even on in the first place, everything is raw bytes. Btw I am using arch linux connected to an arduino nano with an usb cable which will receive the bytes from PC and display them on a lcd. When I send a byte from PC, e.g char 'A', it apears to get corrupted during the transmisson process, and arduino displays the corrupted byte. Everytime I send character 'A' it shows ascii value 254 on the lcd which is clearly wrong. How do I solve this problem?
My C code on pc:
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <unistd.h>
int main(int argc, char **argv)
{
int serial_port = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
getchar();
struct termios old_tty;
struct termios new_tty;
if (tcgetattr(serial_port, &new_tty) != 0) {
printf("Error %i from tcgetattr: %s\n", errno, strerror(errno));
return 1;
}
old_tty = new_tty;
new_tty.c_cflag &= ~(CSTOPB | CSIZE | PARENB);
new_tty.c_cflag |= CS8;
new_tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
new_tty.c_oflag &= ~OPOST;
new_tty.c_iflag &= ~(IXON | IXOFF | IXANY | INPCK | ISTRIP);
//new_tty.c_cc[VMIN] = 0;
//new_tty.c_cc[VTIME] = 0;
cfsetispeed(&new_tty, B9600);
cfsetospeed(&new_tty, B9600);
if (tcsetattr(serial_port, TCSANOW, &new_tty) != 0) {
printf("Error %i from tcsetattr: %s\n", errno, strerror(errno));
return 1;
}
tcflush(serial_port, TCIOFLUSH);
unsigned char val = 'A';
write(serial_port, &val, sizeof(val));
getchar();
tcsetattr(serial_port, TCSANOW | TCSADRAIN, &old_tty);
close(serial_port);
return 0;
}
Code on Arduino:
void setup() {
lcd.begin(16, 2); // begins connection to the LCD module
lcd.backlight(); // turns on the backlight
lcd.clear();
lcd.setCursor(0, 0);
Serial.begin(9600);
lcd.print("Init done");
}
void loop() {
if (Serial.available() > 0) {
uint8_t x = Serial.read();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("I received: ");
lcd.setCursor(0, 1);
lcd.print(x);
}
}
Related
I am working on understanding ADC with an arduino and a LCD shield that has buttons. I like to work in Atmel Studio and work to write my own libraries through research and the datasheet. My goal is to write the ADC value to the screen. If I write an Arduino Sketch with the analogRead() function it works, but I can not get it to read anything on the LCDw with my Atmel Studio program. The LCD does work as I can write other information on the LCD. My program is below. Any ideas would really help. Thanks!!!
Analog Header
#include<util/delay.h>
void adc_init(void)
{
ADMUX = (1<<REFS0); //select AVCC as reference
ADCSRA = (1<<ADEN) | 7; //enable (ADEN) and prescale = 128 (16MHz/128 = 125kHz)
}
int readAdc(char chan)
{
ADMUX = (1<<REFS0) | (chan & 0x0f); //select ref (REFS0) and channel
ADCSRA |= (1<<ADSC); //start the conversion
while (ADCSRA & (1<<ADSC)); //wait for end of conversion
return ADC; //Return 16 Bit Reading Register
}
Main Program
#ifndef F_CPU
#define F_CPU 16000000UL // 16 MHz clock speed
#endif
#define D4 eS_PORTD4
#define D5 eS_PORTD5
#define D6 eS_PORTD6
#define D7 eS_PORTD7
#define RS eS_PORTB0
#define EN eS_PORTB1
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include "lcd328.h"
#include "myHeader328.h"
/*--------------------------------------------------------
-- initScreen() initializes the screen
--------------------------------------------------------*/
void initScreen()
{
Lcd4_Init(); //Initialize Screen
Lcd4_Clear(); //Clear Screen
Lcd4_Set_Cursor(1,0);
Lcd4_Write_String("Count:0");
}
/*--------------------------------------------------------
-- refreshScreen() refreshed the screen
--------------------------------------------------------*/
void refreshScreen(int count2)
{
char countStr[5];
sprintf(countStr, "%i", count2);
Lcd4_Set_Cursor(1,6);
Lcd4_Write_String(countStr);
_delay_ms(50);
}
/*--------------------------------------------------------
-- main()
--------------------------------------------------------*/
int main(void)
{
DDRD = 0xFF;
DDRB = 0xFF;
DDRC = 0x00;
initScreen();
PORTB = PORTB | (1<<PORTB2); //Turn on backlight
int adcOut = 4;
while(1)
{
adcOut = readAdc(0);
refreshScreen(adcOut);
_delay_ms(500);
}
}
You had to call adc_init() in your main loop.
/*--------------------------------------------------------
-- main()
--------------------------------------------------------*/
int main(void)
{
DDRD = 0xFF;
DDRB = 0xFF;
DDRC = 0x00;
initScreen();
adc_init(); //!!!!!
PORTB = PORTB | (1<<PORTB2); //Turn on backlight
int adcOut = 4;
while(1)
{
adcOut = readAdc(0);
refreshScreen(adcOut);
_delay_ms(500);
}
}
I'm trying to read from Arduino (who's sending char '4' constantly) with XBee.
I have tried writing from the PC to Arduino, and it works, so the connection is correct.
When I execute de following code, the terminal doesn't show anything and don't finish the program, so it gets stuck on reading.
#include <stdio.h> // Standard input / output functions
#include <stdlib.h>
#include <string.h> // String function definitions
#include <unistd.h> // UNIX standard function definitions
#include <fcntl.h> // File control definitions
#include <errno.h> // Error number definitions
#include <termios.h> // POSIX terminal control definitions
#define XBEE "/dev/ttyUSB0"
#define BAUDRATE B9600
int main(int argc,char** argv)
{
struct termios tio;
struct termios stdio;
struct termios old_stdio;
int tty_fd = open(XBEE , O_RDWR| O_NOCTTY);
cfsetospeed(&tio,BAUDRATE);
cfsetispeed(&tio,BAUDRATE); // Baudrate is declared above
tcsetattr(tty_fd,TCSANOW,&tio);
// for(i;i<5;i++){
// write(tty_fd,&c,1); //If new data is available on the console, send it to the serial port
// write(tty_fd,&o,1); //If new data is available on the console, send it to the serial port
// }
int n=0;
char buf = '\0';
/* Whole response*/
do
{
n = read( tty_fd, &buf, sizeof(char) );
}
while( n > 0);
if (n < 0)
{
printf("ERROR READING");
}
else if (n == 0)
{
printf("Read nothing!");
}
else
{
printf("Response: %c",buf);
}
close(tty_fd);
tcsetattr(STDOUT_FILENO,TCSANOW,&old_stdio);
return EXIT_SUCCESS;
}
How do I solve this?
UPDATE
I tried this other code and receive a warning: turning off output flushing and then the terminal froze.
#include <stdio.h> // Standard input / output functions
#include <stdlib.h>
#include <string.h> // String function definitions
#include <unistd.h> // UNIX standard function definitions
#include <fcntl.h> // File control definitions
#include <errno.h> // Error number definitions
#include <termios.h> // POSIX terminal control definitions
#define XBEE "/dev/ttyUSB0"
#define BAUDRATE B9600
int main(int argc,char** argv)
{
struct termios tio;
struct termios stdio;
struct termios old_stdio;
struct termios options;
int tty_fd = open(XBEE , O_RDWR | O_NOCTTY | O_NDELAY);
cfsetospeed(&tio,BAUDRATE);
cfsetispeed(&tio,BAUDRATE); // Baudrate is declared above
tcsetattr(tty_fd,TCSANOW,&tio);
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
// for(i;i<5;i++){
// write(tty_fd,&c,1);//if new data is available on the console, send it to serial port
// write(tty_fd,&o,1);//if new data is available on the console, send it to serial port
// }
int n=0;
char buf = '1';
int i = 1;
/* Whole response*/
while(i==1){
n = read( tty_fd, &buf, sizeof(char) );
if (n < 0)
{
printf("ERROR READING");
}
else if (n == 0)
{
printf("Read nothing!");
}
else
{
printf("Response: %c",buf);
close(tty_fd);
break;
}
}
tcsetattr(STDOUT_FILENO,TCSANOW,&old_stdio);
return EXIT_SUCCESS;
}
If you're going to be using C to communicate with XBee modules, you might want to check out this Open Source XBee Host library. You could just use the serial driver from it in your code, or take a look at the xbee_term sample program as a simple terminal.
If you are printing data, why are you using printf? You must use the Serial.print() syntax w.r.t the Arduino IDE.
I am trying to read the Atmega8's 16-bit counter, but the output is never > 255. The Atmega8 is configured as an Arduino. I know it has to be read 8-bits at a time, but it doesn't seem to be working. Look at the code in readCounder() function, and the output from Serial.println.
#include <Arduino.h>
#include <avr/io.h>
#include <string.h>
#define IN_BUF_LEN 65
#define OUT_BUF_LEN 128
// Pin 13 has an LED connected
int pinLed = 13;
char cmdBuf[IN_BUF_LEN];
char outBuf[128];
char *token;
void readCounter(){
uint8_t count1, count2;
uint16_t count;
/* Disable interrupts */
noInterrupts();
count = TCNT1;
count1 = TCNT1H;
count2 = TCNT1L;
// enable interrupts
interrupts();
snprintf(outBuf, OUT_BUF_LEN, "Count:%d, %d, %d", count,count1,count2);
Serial.println(outBuf);
}
// the setup routine runs once when you press reset:
void setup() {
// initialize the digital pin as an output.
pinMode(pinLed, OUTPUT);
Serial.begin(19200);
// Turn on the counter, Clock on Rise
TCCR1B |= (1 << CS12) | (1 << CS11) | (1 << CS10);
}
// the loop routine runs over and over again forever:
void loop() {
digitalWrite(pinLed, HIGH);
delay(50);
digitalWrite(pinLed, LOW);
int bytesRead = Serial.readBytesUntil(10, cmdBuf, IN_BUF_LEN - 1);
cmdBuf[bytesRead] = 0;
if (bytesRead > 0){
token = strtok(cmdBuf, " ");
if(!strcasecmp(token, "readCounter")){
readCounter();
}
}
}
When readCounter() is called, Serial.println typically outputs:
Count:30, 0, 30
Count:130, 0, 130
Count:250, 0, 250
Count:236, 0, 236
Count:72, 0, 72
Verify the values of TCCR1A and TCCR1B to make sure timer 1 isn't in a 8-bit mode such as 8-bit PWM or CTC with a TOP value less than 256.
I have a simple program written in C which uses termios to send a basic string to the Raspberry Pi UART and attempts to read and output the response. The Rx and Tx pins on the Raspberry Pi are connected with a jumper so whatever is sent should be immediately received.
Despite the program outputting that it successfully sent and received 5 characters for the chosen string ('Hello'), trying to print the contents of the buffer just produces one or two garbage characters.
The program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
int main(int argc, char* argv[]) {
struct termios serial;
char* str = "Hello";
char buffer[10];
if (argc == 1) {
printf("Usage: %s [device]\n\n", argv[0]);
return -1;
}
printf("Opening %s\n", argv[1]);
int fd = open(argv[1], O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1) {
perror(argv[1]);
return -1;
}
if (tcgetattr(fd, &serial) < 0) {
perror("Getting configuration");
return -1;
}
// Set up Serial Configuration
serial.c_iflag = 0;
serial.c_oflag = 0;
serial.c_lflag = 0;
serial.c_cflag = 0;
serial.c_cc[VMIN] = 0;
serial.c_cc[VTIME] = 0;
serial.c_cflag = B115200 | CS8 | CREAD;
tcsetattr(fd, TCSANOW, &serial); // Apply configuration
// Attempt to send and receive
printf("Sending: %s\n", str);
int wcount = write(fd, &str, strlen(str));
if (wcount < 0) {
perror("Write");
return -1;
}
else {
printf("Sent %d characters\n", wcount);
}
int rcount = read(fd, &buffer, sizeof(buffer));
if (rcount < 0) {
perror("Read");
return -1;
}
else {
printf("Received %d characters\n", rcount);
}
buffer[rcount] = '\0';
printf("Received: %s\n", buffer);
close(fd);
}
Outputs:
Opening /dev/ttyAMA0
Sending: Hello
Sent 5 characters
Received 5 characters
Received: [garbage]
I can't see any major problem with the code myself, but I might be wrong. I can successfully send and receive characters using PuTTY connected with the same settings, so it can't really be a hardware problem. Although I haven't tried it in PuTTY, trying to connect with anything less than 115200 baud with this program will result in nothing being received.
Where am I going wrong?
int wcount = write(fd, &str, strlen(str));
int rcount = read(fd, &buffer, sizeof(buffer));
In these lines, buffer/str are already pointers. You are passing a pointer to a pointer.
The lines should be:
int wcount = write(fd, str, strlen(str));
int rcount = read(fd, buffer, sizeof(buffer));
I want send some string to PC via serial bus. In cute com its displaying the string along with some chars are missing and at the starting and end of the string its appending some hex numbers. Why this problem occurring I don't know please help in this issue. My code is here.
#include <avr/io.h>
#include <string.h>
#include <avr/interrupt.h>
#define F_CPU 16000000UL
#include <util/delay.h>
#define USART_BAUDRATE 9600 // Baud Rate value
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
void usart_init() {
//Enable communication in duplex mode
UCSR1A = (1 << U2X1);
UCSR1B |= (1 << RXEN1) | (1 << TXEN1); // Turn on the transmission and reception circuitry
UCSR1C &= ~(1 << UMSEL1);
UCSR1C |= (1<<USBS1) | (1 << UCSZ10) | (1 << UCSZ11);
UBRR1L = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register
UBRR1H = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value..
}
void serial_write(unsigned char data) {
while(!(UCSR1A & (1<<UDRE1)))
;
UDR1 = data;
_delay_ms(10);
}
void transmitString(unsigned char *str) {
int i;
for(i=0;i<strlen(str);i++) {
serial_write(str[i]);
_delay_ms(1);
}
}
int main() {
cli();
usart_init();
unsigned char buffer[20];
strcpy(buffer, "Walk Alone");
while(1) {
transmitString(buffer);
//_delay_ms(250);
}
return 0;
}
Firstly, this question belongs in http://electronics.stackexchange.com
To answer your question, functions strcpy() and strlen() expect a char * and not unsigned char * check here