Arduino und ATtiny202
Nach
einem früheren Misserfolg konnte ich nun die aktuelle Version
megaTinyCore von SpenceKonde erfolgreich installieren. Besonders
hat mich gefreut, dass ich nun keinen speziellen Bootloader im Tiny202
verwenden muss, sondern meine bewährte Schaltung mit der seriellen
Programmierung über einen USB/Seriell-Wandler und einen zusätzlichen
Widerstand verwenden kann. Das Bild oben zeigt, wie ich das
Blink-Beispiel aus der Arduino-IDE in den Tiny202 übertragen habe.
Blieb nur die Frage, wo denn nun die LED_BUIDLIN liegt. Das
Blink-Signal war schnell gefunden, es liegt am Pin 7, nach
Arduino-Zählung am IO-Pin 4.
Zuerst habe ich im Boardverwalter die aktuelle Version 2.6.10 des
megaTinyCore installiert. Das dauert recht lange, sodass ich
vorsichtshalber schon mal im Windows-Task-Manager nachgeschaut habe, ob
überhaupt etwas passiert. Aber irgendwann war es fertig. Von nun an
kann ich den megaTinyCore und darin den verwendeten Controller, in
diesem Fall den ATtiny202 wählen.
In den
Werkzeugen kann man nun den Chip (ATtiny202) auswählen, die
Taktfrequenz mit 20 MHz wählen, den COM-Port einstellen und den
Programmer wählen. SerialUPDI funktionioniert genauso wie Pymcuprog
ohne ein spezielles Programmiergerät.
Als nächstes habe ich aus den Arduino-Beispielen den Sketch
AnalogInOutSerial geladen. Das ist ein Test für den AD-Wandler, die
PWM-Ausgabe und die serielle Print-Ausgabe. Die einzige erforderliche
Anpassung betraf den analogen Eingangspin und den analogen Ausgangspin.
Hier habe ich D3 (Pin7) und D4 (Pin5) gewählt. Die serielle
Ausgabe der Messwerte kann auch für den Seriellen Plotter
verwendet werden. Hier wurde die Entladekurve eines 100µF-Elkos an
einem 1 MOhm-Widerstand aufgezeichnet.
Am Ende habe ich einige Quelltexte in die Arduino-IDE übernommen, die
zuvor mit PlatformIO entwickelt worden waren. In allen Fällen hat das
funktioniert. Deshalb habe ich nun eine Änderung in meinem Infrarot-Transceiver
mit der Arduino-Software getestet. Es ging um eine Änderung der
Timeout-Zeit. Bisher hat sich das Gerät nach einer Minute ohne
Sende-Aktivitäten abgeschaltet. Das hat sich jedoch als zu kurz
erwiesen, wenn man einer längeren Antwort der Gegenstation lauscht. In
der neuen Version wurde das Timeout auf 10 Minuten erhöht.
//IRCWTRX202, Touch PA1, IR-LED PA3, LED PA7, S1 PA6
#include <avr/io.h>
#define F_CPU 3333333
#define __DELAY_BACKWARD_COMPATIBLE__
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <util/atomic.h>
volatile uint8_t pa6Ioc;
uint8_t t=0;
uint32_t timeout = 0;
uint32_t limit = 600000; //10 min
ISR(PORTA_PORT_vect){
if(PORTA.INTFLAGS & PIN6_bm){
pa6Ioc = 1;
PORTA.INTFLAGS &= PIN6_bm;
}
}
int main(void){
PORTA.DIRSET = PIN3_bm; //Ausgang PA3
PORTA.DIRSET = PIN1_bm; //Ausgang PA1
PORTA.PIN1CTRL = PORT_PULLUPEN_bm;; //Pullup PA1
PORTA.DIR |= PIN7_bm; //LED
PORTA.OUT |= PIN7_bm;
PORTA.DIR |= PIN2_bm; //IR-RX
PORTA.OUT |= PIN2_bm;
PORTA.DIR &= ~ PIN6_bm; //S1
PORTA.PIN6CTRL |= PORT_PULLUPEN_bm |
PORT_ISC_BOTHEDGES_gc;
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sei();
while(1) {
t=0;
PORTA.DIRCLR = PIN1_bm;
while((!(VPORTA.IN & PIN1_bm))&&(t<3)){
t++;
}
PORTA.DIRSET = PIN1_bm;
if (t>1 || !(VPORTA.IN & PIN6_bm) ){
for(char n=0; n<10; n++){
PORTA.OUTSET = PIN3_bm;
_delay_us(3);
PORTA.OUTCLR = PIN3_bm;
_delay_us(21);
}
timeout = 0;
}
_delay_ms(1);
timeout++;
if(timeout>limit){ //10 min
PORTA.OUT &= !PIN7_bm;
PORTA.OUT &= !PIN2_bm;
sleep_mode();
ATOMIC_BLOCK(ATOMIC_FORCEON){
_delay_ms(10);
}
timeout=0;
PORTA.OUT |= PIN7_bm;
PORTA.OUT |= PIN2_bm;
}
}
}