ESP32 Task watchdog got triggered using ESP IDF - esp32

We need to read ADC module over I2C continuously 20 times to get stable values of ADC.
We have created a task for it, but code stop working in couple of min showing below error.
E (1925655) task_wdt: Task watchdog got triggered. The following tasks did not r
eset the watchdog in time:
E (1925655) task_wdt: - IDLE (CPU 0)
E (1925655) task_wdt: Tasks currently running:
E (1925655) task_wdt: CPU 0: esp_timer
We are not getting any exact solution for our error. Below is the task espfor reference.
void Hal_Read_Average_Voltage_For_TLA202x (void *pvParameters)
{
float read_value = 0, bigger_value = 0, voltage = 0;
while(1)
{
Hal_TLA2024_Re_Initialize ();
{
for (int count1 = 0; count1 < 20; count1++)
{
voltage = readVoltage (); //Performs I2C register read
if (voltage > bigger_value)
{
bigger_value = voltage;
}
vTaskDelay (1);
}
read_value += bigger_value;
bigger_value = 0;
}
ESP_LOGE(TAG, "ADC Highest Value = %f\n", (read_value));
read_value = 0;
bigger_value = 0;
voltage = 0;
vTaskDelay (300 / portTICK_PERIOD_MS);
}
}
float readVoltage (void)
{
int16_t raw_voltage;
uint16_t u16TempRead = 0;
uint8_t u8TempRead[2] = { 0, 0 };
uint8_t u8TempAddress = TLA202x_DATA_REG;
Hal_I2C_Read_Register (TLA202x_I2CADDR_DEFAULT, u8TempAddress, u8TempRead, 2, 1);
u16TempRead = u8TempRead[1] | (u8TempRead[0] << 8);
raw_voltage = u16TempRead;
// this will read the sign bit correctly, but shifting will move the bit out
// of the msbit
if (raw_voltage & 0x8000)
{
raw_voltage >>= 4;
raw_voltage |= 0x8000;
}
else
{
raw_voltage >>= 4;
}
switch (current_range)
{
case TLA202x_RANGE_6_144_V:
voltage = raw_voltage *= 3;
break;
case TLA202x_RANGE_4_096_V:
voltage = raw_voltage *= 2;
break;
case TLA202x_RANGE_2_048_V:
voltage = raw_voltage *= 1;
break;
case TLA202x_RANGE_1_024_V:
voltage = raw_voltage *= 0.5;
break;
case TLA202x_RANGE_0_512_V:
voltage = raw_voltage *= 0.25;
break;
case TLA202x_RANGE_0_256_V:
voltage = raw_voltage *= 0.125;
break;
}
voltage /= 1000.0; // mV =>V
return voltage;
}
void Hal_I2C_Read_Register (uint32_t slave_address, int register_address, uint8_t read_data_buffer[],
uint8_t read_buffer_length, uint8_t write_buffer_length)
{
i2c_cmd_handle_t cmd;
DATA_READ: cmd = i2c_cmd_link_create ();
i2c_master_start (cmd);
if (register_address != -1)
{
i2c_master_write_byte (cmd, slave_address << 1 | I2C_MASTER_WRITE,
ACK_CHECK_EN);
i2c_master_write_byte (cmd, register_address, ACK_CHECK_EN);
i2c_master_start (cmd);
}
i2c_master_write_byte (cmd, slave_address << 1 | I2C_MASTER_READ,
ACK_CHECK_EN);
if (read_buffer_length > 1)
{
i2c_master_read (cmd, read_data_buffer, read_buffer_length - 1, ACK_VAL);
}
i2c_master_read_byte (cmd, read_data_buffer + read_buffer_length - 1,
NACK_VAL);
i2c_master_stop (cmd);
esp_err_t ret = i2c_master_cmd_begin (I2C_NUM_0, cmd, 1000/ portTICK_RATE_MS);
i2c_cmd_link_delete (cmd);
if (ret == ESP_OK)
{
}
else if (ret == ESP_ERR_TIMEOUT)
{
// ESP_LOGW(TAG, "Bus is busy");
}
else
{
ESP_LOGW(TAG, "Read failed %d", ret);
goto DATA_READ;
}
}
We are having 2 more thread running on same priority.
If we remove the for loop in the above thread then there is no WDT error.

