Irgendwann bin ich an dem Punkt angelangt, da reichte die Funktionalität von einfachen Schaltungen nicht mehr aus, ein vollständiger kleiner Ein-Platinen-Rechner wäre dafür aber schon überdimensioniert. Für solche Aufgaben bietet sich ein Mikrocontroller an. Und um das ganze mal auszuprobieren, will man sich ja nicht direkt einen professionellen Programmer und ein Entwicklungsboard zulegen.
Praktischerweise bietet der Raspberry Pi entsprechende Möglichkeiten, über die UART-Schnittstelle seiner GPIO-Ports das gleiche zu erreichen. Dazu ist allerdings ein bisschen Einrichtung notwendig. Im Netz gibt es dazu zahlreiche Tutorials, die ich nicht wiederholen will, sondern hier einmal zusammenfassen, was für mich am besten funktoniert hat.
Als erstes sollte man sich die nötigen Komponenten runterladen, avrdude ist nicht über Repositories zu bekommen, daher mit wget direkt runterladen und mit dpkg installieren. Die weiteren Komponenten (Arduino IDE, git-core, gcc-avr) können mit apt-get installiert werden. lxde ist optional, wenn man noch keine grafische Oberfläche installiert hat und xrdp ist ganz praktisch, wenn man nicht am Raspberry selbst programmieren, sondern sich per Remote Desktop mit ihm verbinden will.
1 2 3 4 5 6 7 8 |
wget http://project-downloads.drogon.net/files/avrdude_5.10-4_armhf.deb wget http://project-downloads.drogon.net/files/avrdude-doc_5.10-4_all.deb dpkg -i avrdude_5.10-4_armhf.deb dpkg -i avrdude-doc_5.10-4_all.deb apt-get update apt-get install arduino git-core gcc-avr lxde xrdp |
Wenn am Raspberry Pi selbst keine Eingabegeräte oder Monitor angeschlossen sind, wie bei mir, bietet es sich an, alles von einem Remote-PC aus zu erledigen. Dazu installieren wir uns noch einen Samba-Server für Netzwerkfreigaben (Anleitung hier) und für den Konsolenzugriff PuTTY für Windows. Als Netzwerkfreigabe richten wir uns den Home-Ordner unseres Raspberry-Users ein. Damit wäre der Raspberry dann schonmal für den Remotezugriff und mit der Entwicklungsumgebung eingerichtet.
Jetzt werden noch andere Anpassungen nötig, bevor wir starten können. Standardmäßig wird die UART-Schnittstelle am Raspberry Pi unter Raspbian als serielle Schnittstelle verwendet. Um sie als UART-Schnittstelle benutzen zu können, gehen wir wie folgt vor:
Mit
1 |
sudo nano /boot/cmdline.txt |
öffnen wir die Datei /boot/cmdline.txt im Editor und entfernen den Teil “console=ttyAMA0,115200 kgdboc=ttyAMA0,115200″, so dass die entsprechende Zeile dann so aussieht:
1 |
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait |
Ausserdem muss in der Datei /etc/inittab eine Zeile auskommentiert werden, dazu öffnen wir die Datei wieder mit nano:
1 |
sudo nano /etc/inittab |
und kommentieren diese Zeile aus:
1 |
# T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100 |
Jetzt wir der Raspberry einmal neugestartet und die UART-Schnittstelle steht zur Verfügung.
Jetzt brauchen wir noch die notwendigen Bibliotheken für die AVR-Controller und die Definition des Raspberry als Programmer in der Arduino IDE, dann kann es losgehen.
Arduino IDE hat bei der Installation im Home-Ordner das Verzeichnis “sketchbook” angelegt, hier werden alle Hardware-Definitionen, Libraries und Projektdateien abgelegt. Für die ATTiny-Reihe der AVR-Mikrocontroller gibt es hier die Core-Definitionen. Je nach Version der Arduino IDE sollte man das entsprechende Archiv runterladen. Der Inhalt wird dann in das Verzeichnis “hardware” entpackt.
Im Verzeichnis “/sketchbook/hardware/tiny/” legen wir nun (für den ATTiny84 als Beispiel) die Datei boards.txt an mit folgendem Inhalt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
attiny84at8.name=ATtiny84 @ 8 MHz (internal oscillator; BOD disabled) # The following do NOT work... # attiny84at8.upload.using=avrispv2 # attiny84at8.upload.using=Pololu USB AVR Programmer # The following DO work (pick one)... attiny84at8.upload.using=arduino:arduinoisp # attiny84at8.upload.protocol=avrispv2 # attiny84at8.upload.using=pololu attiny84at8.upload.maximum_size=8192 # Default clock (slowly rising power; long delay to clock; 8 MHz internal) # Int. RC Osc. 8 MHz; Start-up time PWRDWN/RESET: 6 CK/14 CK + 64 ms; [CKSEL=0010 SUT=10]; default value # Brown-out detection disabled; [BODLEVEL=111] # Preserve EEPROM memory through the Chip Erase cycle; [EESAVE=0] attiny84at8.bootloader.low_fuses=0xE2 attiny84at8.bootloader.high_fuses=0xD7 attiny84at8.bootloader.extended_fuses=0xFF attiny84at8.bootloader.path=empty attiny84at8.bootloader.file=empty84at8.hex attiny84at8.build.mcu=attiny84 attiny84at8.build.f_cpu=8000000L attiny84at8.build.core=tiny ########################################################################### attiny84at1.name=ATtiny84 @ 1 MHz (internal oscillator; BOD disabled) # The following do NOT work... # attiny84at1.upload.using=avrispv2 # attiny84at1.upload.using=Pololu USB AVR Programmer # The following DO work (pick one)... attiny84at1.upload.using=arduino:arduinoisp # attiny84at1.upload.protocol=avrispv2 # attiny84at1.upload.using=pololu attiny84at1.upload.maximum_size=8192 # Default clock (slowly rising power; long delay to clock; 8 MHz internal; divide clock by 8) # Int. RC Osc. 8 MHz; Start-up time PWRDWN/RESET: 6 CK/14 CK + 64 ms; [CKSEL=0010 SUT=10]; default value # Divide clock by 8 internally; [CKDIV8=0] # Brown-out detection disabled; [BODLEVEL=111] # Preserve EEPROM memory through the Chip Erase cycle; [EESAVE=0] attiny84at1.bootloader.low_fuses=0x62 attiny84at1.bootloader.high_fuses=0xD7 attiny84at1.bootloader.extended_fuses=0xFF attiny84at1.bootloader.path=empty attiny84at1.bootloader.file=empty84at1.hex attiny84at1.build.mcu=attiny84 attiny84at1.build.f_cpu=1000000L attiny84at1.build.core=tiny ########################################################################### |
Ausserdem noch die Datei “/sketchbook/hardware/tiny/variants/tiny8/pins_arduino.h”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
/* pins_arduino.c - pin definitions for the Arduino board Part of Arduino / Wiring Lite Copyright (c) 2005 David A. Mellis This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA $Id: pins_arduino.c 565 2009-03-25 10:50:00Z dmellis $ Modified 28-08-2009 for attiny84 R.Wiersma Modified 09-10-2009 for attiny45 A.Saporetti */ #ifndef Pins_Arduino_h #define Pins_Arduino_h #include <avr/pgmspace.h> // ATMEL ATTINY45 / ARDUINO // // +-\/-+ // Ain0 (D 5) PB5 1| |8 Vcc // Ain3 (D 3) PB3 2| |7 PB2 (D 2) Ain1 // Ain2 (D 4) PB4 3| |6 PB1 (D 1) pwm1 // GND 4| |5 PB0 (D 0) pwm0 // +----+ static const uint8_t A0 = 6; static const uint8_t A1 = 7; static const uint8_t A2 = 8; static const uint8_t A3 = 9; #define digitalPinToPCICR(p) ( ((p) >= 0 && (p) <= 4) ? (&GIMSK) : ((uint8_t *)0) ) #define digitalPinToPCICRbit(p) ( PCIE ) #define digitalPinToPCMSK(p) ( ((p) <= 4) ? (&PCMSK) : ((uint8_t *)0) ) #define digitalPinToPCMSKbit(p) ( (p) ) #define analogPinToChannel(p) ( (p) < 6 ? (p) : (p) - 6 ) #ifdef ARDUINO_MAIN // these arrays map port names (e.g. port B) to the // appropriate addresses for various functions (e.g. reading // and writing) tiny45 only port B const uint16_t PROGMEM port_to_mode_PGM[] = { NOT_A_PORT, NOT_A_PORT, (uint16_t) &DDRB, }; const uint16_t PROGMEM port_to_output_PGM[] = { NOT_A_PORT, NOT_A_PORT, (uint16_t) &PORTB, }; const uint16_t PROGMEM port_to_input_PGM[] = { NOT_A_PIN, NOT_A_PIN, (uint16_t) &PINB, }; const uint8_t PROGMEM digital_pin_to_port_PGM[] = { PB, /* 0 */ PB, PB, PB, PB, PB, // 5 PB, // A0 PB, PB, PB, // A4 }; const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = { _BV(0), /* 0, port B */ _BV(1), _BV(2), _BV(3), /* 3 port B */ _BV(4), _BV(5), _BV(5), _BV(2), _BV(4), _BV(3), }; const uint8_t PROGMEM digital_pin_to_timer_PGM[] = { TIMER0A, /* OC0A */ TIMER0B, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, }; #endif #endif |
und die Datei “/sketchbook/hardware/tiny/variants/tiny14/pins_arduino.h”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
/* pins_arduino.c - pin definitions for the Arduino board Part of Arduino / Wiring Lite Copyright (c) 2005 David A. Mellis This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA $Id: pins_arduino.c 565 2009-03-25 10:50:00Z dmellis $ Modified 28-08-2009 for attiny84 R.Wiersma Modified 09-10-2009 for attiny45 A.Saporetti */ #ifndef Pins_Arduino_h #define Pins_Arduino_h #include <avr/pgmspace.h> // ATMEL ATTINY84 / ARDUINO // // +-\/-+ // VCC 1| |14 GND // (D 10) PB0 2| |13 AREF (D 0) // (D 9) PB1 3| |12 PA1 (D 1) // PB3 4| |11 PA2 (D 2) // PWM INT0 (D 8) PB2 5| |10 PA3 (D 3) // PWM (D 7) PA7 6| |9 PA4 (D 4) // PWM (D 6) PA6 7| |8 PA5 (D 5) PWM // +----+ const static uint8_t A0 = 0; const static uint8_t A1 = 1; const static uint8_t A2 = 2; const static uint8_t A3 = 3; const static uint8_t A4 = 4; const static uint8_t A5 = 5; const static uint8_t A6 = 6; const static uint8_t A7 = 7; #define digitalPinToPCICR(p) ( ((p) >= 0 && (p) <= 10) ? (&GIMSK) : ((uint8_t *)0) ) #define digitalPinToPCICRbit(p) ( ((p) <= 7) ? PCIE0 : PCIE1 ) #define digitalPinToPCMSK(p) ( ((p) <= 7) ? (&PCMSK0) : (((p) <= 10) ? (&PCMSK1) : ((uint8_t *)0)) ) #define digitalPinToPCMSKbit(p) ( ((p) <= 7) ? (p) : (10 - (p)) ) #ifdef ARDUINO_MAIN // these arrays map port names (e.g. port B) to the // appropriate addresses for various functions (e.g. reading // and writing) const uint16_t PROGMEM port_to_mode_PGM[] = { NOT_A_PORT, (uint16_t)&DDRA, (uint16_t)&DDRB, }; const uint16_t PROGMEM port_to_output_PGM[] = { NOT_A_PORT, (uint16_t)&PORTA, (uint16_t)&PORTB, }; const uint16_t PROGMEM port_to_input_PGM[] = { NOT_A_PORT, (uint16_t)&PINA, (uint16_t)&PINB, }; const uint8_t PROGMEM digital_pin_to_port_PGM[] = { PA, /* 0 */ PA, PA, PA, PA, PA, PA, PA, PB, /* 8 */ PB, PB, }; const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = { _BV(0), /* port A */ _BV(1), _BV(2), _BV(3), _BV(4), _BV(5), _BV(6), _BV(7), _BV(2), /* port B */ _BV(1), _BV(0), }; const uint8_t PROGMEM digital_pin_to_timer_PGM[] = { NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, TIMER1B, /* OC1B */ TIMER1A, /* OC1A */ TIMER0B, /* OC0B */ TIMER0A, /* OC0A */ NOT_ON_TIMER, NOT_ON_TIMER, }; #endif #endif |
Damit sind jetzt die ATTinys bekannt. In der Datei “/usr/share/arduino/hardware/arduino/programmers.txt” ergänzen wir folgende Zeilen und definieren so den Raspberry als Programmer:
1 2 3 |
gpio.name=Raspberry Pi GPIO (on-board) gpio.communication=gpio gpio.protocol=gpio |
Jetzt ist der Raspberry Pi endlich soweit eingerichtet, dass es an die Verkabelung und an den ersten Test-Sketch gehen kann. Mehr dazu im nächsten Artikel.
Pingback: Programmieren von Attiny84 durch den Raspberry Pi | blog.necromundo.de
Pingback: ATTiny84 mit Arduino UNO programmieren | blog.necromundo.de