Atmega328 Analog-to-Digital Converter - arduino

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

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

serial output anomaly in atmega2560

I am facing a problem with atmega2560 serial outport port. When I connect AVRISPmkII programmer to atmega2560, all serial port gives output data at specified baud rate but when I disconnect programmer, there is no output but 1 second led blinks. I don't think that this is the code proble!m. I have not tried it with other programmer as that is all I have. The code is very simple anyway - blink led at 1 second and give output through RS232 port.
Voltage at reset pin is 5V and at sck is about 1.19V whether or not programmer is connected.
What is the problem here ?
The figure shows ISP and serial port circuits.
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <string.h>
void USART0_init(void) /*************** USART 0 ***********************/
{
UCSR0A = 0x00;
UCSR0B = 0b00011000;
UCSR0C = 0b00000110;
UBRR0H = 0x00;
UBRR0L = 103; //baud rate: 9600, right - rx, tx, gnd - left
}
void USART0_putc(char data)
{
while(!(UCSR0A&0x20));
UDR0=data;
}
void USART0_puts(char* str){
while(*str) {USART0_putc(*str++);}
}
void USART1_init(void) /*************** USART 1 ***********************/
{
UCSR1A = 0x00;
UCSR1B = 0b10011000;
UCSR1C = 0b00000110;
UBRR1H = 0x00;
UBRR1L = 103; //baudrate: 9600
}
void USART1_putc(char data)
{
while(!(UCSR1A&0x20));
UDR1=data;
}
void USART1_puts(char* str){
while(*str) {USART1_putc(*str++);}
}
char t = 0;
char rx_buf1[50];
ISR(USART1_RX_vect)
{
cli();
t = UDR1;
rx_buf1[cnt1++] = t;
if (t == 0x0a){ // detect EOL \n FOR NOW
rx_buf1[cnt1] = '\0';
sprintf(out_buf1, "\r\nS1, ");
strcat(out_buf1, (const char*)rx_buf1);
sprintf(out_buf1, ", /");
USART0_puts(out_buf1);
cnt1 = 0;
rx_complete1 = 1;
}
if (cnt1 >= 50){
cnt1 = 0;
}
sei();
}
void timer_init(void)
{
cli();
TCCR1B = (1<<WGM12); //CTC mode
OCR1A = 1561; //100 ms
TIMSK1 |= (1<<OCIE1A);
TCCR1B |= (1<<CS12)|(0<<CS11)|(1<<CS10);
}
void dev_init(void)
{
DDRA = 0x0F;
PORTA = 0x00;
timer_init();
stdout = &uart0_str;
stderr = &uart1_str;
USART0_init();
USART1_init();
sei();
}
int main(void)
{
dev_init();
while(1)
{
process();
}
return 0;
}
volatile unsigned char tick_100ms;
char out_buf[100];
float speed = 4.3;
void process(void){
static unsigned char lc=1;
static uint8_t tick_cnt = 0;
if (tick_100ms){
tick_100ms = 0;
tick_cnt++;
if (tick_cnt == 10){
tick_cnt = 0;
PORTA = ~lc; /* this code is for blinking 4 LEDS */
lc = lc*2; /* very 1 seconds alternately*/
if (lc >8) lc = 1;
sprintf(out_buf, "S1, speed: %05.2f/\r\n", (double)speed);
USART0_puts(out_buf);
USART1_puts(out_buf);
}
}
}
I gave posted my code below.
The uart 1 interrupt code is not needed because there is no incoming data. Disabling them made no difference.

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

Read of Atmega8 16-bit counter always returns 8-bit value

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.

Serial communication in Atmega128

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

Resources