Updated ESP-IDF version to 4.4 and it solved this issue.

Related

ESP8266 Client connexion via a webscoket (no library, only AT commands)

I am working on websocket implementation on client side using AT commands.
I've taken this as a baseline and read this.
Hardware : ESP8266+arduino uno.
Code :
String cmd = "AT+CIPSTART=\"TCP\",\""; cmd += SERVER_IP; cmd += "\",81"; //Start a TCP connection. to server SERVER_IP on port 81
if (!sendCommand(cmd, "OK", CONTINUE))
return;
delay(2000);
if (!sendCommand("AT+CIPSTATUS", "OK", CONTINUE))// Check for TCP Connection status.
return;
cmd = "GET 192.168.43.228:81 HTTP/1.1\r\n";
cmd += "Host: 192.168.43.228:81\r\n";
cmd += "Upgrade: websocket\r\n";
cmd += "Connection: Upgrade\r\n\r\n";
if (!sendCommand("AT+CIPSEND=" + String(cmd.length()), ">", CONTINUE)) {
sendCommand("AT+CIPCLOSE", "", CONTINUE);
Serial.println("Connection timeout.");
return;
}
sendCommand(cmd, "OK", CONTINUE);// Send data to server.
delay(1000);
readResponseData("");
Log on arduino side :
ESP8266 Demo
AT+RST
OK
bBֆ#⸮Sc⸮⸮⸮ȤS⸮⸮⸮ɥ⸮⸮⸮⸮H⸮
[System Ready
, Vendo:⸮ݹ⸮⸮⸮ɹcom]
AT+GMR
0018000902
OK
AT+CWMODE?
+CWMODE:1
OK
AT+CWMODE=1
no change
AT+CWMODE=1
no change
AT+CIPMUX=0
OK
AT+CWJAP="AndroidAP","xxxx"
OK
Connected to WiFi.
AT+CWJAP="AndroidAP","xxxxx"
OK
AT+CWSAP=?
no this fun
AT+CIFSR
192.168.43.29
OK
Module is ready.
AT+CIPSTART="TCP","192.168.43.228",81
OK
Linked
AT+CIPSTATUS
STATUS:3
+CIPSTATUS:0,"TCP","192.168.43.228",81,0
OK
AT+CIPSEND=100
>
GET 192.168.43.228:81 HTTP/1.1
Host: 192.168.43.228:81
Upgradewrong syntax
ERROR
SEND OK
OK
Unlink
Server side :
WiFi connected
IP address:
192.168.43.228
Server available at ws://192.168.43.228:81
Accepted new web sockets client at index 0
--
...and nothing else from the server which is supposed sending a message as soon as it accepts the websocket.
Please give me some insight :)
I found one solution.
In fact I was not aware about all the details of RFC4566
After a successful handshake, you need to be inline with the frame requirement. It is not just as raw text :)
For a limited use case (i.e. length<125) here is the overview of the solution:
char str[] = "Hello";
char buf[125];
bool toMask = true;
uint8_t extra = toMask ? 6 : 2;
buildFrame(str, buf, WS_OPCODE_TEXT, toMask);
ESP8266SendData(0, buf, str.length() + extra);
I've tested this to get:
void buildFrame(char *str, uint8_t *ret, uint8_t opcode, bool maskon) {
uint8_t mask[4];
int size = strlen(str);
// Opcode; final fragment
ret[0] = opcode | WS_FIN;
ret[1] = (uint8_t) (size) | (maskon == true ? WS_MASK : 0);
if (maskon) {
mask[0] = random(0, 256);
mask[1] = random(0, 256);
mask[2] = random(0, 256);
mask[3] = random(0, 256);
for (int i = 2; i < 4 + 2; ++i) {
ret[i] = mask[i - 2];
}
for (int i = 6; i < size + 6; i++) {
ret[i] = str[i - 6] ^ mask[(i - 6) % 4];
}
}
else {
for (int i = 2; i < size + 2; ++i) {
ret[i] = (uint8_t) str[i - 2];
}
}
}
For frame decoding :
uint8_t extractPayload(String buffer, String& payload) {
// here only payloads whose size < 125
bool FIN = buffer[0] & WS_FIN;
uint8_t opcode = buffer[0] & ~WS_FIN;
bool hasMask = buffer[1] & WS_MASK;
uint8_t len = buffer[1] & ~WS_MASK;
uint8_t mask[4];
if (hasMask) {
mask[0] = buffer[2];
mask[1] = buffer[3];
mask[2] = buffer[4];
mask[3] = buffer[5];
for (int i = 6; i < len + 6; i++) {
payload += (char) (buffer[i] ^ mask[(i - 6) % 4]);
}
}
else {
payload = buffer.substring(2);
}
Serial.print("FIN = "); Serial.println(FIN, HEX);
Serial.print("Opcode = "); Serial.println(opcode, HEX);
Serial.print("Mask = "); Serial.println(hasMask, HEX);
Serial.print("Payload length = "); Serial.println(len, HEX);
return opcode;
}

