Problem mit Tiny45

Servus,
Im Zuge meines aktuellen Projekts ist bei mir ein seltsames Problem aufgetaucht:
Um mit dem Tiny ein IR NEC Code dekodiren zu können habe ich nachfolgendes Programm geschrieben.

Zum Debuggen usw. habe ich das mit meim IR-Empfänger und Arduino getestet (wegen Serial ...), wo es auch gut funktioniert.
Das Problem ist nun, das es auf meinem Tiny45 (interner 8MHz Oszi mit Vorteiler 8) überhaupt nicht funktioniert.
Ich hab ne LED an den Pin über welchen die Debug-Funktion läuft angeschlossen und das Ganze laufen lassen,
mir ist aufgefallen, dass er bereits beim ersten Bit die Funktion (getNecCode()) abbricht und das immer egal bei welcher Taste.

Weiß jemand zufällig wo das Problem sitzt, das einzige was mir noch in den Kopf kommt ist, dass der Ram aufgebraucht ist
das kann ich mir aber nicht vorstellen o_O:

#define PIN_DATA 4
#define PIN_CHAN_POW 1
#define PIN_CHAN_CDD 0

#define NEC_START_MIN 8500
#define NEC_START_MAX 9500
#define NEC_PAUSE_MIN 4000
#define NEC_PAUSE_MAX 5000

#define NEC_BRUST_MIN 480
#define NEC_BRUST_MAX 640

#define NEC_ONE_MIN  480
#define NEC_ONE_MAX  640
#define NEC_ZERO_MIN 1610
#define NEC_ZERO_MAX 1770

#define CODE_ON  0x4DB242FF
#define CODE_OFF 0x4CB342FF
#define CODE_CD  0x4FB042FF

boolean error;

void setup()
{
  pinMode(PIN_DATA, INPUT);
  pinMode(PIN_CHAN_POW, OUTPUT);
  pinMode(PIN_CHAN_CDD, OUTPUT);
}

void loop()
{
  if(isNecCode() == true)
  { 
    unsigned long res = getNecCode();
    
    if(error == false)
    {
      if(res == CODE_ON)
        turnOn();
      else if(res == CODE_OFF)
        turnOff();
      else if(res == CODE_CD)
        cdOpenClose();
      
      debug(3);
    }
    else
    {
      error = false;
    }
  }
}

//Stellt fest ob es ein NecCode ist
boolean isNecCode()
{
  unsigned long startTime = micros();
  while(digitalRead(PIN_DATA) == LOW);
  startTime = micros() - startTime;
  
  if(startTime > NEC_START_MIN && startTime < NEC_START_MAX)
  {
    startTime = micros();
    while(digitalRead(PIN_DATA) == HIGH);
    startTime = micros() - startTime;
    
    if(startTime > NEC_PAUSE_MIN && startTime < NEC_PAUSE_MAX) 
      return true;
    else
      return false;
  }
  
  return false;
}

//Entschlüsselt ein einzelnes Bit
unsigned long getBit()
{
  unsigned long startTime = micros();
  while(digitalRead(PIN_DATA) == LOW);
  startTime = micros() - startTime;
  
  if(startTime > NEC_BRUST_MIN && startTime < NEC_BRUST_MAX)
  {
    startTime = micros();
    while(digitalRead(PIN_DATA) == HIGH)
    {
      if(micros() - startTime > NEC_ZERO_MAX) break;
    }
    startTime = micros() - startTime;
    
    if(startTime > NEC_ONE_MIN && startTime < NEC_ONE_MAX) 
      return 1;
    else if(startTime > NEC_ZERO_MIN && startTime < NEC_ZERO_MAX)
      return 0;
    else
      return startTime;
  }
  
  return startTime;
}

//Gibt den NEC Code zurrück
unsigned long getNecCode()
{
  unsigned long result = 0;
  
  for(int i = 0; i < 32; i++)
  {
    unsigned long tempBit = getBit();
    if(tempBit == 1) { 
      result |= (1UL << i);
    } else if(tempBit == 0) {

    } else if(tempBit != 0) {
      
      if(result > 10) 
        debug(2);
      else
        debug(1);
      
      error = true;
      break;
    }
  }   
  
  return result;
}

//Schaltet die Konsole an
void turnOn()
{
  digitalWrite(PIN_CHAN_POW, HIGH);
  delay(100);
  digitalWrite(PIN_CHAN_POW, LOW);
}

//Schaltet die Konsole aus
void turnOff()
{
  digitalWrite(PIN_CHAN_POW, HIGH);
  delay(3000);
  digitalWrite(PIN_CHAN_POW, LOW);
}

//CD-Laufwerk auf/zu
void cdOpenClose()
{
  digitalWrite(PIN_CHAN_CDD, HIGH);
  delay(100);
  digitalWrite(PIN_CHAN_CDD, LOW);
}

void debug(int num)
{
  for(int i = 0; i < num; i++)
  {
    digitalWrite(PIN_CHAN_CDD, HIGH);
    delay(1000);
    digitalWrite(PIN_CHAN_CDD, LOW);
    delay(1000);
  }
 }

Jop, BURST, danke.
Kleiner Tippfehler.
Löst aber mein Problm nicht :~ :frowning:

Hallo,

kann es sein, dass der Tiny45 nichts davon weiß dass er nur mit 1MHz läuft und deshalb micros() und delay() um den Faktor 16 daneben liegen?

