mikrocontroller.net

Forum: Compiler & IDEs Problem mit RC5


Autor: Fragender (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich versuche mit folgendem Code RC5 mit einem TSOP1736 zu empfangen, die 
Fernbedienung sendet RC5.

SIGNAL(SIG_INTERRUPT0)
{
 uint8_t foo,i;
 //GICR &= ~(1<<INT0); // Externen Interrupt deaktivieren
 char wert[30] = "interrupt!!!";
 char test[30] = "1";
 send_string(wert);
 for(i=0;i<=14;i++) {
  foo = (PIND && (1<<3));
  if(foo==1) {
  send_string(test);}
  _delay_us(1778);
  foo = 0;
 }

Das Problem ist, ich bekomme immer 15 Einser, egal welche Taste ich 
drücke, eigentlich dürfte ich doch nur soviele Einser bekommen, wie auch 
tatsächlich im Code vorkommen?!
CPU ist ein ATMEGA8, 16Mhz.
Gruss
Fragender

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
SIGNAL(SIG_INTERRUPT0)
{
...
  _delay_us(1778);

HO-ECKER! Sie sind raus!



Beitrag "Fernbedien RC5 Empfänger"

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal davon abgesehen, dass der ganze Ansatz relativ untauglich ist ...

> foo = (PIND && (1<<3));

foo ist hier immer dann 1, wenn irgendein Pin an Port D High ist.

Autor: Fragender (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das hilft mir jetzt leider nicht wirklich weiter.. was ist an dem delay 
falsch? Das sollte doch noch im Bereich des Erlaubten sein oder?
Und nach meinem Verständnis wird wird damit der PIND3 eingelesen.

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>delay falsch?
Ein Warte_Zeit_X hat in einer ISR NICHTS , aber auch GARNICHTS zu 
suchen.
Dort hängt der µC ja sonst fest.

Meiner (persönlichen) Meinung, sind Warteschleifen jeglicher Art  (warte 
auf irgendein Bit/Zeit,..) ein absolutes No-Go. SOwas realisiert man mit 
verschiedenen Task und Schrittketten...

>(PIND && (1<<3)); ... PIND3 eingelesen.

wenn dann so:
foo = (PIND & (1<<3));
// foo = 0     , wenn PD3 low
// foo = (1<<3), wenn PD3 high

Autor: Fragender (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber ich will ja gerade, dass das Programm dort "festhängt", damit der 
RC5 Code gelesen wird und dann kann es ja normal weitergehen, neue 
Interrupts in dieser Zeet sind unerwünscht!

Autor: Fragender (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, habs jetzt nochmal komplett neugestrickt, und zwar interuptbasiert:
SIGNAL(SIG_INTERRUPT0)
{
 TIMSK |= (1<<TOIE0);
 char last_bit = 1;
 char test[3];
 uint8_t i;
 if(TCNT0<139 && bitnummer <= 14 && last_bit == 1) {
  gesamt[bitnummer] = 1;
  last_bit = 1;
  TCNT0 = 0;
  bitnummer++;
  }
 if(TCNT0>139 && TCNT0<194 && bitnummer <= 14 && last_bit == 1) {
  gesamt[bitnummer] = 0;
  last_bit = 0;
  TCNT0 = 0;
  bitnummer++;
  }
 if(TCNT0<139 && bitnummer <= 14 && last_bit == 0) {
  gesamt[bitnummer] = 0;
  last_bit = 0;
  TCNT0 = 0;
  bitnummer++;
  }
 if(TCNT0>139 && TCNT0<194 && bitnummer <= 14 && last_bit == 0) {
  gesamt[bitnummer] = 1;
  last_bit = 1;
  TCNT0 = 0;
  bitnummer++;
  }
 if(bitnummer == 14) {
  gesamt[1] = 1;
  send_string(ergebnis);
  last_bit = 1;
  bitnummer = 1;
  TIMSK &= ~(1<<TOIE0);
  TCNT0 = 0;
  rdy = 1;
  }
} 
   
   
int main(void)
{
 init_usart();
 init_rc5();
 sei();
 uint8_t i;
 char test[3];
 char wert[10] = "RC5:";
 for(;;)
 {
  if(rdy==1) {
  send_string(wert);
  for(i=1;i<=14;i++) {
    itoa(ergebnis[i],test,10);
    send_string(test);
    }
  rdy = 0;
  }
  
 };
}
Leider bekomme ich als Ergebnis eine ellenlange Zahl, und nicht das 
gewünschte :( zumindest die Geräteadresse müsste ja 0 sein. Wär schön 
wenn sich jemand den Code mal durchlesen würde, wenn Fragen zum Code da 
sind, bitte fragen!

Autor: Fragender (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und noch die Initialisierung + Variablen:

#include <avr/io.h>
#include <avr/interrupt.h>
#include <math.h>
#include <inttypes.h>
#include <compat/deprecated.h>





volatile char s_bit;
volatile uint8_t addresse;
volatile uint8_t code;
volatile char rdy;
volatile uint16_t gesamt[14];


volatile uint8_t bitnummer = 0;
volatile char ergebnis[20] = "RC5 fertig!";

void init_rc5()
{
 MCUCR |= (1<<ISC01) | (1<<ISC00);;  //wait rising edge
 GICR |= (1<<INT0);    //enable INT0
 TCCR0 |= (1<<CS02);   //Prescaler 256
 cbi(DDRD,PD2);
}

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
SIGNAL(SIG_INTERRUPT0)
{
  TIMSK |= (1<<TOIE0);
...
  TIMSK &= ~(1<<TOIE0);
...
Wieso hantierst du mit TOIE0, du hast doch gar keinen Timer-Interrupt.

 if(TCNT0>139 && TCNT0<194 && bitnummer <= 14 && last_bit == 1) {
  gesamt[bitnummer] = 0;
  last_bit = 0;
  TCNT0 = 0;
  bitnummer++;
  }
 if(TCNT0<139 && bitnummer <= 14 && last_bit == 0) {
  gesamt[bitnummer] = 0;
  last_bit = 0;
  TCNT0 = 0;
  bitnummer++;
  }
Wenn das erste if zutrifft, trifft auch das zweite automatisch zu (noch 
im selben Interrupt), außer "bitnummer" wird durch das erste if größer 
als 14.

volatile uint16_t gesamt[14];
...
if( ... && bitnummer <= 14 && ... ) {
  gesamt[bitnummer] = 0;
Du schreibst hinter das Ende des Array.

  for(i=1;i<=14;i++) {
    itoa(ergebnis[i],test,10);
    send_string(test);
    }
Wieso "ergebnis", die eingelesenen Bits stehen doch in "gesamt".
Und der Array-Index würde auch hier nicht stimmen.

PS: Das ist nur das, was mir auf die Schnelle aufgefallen ist. Es gibt 
vermutlich noch mehr Problemstellen.

Autor: Fragender (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
hab deine Anmerkungen ausgebessert, hilft aber leider nich twirklich 
weiter, ich schaue mir jetzt die adressbits an und die sind leider 
meistens 11111 oder es kommt gar nichts. hier der korrigierte code:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <math.h>
#include <inttypes.h>
#include <compat/deprecated.h>

volatile char s_bit;
volatile uint8_t addresse;
volatile uint8_t code;
volatile char rdy;
volatile uint16_t gesamt[14];

volatile uint8_t bitnummer = 1;
volatile char ergebnis[20] = "RC5 fertig!";

void init_rc5()
{
 MCUCR |= (1<<ISC01) | (1<<ISC00);;  //wait rising edge
 GICR |= (1<<INT0);    //enable INT0
 TCCR0 |= (1<<CS02);   //Prescaler 256
 cbi(DDRD,PD2);
}

//****************************************************USART******************************

void init_usart(void)
{
 UBRRL |= 0b01100111;
 UCSRB = (1<<TXEN) | (1<<RXEN);
 UCSRC = (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0);
}

void send_char(unsigned char s)
{
 while (!(UCSRA & (1<<UDRE)));
 UDR = s;
}

void send_string(char *s)
{
 while(*s != '\0')
  {
   send_char(*s);
   s++;
  }
}

//**********************************************************USART-ENDE********************


SIGNAL(SIG_INTERRUPT0)
{
 TIMSK |= (1<<TOIE0);
 char last_bit = 1;
 char test[3];
 uint8_t i;
 if(last_bit == 1) {
 if(TCNT0<139 && bitnummer <= 14) {
  gesamt[bitnummer] = 1;
  last_bit = 1;
  TCNT0 = 0;
  bitnummer++;
  }
 if(TCNT0>139 && TCNT0<194 && bitnummer <= 14) {
  gesamt[bitnummer] = 0;
  last_bit = 0;
  TCNT0 = 0;
  bitnummer++;
  }
 }
 if(last_bit == 0) {
 if(TCNT0<139 && bitnummer <= 14) {
  gesamt[bitnummer] = 0;
  last_bit = 0;
  TCNT0 = 0;
  bitnummer++;
  }
 if(TCNT0>139 && TCNT0<194 && bitnummer <= 14) {
  gesamt[bitnummer] = 1;
  last_bit = 1;
  TCNT0 = 0;
  bitnummer++;
  }
 }
 if(bitnummer == 14) {
  gesamt[1] = 1;
  send_string(ergebnis);
  last_bit = 1;
  bitnummer = 1;
  TIMSK &= ~(1<<TOIE0);
  TCNT0 = 0;
  rdy = 1;
  }
} 
   
   
int main(void)
{
 init_usart();
 init_rc5();
 sei();
 uint8_t i;
 char test[3];
 char wert[10] = "RC5:";
 for(;;)
 {
  if(rdy==1) {
  send_string(wert);
  for(i=4;i<=8;i++) {
    itoa(gesamt[i],test,10);
    send_string(test);
    }
  rdy = 0;
  }
  
 };
}
  

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> hab deine Anmerkungen ausgebessert

Ich hatte 4 Sachen angemerkt. Zwei sind unverändert, eines hast du 
geändert, allerdings das Problem dadurch nicht beseitigt (if-Sache).

Und bei der letzten Sache
  for(i=4;i<=8;i++) {
    itoa(gesamt[i],test,10);
    send_string(test);
    }
verstehe ich das 4 bis 8 nicht.

Autor: Fragender (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
http://www.roboternetz.de/phpBB2/viewtopic.php?p=3... Habs da 
geändert, sorry da ist das auch leichter mit Editieren.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
9 bis 14 ist für mich auch nicht verständlicher.

"gesamt" auf 16 zu vergrößern, behebt zwar das "hinter das Array 
schreiben"-Problem, geht das Problem aber von der falschen Seite her an.
Wieso beschreibst du das Array von 1 bis 14 und nicht von 0 bis 13?
Gibt es da vielleicht bei dir noch Defizite beim Verständnis von 
Array-Indexen?

Das if-Problem besteht weiterhin.
Das "if(last_bit == 0)" nützt dir da nichts, da du ja im if-Block vorher 
"last_bit = 0;" stehen hast. Eine "if ... else if ..."-Konstruktion 
würde hier helfen.

Allerdings ist auch der Ansatz schon falsch. Du kannst bei 
Manchester-Codierung die Bits nicht so einfach aus dem Abstand zwischen 
zwei steigenden Flanken ermitteln.

Autor: Fragender (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
hab das mit else if geändert, mit dem 9 bis 14 wollte ich lediglich die 
Datenbits auslesen. Wenn es nützlich ist, kann ich den Code nochmal 
posten. Warum geht das mit den steigenden Flanken nicht? Wenn ich weiss, 
ob das letzte Bit eine 1 oder 0 war, geht das doch?!

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine einfache Betrachtung zeigt, dass deine Methode so nicht gehen kann:
Du ermittelst zu jeder steigenden Flanke ein Bit, du hast also eine 
1:1-Relation von steigenden Flanken und Bits. Jetzt zeichne dir mal den 
Manchester-Code zur Bitfolge 010101... auf. Da hast du mehr Bits, als 
steigende Flanken. Wie soll dein Algorithmus diese Bitfolge also 
rekonstruieren können?

Autor: Fragender (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
das hast du recht :/. Hast du vielleicht einen Tip, wie ich es sonst 
angehen könnte? Ich mag auf keinen Fall einen fertigen Code verwenden, 
hab da mittlerweile soviel Zeit reingesteckt, dass ich das einigermssen 
in Eigenregie zum Laufen bringen möchte.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.