First led of WS2812B starts to light when the code enters the for loop

I'am working on this project, it should be a light for a carport. There are two ways to turn the light on, via motion sensor or via a switch. The Led strip starts to turn on one led after another. It will stay on for a period of time and then a reversed animation starts and turns all LEDs to black. I'am using a for loop for this animation (it's the same one FastLed uses in the first light example). The error is only when the motion sensor is activate and while the for loop is running. I'am sorry for the bad integer names, could be confusing.
Thanks a lot!
Here is the Code:
(If you can't understand German,
- Bewegungsmelder = Motion sensor
- Schalter = Switch
// für die Leds
#define NUMfront_LEDS 150 //150 Leds
#define NUMinner_LEDS 35 //35 Leds
#define rightPIN 6 //Pin 6
#define leftPIN 5
#define innerrightPIN 8
#define innerleftPIN 7
#define CLOCK_PIN 13
// für die Schalter
#define schalter 2 //Pin 2
#define Bewegungsmelder 4 //Pin 4
int schalterval = 0;
int Bewegungsval = 0;
long Time = 0;
long Wait = 900000;
int On = 0;
CRGB leftLeds[NUMfront_LEDS];
CRGB rightLeds[NUMfront_LEDS];
CRGB innerleftLeds[NUMinner_LEDS];
CRGB innerrightLeds[NUMinner_LEDS];
void setup() {
// sanity check delay - allows reprogramming if accidently blowing power w/leds
Serial.begin(115200);
delay(2000);
FastLED.addLeds<WS2812B, rightPIN, RGB>(rightLeds, NUMfront_LEDS); // GRB ordering is typical
FastLED.addLeds<WS2812B, leftPIN, RGB>(leftLeds, NUMfront_LEDS);
FastLED.addLeds<WS2812B, innerrightPIN, RGB>(innerrightLeds, NUMinner_LEDS);
FastLED.addLeds<WS2812B, innerleftPIN, RGB>(innerleftLeds, NUMinner_LEDS);
Time = millis();
}
void loop() {
Serial.println("----------------------------------------------");
Serial.print(Wait);
Serial.print("----");
Serial.print(millis());
Bewegungsval = digitalRead(Bewegungsmelder);
schalterval = digitalRead(schalter);
Serial.println(Bewegungsval);
Serial.println(schalterval);
Serial.println("Space");
Schalter:
if (digitalRead(schalter) == 1) {
On = 0;
for (int blackLed = NUMfront_LEDS; blackLed > -1; blackLed = blackLed - 1) {
leftLeds[blackLed] = CRGB::White;
rightLeds[blackLed] = CRGB::White;
delay(19);
FastLED.show();
}
// Carport innen
fill_solid( innerrightLeds, NUMinner_LEDS, CRGB::White);
fill_solid( innerleftLeds, NUMinner_LEDS, CRGB::White);
//Leds aus
//Carport aussen
while (digitalRead(schalter) == 1) {
}
for (int whiteLed = 0; whiteLed < NUMfront_LEDS; whiteLed = whiteLed + 1) {
leftLeds[whiteLed] = CRGB::Black;
rightLeds[whiteLed] = CRGB::Black;
delay(19);
FastLED.show();
}
// Carport innen
fill_solid( innerrightLeds, NUMinner_LEDS, CRGB::Black);
fill_solid( innerleftLeds, NUMinner_LEDS, CRGB::Black);
FastLED.show();
}
else if (Bewegungsval == 1) {
//Carport aussen
if (On == 1) {
goto Skip;
}
for (int blackLed = NUMfront_LEDS; blackLed > -1; blackLed = blackLed - 1) {
leftLeds[blackLed] = CRGB::White;
rightLeds[blackLed] = CRGB::White;
delay(19);
FastLED.show();
}
// Carport innen
fill_solid( innerrightLeds, NUMinner_LEDS, CRGB::White);
fill_solid( innerleftLeds, NUMinner_LEDS, CRGB::White);
FastLED.show();
//Leds aus
On = 1;
Skip:
Time = millis();
Wait = Time + 10000; // + 5min. 300000
Bewegungsval = digitalRead(Bewegungsmelder);
goto Schalter;
}
Time = millis();
if (Time >= Wait) {
On = 0;
for (int whiteLed = 0; whiteLed < NUMfront_LEDS; whiteLed = whiteLed + 1) {
leftLeds[whiteLed] = CRGB::Black;
rightLeds[whiteLed] = CRGB::Black;
delay(19);
FastLED.show();
}
// Carport innen
fill_solid( innerrightLeds, NUMinner_LEDS, CRGB::Black);
fill_solid( innerleftLeds, NUMinner_LEDS, CRGB::Black);
}
}```
Although fluent in German the program structure is alittle chaotic. Since we are in C++
you should not use goto
Since to my understanding the light routines for switch and IR are the same this code should only exist once
Your routine for measuring time is not rollover safe see blinkwithoutdelay example how todo
So clean the code up by using the following structure:
unsigned long startTime = 0;
unsigned long myTimer = 10000;// 10 sec
bool lightIsOn = false;
setup(){....}
loop(){
....
// We check wether switch or IR are triggerd AND we are not already in a light sequence
if ((digitalRead(schalter) == 1 || Bewegungsval == 1) && lightIsOn == false) {
lightIsOn = true; // change state so we know that a light sequence is running
startTime = millis(); // reset the timer
}
// this part runs as long lighIsOn == true and time is not up
if(millis() - startTime <= myTimer && lighIsOn == true){
// Carport aussen
your light sequence .....
}
// Here we run the time is up sequence
if(millis() - startTime > myTimer && lighIsOn == true) { // rollover safe
light sequence for time is up
........
lightIsOn = false; // change state so we know that a light sequence is over
}
}
This technique is called finite state machine there is no "jumping around" via goto.
If you need more states you just expand the sequence - there is no else because eg in the last two combined if statements we check for lightIsON == true ==> else would mean lightIsON == false in the second which makes no sense here as we only differentiate these to states by time.
Please never use goto in object oriented programming it makes your code unreadable and untraceable. Rewrite the program and if there are "new" problems edit here or open a new question

Unable to execute interrupt function

Using Mplab ide 5.10 and xc8 compiler for the pic18f4550 I am unable to get the code to get into the interrupt function the goal is to get J to count up in the background until something trigger it to output a value in the lcd. Currently only the lcd display the first message and using ICD 3 the value of J does not change and does not look like the program runs the interrupt function at all
#define _XTAL_FREQ 48000000
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include "lcd.h"
unsigned char j, output = 0, i, outchar;
char buffer[2] = " ";
char Message[ ] = "Hands Position ";
void interrupt timer0_isr();
void lcd_write_cmd(unsigned char cmd);
void lcd_write_data(unsigned char data);
void lcd_strobe(void); // Generate the E pulse
void lcd_init(void);
void interrupt timer0_ISR() // Timer0 Interrupt Service Routine (ISR)
{
if (INTCONbits.TMR0IF) // TMR0IF:- Timer0 Overflow Interrupt Flag Bit
{
TMR0H = 0x48; // Timer0 start value = 0x48E5 for 1 second
TMR0L = 0xE5;
PORTCbits.RC1 = !PORTCbits.RC1; /* external timing check - toggle every 1ms */
if (j <= 4) { //limit up to 7
j++; // Increase count by 1
PORTB = j; // Output to Demultiplexer
} else {
j = 0; // Reset count aftwr it hit 7
PORTB = j; // Output to Demultiplexer
}
INTCONbits.TMR0IF = 0; // Reset TMR0IF at interrupt end
}
}
void main(void) // Main Function
{
ADCON1 = 0x0F;
CMCON = 0x07;
RCONbits.IPEN = 1; // Bit7 Interrupt Priority Enable Bit
INTCONbits.GIEH = 1; // Bit7 Global Interrupt Enable bit
INTCONbits.GIEL = 0; /* turn on low & high interrupts */
T0CONbits.TMR0ON = 1; // Turn on timer
T0CON = 0b00000111; // bit7:0 Stop Timer0
// bit6:0 Timer0 as 16 bit timer
// bit5:0 Clock source is internal
// bit4:0 Increment on lo to hi transition on TOCKI pin
// bit3:0 Prescaler output is assigned to Timer0
// bit2-bit0:111 1:256 prescaler
INTCON2 = 0b10000100; // bit7 :PORTB Pull-Up Enable bit
// 1 All PORTB pull-ups are disabled
// bit2 :TMR0 Overflow Int Priority Bit
// 1 High Priority
TMR0H = 0x48; // Initialising TMR0H
TMR0L = 0xE5; // Initialising TMR0L for 1 second interrupt
INTCONbits.TMR0IE = 1; // bit5 TMR0 Overflow Int Enable bit
INTCONbits.TMR0IF = 0; // bit2 TMR0 Overflow Int Flag bit
// 0 TMR0 register did not overflow
TRISC = 0; /* all outputs */
TRISAbits.TRISA5 = 1; // RA5 is the check for signal from input Multiplexer.
TRISAbits.TRISA0 = 0; // RA0, RA1 & RA2 output to arduino
TRISAbits.TRISA1 = 0;
TRISAbits.TRISA2 = 0;
TRISD = 0x00; // PortD connects to Demultiplexer
TRISB = 0;
lcd_init(); // LCD init
lcd_write_cmd(0x80); // Cursor set at line 1 positon 1
for (i = 0; i < 16; i++) {
outchar = Message[i]; // Store Message in outchar
lcd_write_data(outchar); // Display Message
}
__delay_ms(100);
PORTD = 0x00; // Clear PortD
PORTB = 0;
j = 0; // Start count from 0
while (1) // Main Process
{
if (PORTAbits.RA5 == 1) { // If RA3 detect a signal
switch (j) { // Switch case to determine hand position & output to RA0, RA1 & RA2 to transmit to arduino
case(0):
output = 10;
PORTAbits.RA0 = 0;
PORTAbits.RA1 = 0;
PORTAbits.RA2 = 0;
break;
case(1):
output = 20;
PORTAbits.RA0 = 1;
PORTAbits.RA1 = 0;
PORTAbits.RA2 = 0;
break;
case(2):
output = 30;
PORTAbits.RA0 = 0;
PORTAbits.RA1 = 1;
PORTAbits.RA2 = 0;
break;
case(3):
output = 40;
PORTAbits.RA0 = 1;
PORTAbits.RA1 = 1;
PORTAbits.RA2 = 0;
break;
case(4):
output = 50;
PORTAbits.RA0 = 0;
PORTAbits.RA1 = 0;
PORTAbits.RA2 = 1;
break;
}
lcd_write_cmd(0xC0); // Cursor set at line 2 positon 1
sprintf(buffer, "%d", output); // Convert numbers to character
for (i = 0; i < 2; i++)
lcd_write_data(buffer[i]); // Display Hand Position
}
}
}

IR Receiver RC5 with Pic12F1572

I am building an IR Receiver with PIC12F1572 with receiver module TSOP2438
My objective of this project is to receive a data by remote control and send it to PC via UART..
I have done the code and I am testing it I can send the normal value through the UART but Somewhereis wrong so that I can not receive the hex values regarding the commands of remote control
Can anyone see my code and tell where I am goping wrong?
Here is my code
void main(void)
{
OSCILLATOR_Initialize(); // 0x78 for Fosc = 16Mhz
PIN_MANAGER_Initialize(); //All port pins Digital and input
EUSART_Initialize();
INTCONbits.IOCIF = 0; // Interrupt on-change Flag
INTCONbits.PEIE = 1; //SEt Peripheral Interrupt
INTCONbits.GIE = 1; //Set Global Interrupt
//while(!OSCSTATbits.HFIOFS); //Check here or wait here to OSC stable/ 0.5% accuracy
TRISAbits.TRISA2 = 1; //Configure R1 as input
// uint16_t Input_buffer [20];
EUSART_Write(0x40); // 0x40 = # some flag
while(1)
{
count = 0;
//while((IR_PIN)); //IR_PIN receives an IR signal its output pin goes from logic 1 to logic 0
//which causes the microcontroller to start reading the IR signal using the function. decode()
EUSART_Write(0x41);
//while(IR_PIN);
if(Decode()) //check if RC5 decoding- new data is arrived
{
EUSART_Write(0x42);
toggle_bit = bit_test(IR_Code, 11);
address = (IR_Code >> 6) & 0x1F;
command = IR_Code & 0x3F;
EUSART_Write(toggle_bit);
EUSART_Write(address);
EUSART_Write(command);
EUSART_Write(0x43);
}
}
}
/*----------*/
uint8_t Measure_space()
{
TMR0_Initialize();
while(IR_PIN && (count < 2000))
count = TMR0_ReadTimer(); //Read timer value and store it in count value
if((count > 1999) || (count < 700))
return 0; //0 = If width is out of range
if(count > 1200)
return 1; //1 = If width is long
else
return 2; //2 = If the width is short
}
uint8_t Decode()
{
uint8_t i = 0, check;
mid1:
check = Measure_Pulse();
if(check == 0)
return FALSE;
bit_set(IR_Code, 13 - i);
i++;
if(i > 13)
return TRUE;
if(check == 1)
goto mid0;
else
goto start1;
mid0:
check = Measure_space();
if((check == 0) && (i != 13))
return FALSE;
bit_clear(IR_Code, 13 - i);
i++;
if(i > 13) return TRUE;
if(check == 1)
goto mid1;
else
goto start0;
start1:
check = Measure_space();
if(check != 2)
return FALSE;
goto mid1;
start0:
check = Measure_Pulse();
if(check != 2)
return FALSE;
goto mid0;
}
I think this is because you are sending Hex value without converting to string. If you want to print this Hex value in PC terminal, First you have to convert it to ASCII string.

AVR Atmega8 ADC input causes Crash

i am trying to Read an Voltage Level via a ADC0 of my ATmega8, because of querying a 1 Pin 4x4 Matrix Keypad. The Problem is everytime I apply a Voltage to the ADC higher than GND the Atmega is stopping to do his work. The PWM outputs are still working, but communication via i2c is impossible and the LCD is clear.
My wiring is simple, AREF & AVCC are set to 5V, GND is set to GND and PC0 is my Input. Is there anything I fail to Notice? Thank You for your help.
Here is my Code:
void Initialisierung(void)
{
char text [2];
lcd_init();
cli();
//### TWI
init_twi_slave(SLAVE_ADRESSE); //TWI als Slave mit Adresse slaveadr starten
sei();
lcd_setcursor( 0, 1 );
lcd_string(">Booting...");
lcd_setcursor( 0, 2 );
itoa (SLAVE_ADRESSE,text,16);
lcd_string("I2C Adress=0x");
lcd_string(text);
for (int Index=0; Index<85; ++Index) {
rxbuffer[Index] = 0x20;
}
rxbuffer[81]=0xFF;
rxbuffer[82]=0xFF;
rxbuffer[83]=0xFF;
rxbuffer[84]=0xFF;
}
//update LCD
void lcd_update(void){
for (int o=1;o<=4; o++)
for (int i=1; i<=20; i++){
lcd_setcursor( i-1, o );
lcd_data(rxbuffer[i+((o-1)*20)]);
}
}
An here is the main function:
int main(void)
{
DDRC &= ~(1 << PC0);
PORTC &= ~(1 << PC0);
Initialisierung();
DDRB = (1 << DDB1) | (1 << DDB2);
OCR1A = eeprom_read_word(&brightness); // PWM einstellen,
OCR1B = eeprom_read_word(&contrast);
ICR1 = 1000; // TOP-wert
TCCR1A = (1<<COM1A1) | (1<<COM1B1) | (1<<WGM11); // 2-Kanal "non-inverting"
TCCR1B = (1<<WGM13)|(1<<WGM12) | (1<<CS11);
//Initialize ADC
ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS0);
ADMUX=0x00;
unsigned int adc_value=0; // Variable to hold ADC result
char text[2];
while(1)
{
ADCSRA |= (1<<ADSC); // Start conversion
while (ADCSRA & (1<<ADSC)); // wait for conversion to complete
adc_value = ADCW; //Store ADC value
itoa (adc_value,text,16);
lcd_setcursor( 0,4 );
lcd_string(text);
for (int Index=0; Index<85; ++Index) {
txbuffer[Index] = rxbuffer[Index];
}
uint16_t brightness_i2c=0;
uint16_t contrast_i2c=0;
brightness_i2c=(rxbuffer[81]<<8)|(rxbuffer[82]);
contrast_i2c=(rxbuffer[83]<<8)|(rxbuffer[84]);
if (rxbuffer[0]==1){
lcd_update();
rxbuffer[0]=4;
}else if(brightness_i2c!=eeprom_read_word(&brightness) && brightness_i2c!=0xFFFF){
eeprom_write_word(&brightness,brightness_i2c);
OCR1A = eeprom_read_word(&brightness);
}else if (contrast_i2c!=eeprom_read_word(&contrast) && contrast_i2c!=0xFFFF){
eeprom_write_word(&contrast,contrast_i2c);
OCR1B = eeprom_read_word(&contrast);
}else{
for (uint8_t i=0; i<50; i++) _delay_ms(10);
lcd_setcursor( 19, 4 );
lcd_data(0xFF);
for (uint8_t i=0; i<50; i++) _delay_ms(10);
lcd_setcursor( 19, 4 );
lcd_data(0x20);
}
}
}
I finally got it:
I setup the ADC with interrupts but not freerunning:
ADCSRA =(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADIE)| (1<<ADPS0);
And call the ADC everytime at the end of my While loop:
ADCSRA |= (1<<ADSC);
Here is the Code for the ISR:
ISR(ADC_vect)
{
char text[5];
itoa (ADC,text,16);
lcd_setcursor( 0,4 );
lcd_string(text);
}
Thanks for your time ;)

Resources