Gruß Peter

p.s. lade doch mal den Blink-Sketch drauf und prüfe mit einer LED das Blinken im Sekundenrythmus.

Ne, das kann es auf garkeinen Fall sein, die Fuses stimmen allse,
und beim Debuggen blingt die LED- eh im Sekunden Takt, das klappt alles

Moinsen,

vor der ersten Abfrage der globalen boolschen Variable "error" nach Aufruf von getNeccode() in der loop kann ich keine Initialisierung auf false finden, hast Du das schonmal gecheckt?

Hab es geändert, aber der Fehler ist immernoch.

Der Fehler taucht in der Funktion getBit() auf.
Er erkennt, dass es sich bei dem IR Code um einen NEC-Code handelt und springt in die Funktion
getNecCode(). Die ruft getBit() 32 mal in eriner For-Schleife auf.

Die getBit() Funktion soll feststellen, wie lange der Pin vom Sensor auf LOW ist.
Ist er lange genug LOW, dann überprüft sie, wie lange er HIGH ist und genau da scheint der Fehler zu sein.
Irgendwie misst er da nicht richtig und er gibt Zeiten von unter 10 Mikrosekunden zurück, was auf keinen Fall sein kann,
denn der parallel am Sensor angeschlossene Arduino macht genau an der stelle keinen Fehler sondern erkennt den Code richtig.
Auf beiden läuft exakt der selbe Code ausser das beim Tiny die Pins angepasst wurden.

Edit:

Es hat funktioniert, das Problem war, das der 1MHz Takt zulangsam war.
Der Tiny läuft jetz mit 8MHz und alles klappt perfekt.

Lag wohl daran, das Micros dann spinnt.

Danke für die Hilfe :wink:

Funktionierender Code:

#define PIN_DATA 4
#define PIN_CHAN_POW 1
#define PIN_CHAN_CDD 0

#define NEC_START_MIN 8500
#define NEC_START_MAX 9500
#define NEC_PAUSE_MIN 4000
#define NEC_PAUSE_MAX 5000

#define NEC_BRUST_MIN 480
#define NEC_BRUST_MAX 640

#define NEC_ONE_MIN  480
#define NEC_ONE_MAX  640
#define NEC_ZERO_MIN 1610
#define NEC_ZERO_MAX 1770

#define CODE_ON  0x4DB242FF
#define CODE_OFF 0x4CB342FF
#define CODE_CD  0x4FB042FF

boolean error;

void setup()
{
  pinMode(PIN_DATA, INPUT);
  pinMode(PIN_CHAN_POW, OUTPUT);
  pinMode(PIN_CHAN_CDD, OUTPUT);
  
  error = false;
}

void loop()
{
  if(isNecCode() == true)
  { 
    unsigned long res = getNecCode();
    
    if(error == false)
    {
      if(res == CODE_ON)
        turnOn();
      else if(res == CODE_OFF)
        turnOff();
      else if(res == CODE_CD)
        cdOpenClose();
    }
    else
    {
      error = false;
    }
  }
}

//Stellt fest ob es ein NecCode ist
boolean isNecCode()
{
  unsigned long startTime = micros();
  while(digitalRead(PIN_DATA) == LOW);
  startTime = micros() - startTime;
  
  if(startTime > NEC_START_MIN && startTime < NEC_START_MAX)
  {
    startTime = micros();
    while(digitalRead(PIN_DATA) == HIGH);
    startTime = micros() - startTime;
    
    if(startTime > NEC_PAUSE_MIN && startTime < NEC_PAUSE_MAX) 
      return true;
    else
      return false;
  }
  
  return false;
}

//Entschlüsselt ein einzelnes Bit
unsigned long getBit()
{
  unsigned long startTime = micros();
  while(digitalRead(PIN_DATA) == LOW);
  startTime = micros() - startTime;
  
  if(startTime > NEC_BRUST_MIN && startTime < NEC_BRUST_MAX)
  {
    startTime = micros();
    while(digitalRead(PIN_DATA) == HIGH)
    {
      if(micros() - startTime > NEC_ZERO_MAX) break;
    }
    startTime = micros() - startTime;
    
    if(startTime > NEC_ONE_MIN && startTime < NEC_ONE_MAX) 
      return 1;
    else if(startTime > NEC_ZERO_MIN && startTime < NEC_ZERO_MAX)
      return 0;
    else
      return startTime;
  }
   
  return startTime;
}

//Gibt den NEC Code zurrück
unsigned long getNecCode()
{
  unsigned long result = 0;
  
  for(int i = 0; i < 32; i++)
  {
    unsigned long tempBit = getBit();
    if(tempBit == 1) { 
      result |= (1UL << i);
    } else if(tempBit != 0) {      
      error = true;
      break;
    }
  }   
  
  return result;
}

//Schaltet die Konsole an
void turnOn()
{
  digitalWrite(PIN_CHAN_POW, HIGH);
  delay(100);
  digitalWrite(PIN_CHAN_POW, LOW);
}

//Schaltet die Konsole aus
void turnOff()
{
  digitalWrite(PIN_CHAN_POW, HIGH);
  delay(3000);
  digitalWrite(PIN_CHAN_POW, LOW);
}

//CD-Laufwerk auf/zu
void cdOpenClose()
{
  digitalWrite(PIN_CHAN_CDD, HIGH);
  delay(100);
  digitalWrite(PIN_CHAN_CDD, LOW);
}