Hallo Leute,
ich nutze einen Ardunino Nano (ATmega328p) und hänge leider fest.
Ich möchte, wenn etwas am Controller ankommt, das ein Interrupt auslöst. Im besten Fall soll das angekommene Byte gespeichert werden um weiter verwendet werden zu können.
Mit Serial.read hatte ich es zuerst umgesetzt jedoch kam es vor, das ich mehrmach ein Byte senden musste damit der Controller die Änderung erfasst.
Das ankommende Byte soll dazu dienen, zwischen den analog Pins zu switchen.
Ich habe im Datasheet und im Internet schon einiges gefunden jedoch ohne mein Problem zu lösen. Ich habe mein Programm mal hinzugefügt und ein Testprogramm, welches ich im Internet gefunden habe. In beiden Fällen löst der Interrupt nicht aus.
Vielen Dank vorweg.
Das ist mein Programm
#include <avr/sleep.h>
#include <avr/interrupt.h>
#include <avr/io.h>
int analogVal;
int statusU1;
int statusU2;
volatile char serialEing = 0;
unsigned long UVal1[16];
unsigned long UVal2[16];
int summe1;
int summe2;
float converted;
long internalVCC;
float ZeroVoltageVCC;
float sensedVoltage;
float difference;
int sensitivity;
volatile int flag1 = 0;
void setup() {
ADMUX = bit (REFS0);
ADCSRA |= bit (ADEN) | bit (ADIF) | bit (ADIE) | bit (ADPS0) | bit (ADPS1) | bit (ADPS2);
UCSR0B |= (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0); // UART RX, TX und RX Interrupt einschalten
UCSR0C |= (1 << UCSZ01) | (1 << UCSZ00) ; // Asynchron 8N1
UBRR0H = 0;
UBRR0L = 103; //Baud Rate 9600
sei();
}
ISR(ADC_vect) {
}
ISR(USART0_RXC_vect) //Habe es auch mit ISR(USART0_RX_vect) probiert
{
flag1 = 1;
serialEing = UDR0;
}
void loop() {
Serial.println(flag1);
if ( serialEing == '1' ) {
statusU1 = 1;
statusU2 = 0;
wandlung();
}
if ( serialEing == '2' ) {
statusU1 = 0;
statusU2 = 1;
wandlung();
}
if (statusU1 == 1) {
wandlung();
}
if (statusU2 == 1) {
wandlung();
}
}
void wandlung() {
unsigned int i;
summe1 = 0;
summe2 = 0;
for (i = 0; i < 16; i++) {
if (statusU1 == 1) {
ADMUX = ADMUX & 0xF0;
ADMUX |= 0x00;
delay(1);
sleep();
UVal1[i] = ADCL | (ADCH << 8);
summe1 += UVal1[i];
}
if (statusU2 == 1) {
ADMUX = ADMUX & 0xF0;
ADMUX |= bit (MUX0);//0x01;
delay(1);
sleep();
UVal2[i] = ADCL | (ADCH << 8);
summe2 += UVal2[i];
}
if (i == 15) {
if (statusU1 == 1) {
conversion(summe1);
Serial.println(converted);
delay(7);
}
if (statusU2 == 1) {
conversion(summe2);
Serial.println(converted);
delay(7);
}
}
}
}
void sleep() {
noInterrupts ();
set_sleep_mode (SLEEP_MODE_ADC);
sleep_enable();
// start the conversion
ADCSRA |= bit (ADSC);
interrupts ();
sleep_cpu ();
sleep_disable ();
}
double conversion(int Val) {
if ( x == 0) sensitivity = 219.8039216;
else sensitivity = 40;
internalVCC = readInternalVcc(); //Interne Spannung = ext. Spannung
ZeroVoltageVCC = internalVCC * 0.001 / 2 ; //Sensor 0 V definiert bei halber Versorgungsspannung
sensedVoltage = (Val * internalVCC * 0.001) / 16368; //Interne Spg. auf Volt umrechnen und Digitalwert mit dem Verhältnis multiplizieren
difference = sensedVoltage - ZeroVoltageVCC; // Differenz zwischen Eingangswert und Nullpunkt
converted = difference * sensitivity; // Ausgabe der Eingangsspannung in V
return converted;
}
long readInternalVcc() {
long result;
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); //Die 1,1V werden als Referenz zu AVcc genutzt
delay(2); // Warte auf Vref
ADCSRA |= _BV(ADSC); // Konvertiere
while (bit_is_set(ADCSRA, ADSC));
result = ADCL;
result |= ADCH << 8;
// result = 1126400L / result; // AVcc in MV Vin = 1,1V
result = 1127424L / result; //Vin = 1,101V
return result;
}
Im Internet bin ich auf dieses Beispiel gestoßen jedoch tut sich bei mir nichts
#include <avr/interrupt.h>
#include <avr/io.h>
volatile byte dummy = 0;
void uart_init(void)
{
UCSR0B |= (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0); // UART RX, TX und RX Interrupt einschalten
UCSR0C |= (1<<UCSZ01) | (1<<UCSZ00) ; // Asynchron 8N1
UBRR0H = 0;
UBRR0L = 103; //Baud Rate 9600
}
ISR(USART_RXC_VECT)
{
unsigned char b;
b=UDR0;
dummy = 1;
}
void setup()
{
Serial.begin(9600);
uart_init();
sei();
}
void loop()
{
if (dummy == 1) {Serial.print("UART");}
delay(20);
}