Hallo,
ich habe einen Code auf einem Mega 2560 und 1280 laufen welcher auch gut läuft. Nun wollte ich auf den Due umsteigen. Das meiste habe ich auch schon umgeschrieben bekommen aber bei der Empfangsroutine für FS20 Funkempfänger hadert es etwas. Das ganze funktioniert auf den Megas mit einem analog comparator jedoch finde ich keinen passenden umbau für den Due.
Ich poste nicht das ganz Programm da dieses zu viel wäre sondern nur den relevanten Teil.
Im Anhang ist der komplette Code.
static uint8_t FS20_bit (char value) {
FS20.data = (FS20.data << 1) | value;
if (FS20.bits < 0 && (uint8_t) FS20.data != 0x01)
return OK;
if (++FS20.bits == 45 && ((FS20.data >> 15) & 1) == 0 || FS20.bits == 54 && ((FS20.data >> 24) & 1))
return DONE;
return OK;
}
static void ook868interrupt () {
// count is the pulse length in units of 4 usecs
byte count = TCNT2;
TCNT2 = 0;
// FS20 pulse widths are 400 and 600 usec (split on 300, 500, and 700)
// see http://fhz4linux.info/tiki-index.php?page=FS20%20Protocol
if (FS20.state != DONE)
switch ((count - 25) / 50) {
case 1:
FS20.state = FS20.state == T0 ? FS20_bit(0) : T0;
break;
case 2:
FS20.state = FS20.state == T1 ? FS20_bit(1) : T1;
break;
default:
FS20.state = UNKNOWX;
}
}
static void reset_FS20 () {
FS20.bits = -1;
FS20.data = 0xFF;
FS20.state = UNKNOWX;
}
static void ook868timeout () {
if (FS20.state != DONE)
reset_FS20();
/* if (S300.state != DONE)
reset_S300();
if (EM10.state != DONE)
reset_EM10();*/
}
static void ook868setup () {
pinMode(rx868Pin, INPUT);
pinMode(tx868Pin, OUTPUT);
digitalWrite(rx868Pin, 1); // pull-up
/* enable analog comparator with fixed voltage reference
ACSR =
(0<<ACD) | // Analog Comparator: Enabled
(0<<ACBG) | // Analog Comparator Bandgap Select: AIN0 is applied to the positive input
(0<<ACO) | // Analog Comparator Output: Off
(1<<ACI) | // Analog Comparator Interrupt Flag: Clear Pending Interrupt
(1<<ACIE) | // Analog Comparator Interrupt: Enabled
(0<<ACIC) | // Analog Comparator Input Capture: Disabled
(1<<ACIS1) | (1<ACIS0); // Analog Comparator Interrupt Mode: Comparator Interrupt on Rising Output Edge
*/
ACSR = _BV(ACBG) | _BV(ACI) | _BV(ACIE);
ADCSRA &= ~ _BV(ADEN);
ADCSRB |= _BV(ACME);
// ADMUX = 0; // ADC0
ADMUX = rx868Pin - A0; // ADC0
/* Timer2 (8 Bit Timer) prescaler 64 -> 250 KHz = 4 usec/count, max 1.024 msec (16 MHz clock) */
TCNT2 = 0;
TCCR2A = 0;
TCCR2B = _BV(CS22);
TIMSK2 = _BV(TOIE2);
reset_FS20();
}
static byte ook868poll (byte* buf) {
if (FS20.state == DONE) {
uint32_t since = millis() - FS20.prev;
if (since > 150) {
uint8_t len = FS20.bits / 9;
uint8_t sum = 6; //FS20
for (uint8_t i = 0; i < len; ++i) { //Quersumme erstellen
uint8_t b = FS20.data >> (1 + 9 * i);
buf[len - i - 1] = b;
if (i > 0)
sum += b;
}
if ((sum == buf[len - 1]) || (sum + 6 == buf[len - 1])) { //Wenn Quersumme ok Daten leeren und mit return len als gültiges Paket anerkennen. +6 für FHT
FS20.prev = millis();
reset_FS20();
if (since > 150)
return len;
}
else
log(B11, true, PSTR("~> %02d %02d %02d %02d %02d %02d :%d"), buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], len);
}
reset_FS20();
}
return 0;
}
ISR(ANALOG_COMP_vect) {
ook868interrupt();
}
ISR(TIMER2_OVF_vect) {
ook868timeout();
}
Hausbrett.ino (114 KB)