Serial communication in Atmega128 - serial-port

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

Related

XIAO BLE with MAX30100 and BLE

When I run MAX30100 by itself on SEEED XIAO BLE SENSE module everything works fine. But when I add BLE into code, MAX30100 stops getting beats when BLE begins. I am guessing this is to do with pox.update() not updating in time. If someone has any idea what I can do please share. Thank you.
My code is here:
//MAX30100 BPM + SPO2 header
#include <MAX30100_PulseOximeter.h>
//BLE header
#include <Arduino.h>
#include <ArduinoBLE.h>
//Communication header
#include <Wire.h>
//MAX30100
PulseOximeter pox;
uint8_t hearty = 0;
uint8_t oxy = 0;
//MAX timer
unsigned long max_prev_millis = 0;
//BLE timer
unsigned long ble_prev_millis = 0;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
if (!pox.begin()) Serial.println(F("MAX30100 error"));
else Serial.println(F("MAX30100 OK!"));
pox.setOnBeatDetectedCallback(onBeatDetected);
// setting the registers for the bluetooth transmit power
uint32_t *TXPOWER = (uint32_t *)0x4000150C;
*TXPOWER &= 0x0;
*TXPOWER |= 0x08;
uint32_t *MODE = (uint32_t *)0x40001510;
*MODE &= 0x0;
*MODE |= 0x05;
BLE.setLocalName("IT'S ME, BLE");
}
void loop() {
// put your main code here, to run repeatedly:
pox.update();
//Heart rate reading every 1 second
if (millis() - max_prev_millis >= 1000){
readMax30100();
}
//Bluetooth upload every 15 seconds
if (millis() - ble_prev_millis >= 15 * 1000) {
BLEUpload();
}
}
void readMax30100(){
hearty = pox.getHeartRate();
oxy = pox.getSpO2();
Serial.print(F("Heart rate:"));
Serial.print(hearty);
Serial.print(F("bpm / SpO2:"));
Serial.print(oxy);
Serial.println(F("%"));
max_prev_millis = millis();
}
void BLEUpload(){
BLE.begin();
BLE.stopAdvertise();
BLEAdvertisingData advData;
advData.setFlags(BLEFlagsBREDRNotSupported | BLEFlagsGeneralDiscoverable);
unsigned char send_data[2]
{
(unsigned char) (hearty),
(unsigned char) (oxy)
};
advData.setAdvertisedServiceData(0x2ACA, send_data, sizeof(send_data));
BLE.setAdvertisingData(advData);
BLE.advertise();
BLE.end();
ble_prev_millis = millis();
}
void onBeatDetected(){
Serial.println(F("Beat!"));
}

How to send unprocessed output over linux serial port?

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);
}
}

Atmega328 Analog-to-Digital Converter

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);
}
}

How to receive caller number from Arduino SIM800C GSM shield?

I'm trying to code a GSM caller number receiver. When I (as the phone answerer) answer the phone it should print out the caller number.
I have trouble finding the right AT command for receiving the caller number. I tried AT+CLIP=1\r and on the loop +CLIP, but with no success.
Here is my code:
#include <GSMSim.h>
#include <SoftwareSerial.h>
#define RX 7
#define TX 8
#define RESET 2
#define BAUD 9600
GSMSim gsm;
SoftwareSerial mySerial = SoftwareSerial(RX, TX);
/*
* Also you can this types:
* GSMSim gsm(RX, TX);
* GSMSim gsm(RX, TX, RESET);
* GSMSim gsm(RX, TX, RESET, LED_PIN, LED_FLAG);
*/
void setup() {
Serial.begin(9600);
Serial.println("GSMSim Library - Call Example");
Serial.println("");
delay(1000);
gsm.start(); // baud default 9600
mySerial.read();
mySerial.print("AT+CLIP=1\r");
}
void loop() {
Serial.println(gsm.callStatus());
gsm.callAnswer();
Serial.println("Number:");
Serial.println(mySerial.print("+CLIP"));
delay(1000);
}
I got It working by using mySerial, (ATDevice) read function and using command function to accualy print it out, anyone who looks up how it work, here Is my code
#include <GSMSim.h>
#include <SoftwareSerial.h>
#include <string.h>
#define RX 7
#define TX 8
#define RESET 2
#define BAUD 9600
char outArray;
char inData[20];
char inChar=-1;
byte index = 0;
char * pch;
char* substring(char*, int, int);
GSMSim gsm;
SoftwareSerial ATDevice = SoftwareSerial(RX, TX);
/*
* Also you can this types:
* GSMSim gsm(RX, TX);
* GSMSim gsm(RX, TX, RESET);
* GSMSim gsm(RX, TX, RESET, LED_PIN, LED_FLAG);
*/
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
ATDevice.begin(9600);
command("AT+CLIP=1",1000);
delay(1000);
}
String command(const char *toSend, unsigned long milliseconds) {
String result;
ATDevice.println(toSend);
unsigned long startTime = millis();
Serial.print("Return: ");
while (millis() - startTime < milliseconds) {
if (ATDevice.available()) {
char c = ATDevice.read();
result += c; // append to the result string
}
}
Serial.println(); // new line after timeout.
return result;
}
void loop() {
command("+CLIP",1000);
delay(2000);
}

Using arduino Serial object at the same time using directly USART register in the same code?

When I compile this code ;
#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/delay.h>
volatile int state_Led = LOW;
int SerialVal_;
void setup()
{
#define USART_BAUDRATE 9600
#define UBRR_VALUE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
UBRR0H = (uint8_t)(UBRR_VALUE>>8);
UBRR0L = (uint8_t)UBRR_VALUE;
UCSR0B |= (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0); // Turn on the transmission, reception, and Receive interrupt
UCSR0C |= (1<<UCSZ01)|(1<<UCSZ00);
interrupts();
}
int c = 0;
int b;
void loop()
{
if(Serial.available() > 0); // Error Line
}
ISR(USART_RX_vect)
{
cli();
while(!(UCSR0A&(1<<RXC0))){};
c= UDR0; // clear the USART interrupt
UDR0 = c + 0x0A;
sei();
}
I get the error of "C:\Program Files\Arduino\hardware\arduino\cores\arduino/HardwareSerial.cpp:115: multiple definition of `__vector_18'"
To sum up, if I use interrupt with USART interrupt vector I can't use simple Serial.xxx class methods for a reason that I don't know. I know lots of people are having the same problem. If someone berings the solution, that would be great. Thanks in advance

Resources