De ORT Robotic Arm van Concorde Robotique in Cardiff werd in 1987 geproduceerd in Engeland. Ik kwam er eentje tegen op Marktplaats voor weinig en kon de verleiding niet weerstaan. De robot arm is in prima staat, de grijper ziet er wat ongeordend uit maar dat lijkt me oplosbaar. Alle andere assen draaien soepel. De robot arm kwam met een 12 V voeding en een 10-aderige flatcable. De aansturing kon nog wel eens een klusje worden. Over Concorde Robotique kan ik helemaal geen informatie vinden.
Deze blauwe robot arm heeft aan de binnenkant een printplaat van Colne Robotics en heeft onder de verflaag een oranjerode kleur. Misschien een grondlaag, maar mogelijk betreft het hier een overgespoten robot arm van het type Armdroid van Colne Robotics. Over Colne Robotics is heel veel informatie op het internet beschikbaar en de Armdroid robot armen van dit bedrijf lijken sprekend op deze blauwe, zij het dat ze oranjerood van kleur zijn.
Het elektrische deel van de robot arm bestaat uit zes uit de kluiten gewassen stappenmotoren, die op een printplaat zijn aangesloten, waarop zo op het eerste gezicht alleen enkele logische IC’s en een paar motordrivers zijn gemonteerd. Er is geen CPU en daarom zal de logische aansturing van buitenaf moeten komen, via de 10-aderige kabel. De printplaat bevat 15 verschillende IC’s, waarvan de meest voorkomende productiedatum week 3 in 1987 is. Hiernaast zijn er nog 5 lege IC-voeten.
Ik lees in het ETI magazine uit 1981, waar deze robot arm voor het eerst werd geïntroduceerd, dat er over de 10-aderige kabel zowel schakelaars kunnen worden ingelezen, als de zes stappenmotoren worden aangestuurd. Nu bevat deze ORT robot arm geen schakelaars, maar voor het bufferen van schakelaars zullen de lege IC-voeten voor zijn. Misschien valt er nog iets uit te breiden.
De aansturing van de stappenmotoren is heel low level: de signalen op de 10-aderige kabel bevatten 3 bits voor de selectie van een stappenmotor, 4 bits die gebruikt worden om de stappenmotor te laten draaien, een enable (of richting) bit en 2 voedingslijnen. Op basis van de beschikbare informatie heb ik de volgende schematische weergave opgesteld.
Om deze robot arm met bijvoorbeeld een Arduino of Raspberry Pi te besturen zal er een vertaling moeten plaatsvinden van één of andere vorm van commando (zoals ‘beweeg pols drie stappen omhoog’ of ‘beweeg pols naar positie x’) naar de low level besturing van de stappenmotoren (‘activeer spoel A en spoel B van motor 1’). Ik denk dat ik de commandostructuur leen van de CS-113, die hiervoor prima documentatie heeft. De Arduino moet dan de vertaling doen. Als ik dat eenmaal aan de praat heb, kan ik de Arduino uitbreiden met een toetsenbord of joystick.
Er was een tijd dat er geen iPads en Macintoshes waren en beide Apple Computer medewerkers nog vanuit de garage van Steve Jobs werkten. In die tijd (het zal 1981 zijn geweest) kwam Multitech (later Acer genoemd) met zijn eerste computer-voor-onderwijsdoeleinden op de markt: de Micro-Professor MPF-1. Ook Nederland was goedbedeeld als het ging om de beschikbaarheid van deze ‘unieke leer- en experimenteercomputer’, die voor zo’n 400 gulden inclusief BTW en verzendkosten (nu zo’n 1000 euro) in de handen van de nieuwsgierige hobbyist terecht kwam. En laten we eerlijk zijn: het wás een unieke computer, met experimenteermogelijkheden die ook vandaag de dag niets aan waarde hebben ingeleverd.
De MPF-1 is een microprocessorsysteem gebaseerd op een Zilog Z80. De kleine printplaat bevat de 1,7MHz processor, een rekenmachine-achtig toetsenbord met 36 toetsen en een 6-cijferig 7-segment LED display. Er is verder voorzien in een 8255 PPI Programmable Peripheral Interface die het toetsenbord uitleest en 4KB ROM en 2KB RAM in de vorm van een 2732 EPROM en een 6116 RAM chip. Ook zijn er drie lege IC-voeten voor geheugenuitbreiding, naar wens EPROM of RAM, en twee lege IC-voeten voor een Z80 PIO Parallel I/O en een Z80 CTC Counter Timer. De MPF-1 heeft een kleine luidspreker, aansluitingen voor een cassetterecorder en een gebied waarop kleine eigen schakelingen kunnen worden gesoldeerd. Bijzonder is de behuizing: die bestaat uit een kunststof boekomslag die, dichtgeslagen, zo de boekenkast in kan.
De MPF-1 wordt in Z80 assembly geprogrammeerd. Deze assembleertaal-instructies zien er uit als LD A,05 en ADD A,B, wat wordt ingevoerd als hexadecimale codes (bytes) 3E-05-80 (verderop meer over de vertaling). De bijgeleverde handleidingen bevatten veel uitgewerkte voorbeelden van onder meer timers en spelletjes die gebruik maken van het 6-cijferige display en de luidspreker. De hexadecimale codes van deze voorbeelden worden byte-voor-byte via het toetsenbord ingevoerd in geheugenadressen, met tussen iedere byte het ophogen van het geheugenadres met een druk op de toets +, zoals (1800) 3E +, (1801) 05 +, (1802) 80 +. Het ingebouwde monitorprogramma maakt wijzigingen in geheugenplaatsen eenvoudig en ook het starten van een programma vanaf een bepaald adres en het instellen van breakpoints is mogelijk. Gebruikers die verder willen dan de voorbeelden moeten zich specialiseren in Z80 assembly, een drempel waar gegarandeerd niet iedere nieuwe eigenaar van de MPF-1 overheen wist te komen. De MPF-1 kwam met een handleiding met hierin de relevante delen van het Z80 databoek voor de vertaling van assembleertaal-instructies naar hexadecimale codes. Als de gebruiker de codes van de meegeleverde voorbeelden wist te combineren tot nieuwe programma’s was dat mooi meegenomen, maar het echte werk zat toch in het handmatig vertalen van assembleertaal naar machinetaalcode, aan de hand van handleiding, de Zilog Z80 CPU User’s Manual of een ander boek waarin de vertaling van Z80 assembleertaal naar machinecode staat gespecificeerd, zoals How to program the Z80 van Rodney Zaks.
De MPF-1 is een printplaat van 15 x 22 cm met hierop alle elektronische onderdelen, een 6 x 7 segment led display en een toetsenbord met 36 toetsen. Er is verder voorzien in aansluitingen voor een cassetterecorder, een luidspreker en twee statusleds. Op de printplaat is ruimte voor enkele zelf te solderen onderdelen en diverse IC-voeten zijn leeggelaten voor toekomstige uitbreidingen. Het toetsenbord is voorzien van commando’s voor het monitorprogramma dat in een 2716 EPROM op de printplaat is geplaatst, maar kan ook worden voorzien van een overlay als een programma een ander gebruik van het toetsenbord voorstaat. Een voorbeeld hiervan is de BASIC programmeertaal voor de MPF-1, waarvoor een ander gebruik van het toetsenbord is bedacht en dat met een kunststof folie met aangepaste toetsaanduidingen komt.
Het monitorprogramma was hetgeen de MPF-1 ‘gebruiksvriendelijk’ maakte: het zorgde ervoor dat programma’s in hexadecimaal via een goedwerkend toetsenbord ingevoerd konden worden en dat uitvoer via een led display of met een hoorbare toon gedaan kon worden. Het maakte programmeren al een stuk plezieriger, hoewel iedere assembleerinstructie nog steeds met de hand in een Z80 handboek opgezocht moest worden.
De handleiding van de MPF-1 introduceerde dat gegeven op laconieke wijze, getuige de volgende drie stukken tekst:
De oplettende lezer vraagt zich op dit moment af, hoe de assembleertaal-instructies met het toetsenbord van de MPF-1 ingevoerd moeten worden en zoekt op het toetsenbord vergeefs naar toetsen met de opdruk ORG, LD, ADD en HALT.
Hoewel het handmatig vertalen van assembleertaal naar machinetaalcodes (“machinecode”) voor een beetje puzzelaar niet heel complex met voldoende wilskracht te doen is, is hiervoor de Zilog Z80 CPU User’s Manual het handigst in het gebruik. Hierin is de vertaling van assembleertaal naar machinecode na te slaan, voor bijvoorbeeld LD A, 05. In dit handboek staat op pagina 82 hoe “laad register met vaste waarde”, ofwel LD r, n voor een gegeven register r en vaste waarde n moet worden vertaald naar machinecode:
De pagina beschrijft specifiek de situatie waarin een register met een constante waarde moet worden gevuld. Voor het vullen van een register met de inhoud van een ander register of met de inhoud van een geheugenadres zijn weer andere pagina’s met andere vertalingen. Maar kijkend naar deze pagina en bereid om het nodige aan puzzelwerk te doen: voor register A levert de vertaling 00111110 op (3E hexadecimaal), gevolgd door de vaste waarde 05. Samengesteld is dit 3E05. Voor register B levert de vertaling 00000110 op (06 hexadecimaal), gevolgd door de vaste waarde 04. Samengesteld is dit 0604.
Op pagina 140 van het Z80 handboek staat hoe “voeg de inhoud van een register toe aan register A”, ofwel ADD A, r voor een gegeven register r moet worden vertaald:
Voor register B levert de vertaling 10000000 op (80 hexadecimaal).
Op pagina 97 van het handboek staat hoe “het laden van de inhoud van register A in een geheugenadres”, ofwel LD (nn), A voor een vast geheugenadres nn naar machinecode moet worden vertaald:
Voor het geheugenadres 1830H, het beoogde adres waarin het resultaat van de optelling moet worden opgeslagen, levert dit de samenstelling 323018 op. Voor het adres is eerst het minst significante deel 30 gespecificeerd en hierna het meest significante deel 18, conform de beschrijving “The first n operand [..] is the low order byte of nn“. Deze constructie wordt ‘Little Endian’ genoemd. Andere processoren maken gebruik van ‘Big Endian’, een cultuurverschil die menig programmeerfout voor overstappende programmeurs heeft veroorzaakt, vertel ik uit eigen ervaring.
De instructie HALT vinden we op pagina 173 van het Z80 handboek en levert 76 hexadecimaal op.
Het gehele vertaalde programma ziet er dan als volgt in machinecode uit, gerepresenteerd door hexadecimale getallen:
Het invoeren van de machinecode in de Z80 microprocessor van de MPF-1 is de derde stap in de handleiding, waarin dit in combinatie met het gebruik van het toetsenbord en het led display wordt uitgelegd:
Voor de gebruiker van de MPF-1 betekende het invoeren van het programma de volgende handelingen (getallen tussen haakjes geven weergaves op het display aan en vetgedrukte teksten zoals ADDR de in te drukken toetsen of in te voeren getallen):
ADRR 1800 (00)
ADDR1800DATA
(1800) 3E+
(1801) 05+
(1802) 06+
(1803) 04+
(1805) 80+
(1806) 32+
(1807) 30+
(1808) 18+
(1809) 76
RS ADDR 1800 GO
ADDR 1830 (09)
Het zelf vertalen van de assembleertaal-instructies uit de voorbeelden naar machinecode is een leerzaam proces, die zal helpen bij het begrijpen van het gebruik van de gekozen instructies, het werken met registeres en geheugen en het omgaan met de statusbits van de processor. Hoewel ik mijn carrière in het programmeren van microprocessoren niet met de MPF-1 ben begonnen, herinner ik me nog wel de periode waarin het me begon te dagen dat de ene instructie meer cycli (verwerkingstijd) in beslag neemt dan de andere. Je vindt deze informatie bij iedere instructie in de Z80 User’s Manual onder het kopje M Cycles. Omdat sommige instructies in een programma vaak herhaald worden, maakt het in die gevallen nogal een verschil of een instructie 2 of 1 cycli in beslag neemt.
Een ander voordeel van het zelf opnieuw vertalen van de voorbeelden is dat na enige tijd de vertaling ook zonder handboek lukt: de machinecode bij de meestgebruikte instructies maken dan onderdeel uit van je eigen werkgeheugen.
De aantrekkingskracht van programmeren in assembleertaal (“assembly“) op een single board computer zoals de MPF-1 is moeilijk uit te leggen. Er speelt in elk geval mee dat je dicht bij de elektronica, de hardware van de computer bezig bent. Die computerhardware heeft een heel simpele besturingslogica, waarbij je zelf maximaal oplossingsgericht en creatief bezig moet zijn om complexe oplossingen in kleine stappen op te bouwen. Je bestuurt met de assembleertaal de vulling van het werkgeheugen en aansturing van hardware zoals het display. Niet alleen zie je die elektronica voor je, je ervaart ook de elektronische opbouw van de processor. Want immers, iedere vertaling van instructie naar code reflecteert de bits die straks in de processor bepaalde delen van de interne digitale schakelingen zullen activeren. In gedachten zie je de program counter naar het geheugenadres met de volgende instructie wijzen, de instruction decoder bepalen wat met die instructie te doen, de arithmetic logic unit de bewerking uitvoeren en het resultaat terug in één van de registers plaatsen en een fractie van een seconde later zie je een resultaat op het scherm. Of niet, en dan begint het debuggen, het stap voor stap in gedachten uitvoeren van het programma om te zien waar je een denkfout hebt gemaakt. Machtig mooi allemaal, en de MPF-1 is absoluut die ‘unieke leer- en experimenteercomputer’ die je daarvoor nodig hebt.
Sciento, de Nederlandse importeur van de MPF-1, gebruikte later de printplaat uit de boekomslag van de Micro-Professor voor hun eigen Teach Pendant CS-113, een besturingscomputer voor hun robot arm CS-113. De EPROM was in deze Teach Pendant door Sciento voorzien van een speciaal programma om de robot arm bewegingen te laten maken en te laten herhalen. Een toetsenbord overlay maakte het apparaat compleet. Het geheel was in een stevige aluminium kast ingebouwd met een voedingsaansluiting en een parallelle poort waarop de robot arm werd aangesloten.
Vrij snel na de introductie in 1981 kwam Multitech uit met een BASIC interpreter in een 2K EPROM, die naast de EPROM met het monitorprogramma in een lege IC voet werd geplaatst. Een overlay over het toetsenbord werd meegeleverd en ook de handleiding, met alweer veel voorbeelden, was prima in orde.
Met de MPF-1 BASIC konden programma’s zoals onderstaande worden geschreven:
100 FOR L = 0 TO 9
110 PRINT "IN THE LOOP", L
130 NEXT L
140 PRINT "OUT OF THE LOOP"
De MPF-1 BASIC is een directe afgeleide van Tiny BASIC die vanaf 1976 voor een keur van processoren beschikbaar was. Omdat de Tiny BASIC programmeertaal maar weinig woorden kent en deze woorden toch al als enkele ’token’ in het geheugen van de computer worden opgeslagen, zochten veel computerbouwers naar manieren om met een enkele toets een geheel BASIC woord in te kunnen voeren, zo ook bij de MPF-1. De overlay laat een volledig overzicht van BASIC instructies zien, die door op de betreffende toets te drukken in z’n geheel werden ingevoerd. Dit had twee voordelen: de beschikbare commando’s waren altijd te zien en hoefden vervolgens niet helemaal letter-voor-letter ingetoetst te worden. De commando’s SAVE, CONT, LIST, NEW, LOAD, RUN en ENTER zijn geen programmeerinstructies, maar middelen om programma’s in z’n geheel te laden van of bewaren op cassetteband, een programma te starten, te ‘listen’, of een afgebroken programma te hervatten.
In 1989 was Sciento uit ’s Hertogenbosch een bekende naam op de technische Hogescholen en Universiteiten. In hun portfolio zat onder meer lesmateriaal op het gebied van digitale elektronica, computertechniek en robotica. Bijzonder van het lesmateriaal was dat het allemaal robuust was uitgevoerd en dat je er hele klassen vol technisch onderlegde jongelui hun gang mee kon laten gaan. Mooi was dat. En nu heb ik twee van die historische producten op de kop kunnen tikken: een ‘Robotic Training Arm CS-113’ en een ‘Teach Pendant CS-113’. Die laatste is voor mij, in een andere vorm welliswaar, heel bekend. Ik heb letterlijk honderden uren doorgebracht met het handmatig compileren van Zilog Z80 machinecode op diverse computers (met Rodney Zaks op tafel) en de Micro Professor was daar eentje van. Sciento, die in Nederland ook al importeur was van de MPF-1, heeft daar een stevige metalen doos omheen gefabriceerd, er een eigen EPROM met de robotarm besturingssoftware in geplaatst en het toetsenbord voorzien van een overlay met instructies voor de bediening van de verschillende assen van de robotarm.
Stel je voor, je loopt de zaal uit waar je net een presentatie hebt gevolgd en ziet op een tafeltje twee apparaten staan in het rood en groen. Beide hebben een verlichte knop aan de bovenkant, die uitnodigend pulserend verlicht is. Op het display zie je wat cijfers staan. Een poster aan de muur bevat de tekst ‘Evaluatie – Uw mening wordt op prijs gesteld’ en de kreet ‘Gebruik de Like-O-Meters hieronder’. Met een druk op de knop van de groene kolom kun je aangeven dat je de presentatie leuk vond, met een druk op de knop van de rode kolom geef je juist aan dat je het maar niks vond.
Dit is wat ik voor ogen had toen ik met project Meningteller begon. De zichtbare functionaliteit ervan is relatief simpel: een verlichte schakelaar aan de bovenkant, een display dat bij iedere druk op de knop één optelt en een stevige behuizing die ook bij intensief gebruik overeind blijft. Ik heb ze ‘Like-O-Meter’ gedoopt, een knipoog naar de ‘Like‘ knop die je van Facebook kent (‘Vind ik leuk’). Maar ‘Meningteller’ is eigenlijk leuker, want Nederlands.
Omdat het project gestalte moest krijgen tussen lunch en diner heb ik in in huis rondgezocht om te zien wat er aan materialen zouden kunnen passen. Ik had recentelijk wat PVC materialen ingekocht voor een uitbreiding aan de badkamer en daar nog wat van overgehouden. Daar zat net voldoende materiaal bij om twee gesloten ‘bussen’ te maken. En PCV laat zich gemakkelijk boren en zagen, dat hielp in de besluitvorming.
Aan de softwarekant moest ik wat improviseren om het geheel met een ATtiny85 aan de gang te krijgen. De ATtiny is een kleine 8-pins microcontroller, met 6 pennen vrij te gebruiken voor I/O toepassingen, zoals het inlezen van de stand van een schakelaar, het activeren van een led of het serieel aansturen van een led display. Het led display gebruikt hiervan twee (I2C clock en I2C data), de schakelaar gebruikt er één en de led in de schakelaar ook één. Er zijn nog twee pennen vrij, voor bijvoorbeeld een rgbled in de schakelaar.
Voor de I2C communicatie heb ik gebruik gemaakt van de TinyWireM library van Bro Hogan, die met 320 bytes een veel kleinere footprint heeft dan de AdaFruit led Backpack library. De ATtiny85 heeft ruimte voor 8K gecompileerde programmatuur, hiervan gebruikt de Like-O-Meter iets meer dan 4K. De Arduino ontwikkelomgeving 1.01 heeft een fout die het gebruik van meer ruimte dan 4K voorkomt, dat was nog wel een uitzoekklusje. De broncode bevat aanwijzigingen voor het hercompileren en de benodigde codebibliotheken.
Het gedrag van de Like-O-Meter is als volgt. Zodra de 9 volt accu wordt ingeschakeld (de onderkant schroeft eenvoudig van de behuizing en de accu zit met een clipje vast) toont het display vier streepjes en wordt de led in de schakelaar een seconde ontstoken. Hierna wordt een ‘0’ op het display getoond en is de led in de schakelaar uit. Iedere keer als de schakelaar wordt ingedrukt brandt de led en toont het display de tekst ‘PLUS’. Als de schakelaar weer wordt losgelaten toont het display opnieuw het getal, dat nu met één is verhoogd.
Na ongeveer 15 minuten inactiviteit wordt het display wat gedimd en pulseert de led om de naderende slaapstand aan te kondigen. Een druk op de schakelaar levert het normale tel-er-een-bij-op gedrag en de slaapstand wordt onderbroken. Als er echter niet op de schakelaar wordt gedrukt dan gaat het display na een minuut uit. Het stroomverbruik is nu minimaal (ca. 7mA), maar de telstand wordt wel behouden. Als de schakelaar wordt ingedrukt dan wordt de tekst ‘AAN’ op het display getoond. Zodra de schakelaar nu wordt losgelaten dan toont het display de oude telstand en is de Like-O-Meter weer klaar voor gebruik. Om de telstand te wissen moet de accu (9 volt blokbatterij) worden losgekoppeld. Het stroomverbruik is sterk afhankelijk van het gebruik: met ‘8888’ op het display is de opgenomen stroom ongeveer 80mA. Bij regulier gebruik gaan de accu’s ongeveer 7 dagen mee.
De software is Public Domain, doe ermee wat je goed dunkt 🙂
/*
* Like-O-Meter firmware 1.00
* Copyright (c) 2013 Rudi Niemeijer
* Placed in the Public Domain
*
* This is the firmware for the Like-O-Meter, a device that
* acts as a counter with some light effects.
*
* A Like-O-Meter contains an Adafruit 4-digit 7-segment
* LED backpack, button with built-in LED and an ATtiny85.
*
* In order to compile, this firmware requires the TinyWireM
* library for I2C communication and the Tiny_LEDBackpack
* library for the various LED display functions.
*
* TinyWireM library obtained from http://www.scenelight.nl/?wpfb_dl=22
* Tiny_LEDBackpack obtained from https://github.com/millerlp/Tiny_LEDBackpack
*
* ATtiny pin configuration
* Pin 1 - Not connected
* Pin 2 - Not connected (ATtiny PIN 3)
* Pin 3 - Button (ATtiny PIN 4)
* Pin 4 - GND
* Pin 5 - SDA to LED backpack (grey)
* Pin 6 - LED in button (ATtiny PIN 1 w. PWM)
* Pin 7 - SCL to LED backpack (white)
* Pin 8 - VCC/+5V
*
*/// These two libraries are essential#include <TinyWireM.h>#include <Tiny_LEDBackpack.h>
Tiny_7segment likeOMeterDisplay = Tiny_7segment();int buttonPin =4;// button that pulls the pin UPint ledPin =1;// indicator LED inside the button, pin 1 supports PWMint buttonState;// current state of the buttonint counterValue =0;// current value for the counter#define maxLEDBrightness 150 // maximum LED brightness 0..255#define maxLEDBrightnessFade 75 // maximum LED brightness in fade mode#define fadeSpeed 10 // increase LED brightness every fadeSpeed millis#define napTimeOut 900000 // millis before sleep, 15 minutes#define sleepTimeOut 960000 // millis before hybernation, 15 minutes + 60 seconds int currentLEDBrightness =0;int brighter =true;unsignedlong timeStampButtonPressed;unsignedlong timeStamp =0;#define i2c_addr 0x70 // stock address for Adafruit 7-segment LED backpackvoid setup(){
pinMode(buttonPin, INPUT);
pinMode(ledPin, OUTPUT);
analogWrite(ledPin, maxLEDBrightness);
likeOMeterDisplay.begin(i2c_addr);// initialize HT16K33 controller
likeOMeterDisplay.clear();// clear all digits on display
likeOMeterDisplay.setBrightness(15);// set maximum display brightness
likeOMeterDisplay.writeDigitRaw(0,64);// dash on position 0
likeOMeterDisplay.writeDigitRaw(1,64);// dash on position 1
likeOMeterDisplay.writeDigitRaw(3,64);// dash on position 3
likeOMeterDisplay.writeDigitRaw(4,64);// dash on position 4
likeOMeterDisplay.writeDisplay();// push data to display
delay(1000);// wait a second
likeOMeterDisplay.clear();// clear all digits on display
displayInteger(counterValue);
analogWrite(ledPin,0);// disable the LED for visual verification
timeStampButtonPressed = millis();// simulate button pressed to prevent nap and sleep right from the beginning}void loop(){
buttonState = digitalRead(buttonPin);// NAP MODE TO ATTRACT ATTENTIONif((millis()> timeStampButtonPressed + napTimeOut)&&(millis()> timeStamp + fadeSpeed)){
timeStamp = millis();if(currentLEDBrightness ==0){
likeOMeterDisplay.setBrightness(0);
likeOMeterDisplay.writeDisplay();}
analogWrite(ledPin, currentLEDBrightness);if(brighter){
currentLEDBrightness++;if(currentLEDBrightness > maxLEDBrightnessFade){
currentLEDBrightness = maxLEDBrightnessFade;
brighter =false;}}else{
currentLEDBrightness--;if(currentLEDBrightness <0){
currentLEDBrightness =0;
brighter =true;}}}// SLEEP MODE TO PREVENT BATTERY DEPLETIONif((currentLEDBrightness ==0)&&(millis()> timeStampButtonPressed + sleepTimeOut))// button not pressed for a very long time{// Sleep
likeOMeterDisplay.clear();// replace this with actual battery preserving code, like switching off
likeOMeterDisplay.writeDisplay();
digitalWrite(ledPin,0);while(!digitalRead(buttonPin))// wait here until button is pressed{}// Wakeup
likeOMeterDisplay.setBrightness(15);
likeOMeterDisplay.writeDigitRaw(0,119);// A on position 0
likeOMeterDisplay.writeDigitRaw(1,119);// A on position 1
likeOMeterDisplay.writeDigitRaw(3,55);// N on position 3
likeOMeterDisplay.writeDigitRaw(4,0);// blank on position 4
likeOMeterDisplay.writeDisplay();// push data to display
delay(1000);// wait a second
likeOMeterDisplay.clear();// clear all digits on display
displayInteger(counterValue);while(digitalRead(buttonPin))// wait here until button is released{}
timeStampButtonPressed = millis();}if(buttonState)// button is pressed{
analogWrite(ledPin, maxLEDBrightness);
likeOMeterDisplay.setBrightness(15);
likeOMeterDisplay.writeDisplay();
counterValue +=1;
likeOMeterDisplay.clear();
likeOMeterDisplay.writeDisplay();
likeOMeterDisplay.writeDigitRaw(0,115);// P on position 0
likeOMeterDisplay.writeDigitRaw(1,56);// L on position 1
likeOMeterDisplay.writeDigitRaw(3,62);// U on position 3
likeOMeterDisplay.writeDigitRaw(4,109);// S on position 4
likeOMeterDisplay.writeDisplay();
delay(250);// debounce timewhile(digitalRead(buttonPin))// wait here until button is released{}
delay(250);// debounce time
displayInteger(counterValue);
analogWrite(ledPin,0);
currentLEDBrightness =0;
brighter =true;// nap light is increasing first
timeStampButtonPressed = millis();// administer last time button pressed}}void displayInteger(int number){if(number ==0){
likeOMeterDisplay.writeDigitRaw(4,63);// put a zero on the display}else{
likeOMeterDisplay.print(number);// put the number on the display}
likeOMeterDisplay.writeDisplay();}
/*
* Like-O-Meter firmware 1.00
* Copyright (c) 2013 Rudi Niemeijer
* Placed in the Public Domain
*
* This is the firmware for the Like-O-Meter, a device that
* acts as a counter with some light effects.
*
* A Like-O-Meter contains an Adafruit 4-digit 7-segment
* LED backpack, button with built-in LED and an ATtiny85.
*
* In order to compile, this firmware requires the TinyWireM
* library for I2C communication and the Tiny_LEDBackpack
* library for the various LED display functions.
*
* TinyWireM library obtained from http://www.scenelight.nl/?wpfb_dl=22
* Tiny_LEDBackpack obtained from https://github.com/millerlp/Tiny_LEDBackpack
*
* ATtiny pin configuration
* Pin 1 - Not connected
* Pin 2 - Not connected (ATtiny PIN 3)
* Pin 3 - Button (ATtiny PIN 4)
* Pin 4 - GND
* Pin 5 - SDA to LED backpack (grey)
* Pin 6 - LED in button (ATtiny PIN 1 w. PWM)
* Pin 7 - SCL to LED backpack (white)
* Pin 8 - VCC/+5V
*
*/
// These two libraries are essential
#include <TinyWireM.h>
#include <Tiny_LEDBackpack.h>
Tiny_7segment likeOMeterDisplay = Tiny_7segment();
int buttonPin = 4; // button that pulls the pin UP
int ledPin = 1; // indicator LED inside the button, pin 1 supports PWM
int buttonState; // current state of the button
int counterValue = 0; // current value for the counter
#define maxLEDBrightness 150 // maximum LED brightness 0..255
#define maxLEDBrightnessFade 75 // maximum LED brightness in fade mode
#define fadeSpeed 10 // increase LED brightness every fadeSpeed millis
#define napTimeOut 900000 // millis before sleep, 15 minutes
#define sleepTimeOut 960000 // millis before hybernation, 15 minutes + 60 seconds
int currentLEDBrightness = 0;
int brighter = true;
unsigned long timeStampButtonPressed;
unsigned long timeStamp = 0;
#define i2c_addr 0x70 // stock address for Adafruit 7-segment LED backpack
void setup()
{
pinMode(buttonPin, INPUT);
pinMode(ledPin, OUTPUT);
analogWrite(ledPin, maxLEDBrightness);
likeOMeterDisplay.begin(i2c_addr); // initialize HT16K33 controller
likeOMeterDisplay.clear(); // clear all digits on display
likeOMeterDisplay.setBrightness(15); // set maximum display brightness
likeOMeterDisplay.writeDigitRaw(0, 64); // dash on position 0
likeOMeterDisplay.writeDigitRaw(1, 64); // dash on position 1
likeOMeterDisplay.writeDigitRaw(3, 64); // dash on position 3
likeOMeterDisplay.writeDigitRaw(4, 64); // dash on position 4
likeOMeterDisplay.writeDisplay(); // push data to display
delay(1000); // wait a second
likeOMeterDisplay.clear(); // clear all digits on display
displayInteger(counterValue);
analogWrite(ledPin, 0); // disable the LED for visual verification
timeStampButtonPressed = millis(); // simulate button pressed to prevent nap and sleep right from the beginning
}
void loop()
{
buttonState = digitalRead(buttonPin);
// NAP MODE TO ATTRACT ATTENTION
if ((millis() > timeStampButtonPressed + napTimeOut) && (millis() > timeStamp + fadeSpeed))
{
timeStamp = millis();
if (currentLEDBrightness == 0)
{
likeOMeterDisplay.setBrightness(0);
likeOMeterDisplay.writeDisplay();
}
analogWrite(ledPin, currentLEDBrightness);
if (brighter)
{
currentLEDBrightness++;
if (currentLEDBrightness > maxLEDBrightnessFade)
{
currentLEDBrightness = maxLEDBrightnessFade;
brighter = false;
}
}
else
{
currentLEDBrightness--;
if (currentLEDBrightness < 0)
{
currentLEDBrightness = 0;
brighter = true;
}
}
}
// SLEEP MODE TO PREVENT BATTERY DEPLETION
if ((currentLEDBrightness == 0) && (millis() > timeStampButtonPressed + sleepTimeOut)) // button not pressed for a very long time
{
// Sleep
likeOMeterDisplay.clear(); // replace this with actual battery preserving code, like switching off
likeOMeterDisplay.writeDisplay();
digitalWrite(ledPin, 0);
while (!digitalRead(buttonPin)) // wait here until button is pressed
{
}
// Wakeup
likeOMeterDisplay.setBrightness(15);
likeOMeterDisplay.writeDigitRaw(0, 119); // A on position 0
likeOMeterDisplay.writeDigitRaw(1, 119); // A on position 1
likeOMeterDisplay.writeDigitRaw(3, 55); // N on position 3
likeOMeterDisplay.writeDigitRaw(4, 0); // blank on position 4
likeOMeterDisplay.writeDisplay(); // push data to display
delay(1000); // wait a second
likeOMeterDisplay.clear(); // clear all digits on display
displayInteger(counterValue);
while (digitalRead(buttonPin)) // wait here until button is released
{
}
timeStampButtonPressed = millis();
}
if (buttonState) // button is pressed
{
analogWrite(ledPin, maxLEDBrightness);
likeOMeterDisplay.setBrightness(15);
likeOMeterDisplay.writeDisplay();
counterValue += 1;
likeOMeterDisplay.clear();
likeOMeterDisplay.writeDisplay();
likeOMeterDisplay.writeDigitRaw(0,115); // P on position 0
likeOMeterDisplay.writeDigitRaw(1,56); // L on position 1
likeOMeterDisplay.writeDigitRaw(3,62); // U on position 3
likeOMeterDisplay.writeDigitRaw(4,109); // S on position 4
likeOMeterDisplay.writeDisplay();
delay(250); // debounce time
while (digitalRead(buttonPin)) // wait here until button is released
{
}
delay(250); // debounce time
displayInteger(counterValue);
analogWrite(ledPin, 0);
currentLEDBrightness = 0;
brighter = true; // nap light is increasing first
timeStampButtonPressed = millis(); // administer last time button pressed
}
}
void displayInteger(int number)
{
if (number == 0)
{
likeOMeterDisplay.writeDigitRaw(4, 63); // put a zero on the display
} else
{
likeOMeterDisplay.print(number); // put the number on the display
}
likeOMeterDisplay.writeDisplay();
}
Op de Open Dag van de Jonge Onderzoekers zagen zoon Kars Jan en ik een leuke vinding: een soort radio-ontvanger-met-koptelefoontje dat allerlei elektromagnetische straling hoorbaar maakt. Die wilden we zelf ook wel maken! Snel een foto gemaakt. De schakeling van de Jonge Onderzoekers was heel klassiek opgebouwd op een plaatje hout, waarbij de onderdelen op punaises waren vastgesoldeerd. Zonder twijfel was er eerst een schakeling op papier ontworpen, waarbij de punaises op de verbindingspunten van de papieren schakeling waren geplaatst en de onderdelen één voor één netjes op de plaats gemonteerd.
De mannen van de Jonge Onderzoekers hadden niet een schema voorhanden en vonden het wel een leuk idee om me uit te dagen er zelf een schema van te tekenen. U vraagt, wij draaien. Nadat ze me met een papiertje en pen de schakeling zagen ontwarren begrepen ze wel dat ik dit niet voor het eerst deed en ze waren daarna uiterst behulpzaam om zeker te weten dat ik alle onderdelen van verbindingen op het schema had meegenomen. Dank hiervoor!
Typisch het soort schakeling dat je als eerstejaars elektronicus voor je kiezen krijgt en ik was zelf dan ook niet onder de indruk. Voor Kars Jan ging er echter letterlijk een nieuwe wereld open en om hem een pleziertje te doen heb ik de getekende schakeling opgebouwd en in een doosje gemonteerd. De antenne is een stukje montagedraad van ongeveer 30 centimeter en de hoofdtelefoon wordt met een 3,5mm stereo chassisdeel verbonden met het circuit. Een kleine drukschakelaar zorgt ervoor dat het apparaatje niet de hele dag aan blijft staan, na gebruik.
Het hele circuit is eigenlijk niets meer dan een uit drie transistoren bestaande versterkerschakeling, die de door de draadantenne opgevangen en de germanium-dioden gediscrimineerde radiosignalen geschikt maakt voor audio-weergave. De stroomopname is minimaal en de hele schakeling kost nog geen 10 euro, inclusief een lowbudget hoofdtelefoon, een geschikt doosje en een stukje gaatjesprint. Het uittekenen van de schakeling, bouwen en afmonteren was een fluitje van een cent, een briljante investering voor zo’n leuk stukje speelgoed.
De oorspronkelijke bron van de schakeling is mogelijk Veron, die een sterk gelijkend ontwerp op haar website heeft staan. Ook Elektuur heeft in elk geval twee varianten gepubliceerd.
Het is weer herfst geworden. Een heerlijke tijd van het jaar, met een aantal traditionele evenementen zoals kastanjeszoeken en het controleren van de fietsverlichting. De achterlichten van onze beide kinderen zijn van het handmatige type en hoewel het veel goedkoper niet al te duur is om deze door een kant-en-klare automatische, zelfaanschakelende lamp te vervangen, ging me dat deze keer te ver.
LED fietsachterlichten Een standaard fietsachterlicht met LED bestaat uit twee penlite-batterijen, een schakelaar, één of meer LED’s met wat weerstanden. De fietseigenaar schakelt de verlichting in met de schakelaar en schakelt deze na gebruik weer uit. Wat ik graag wil, is dat de fietseigenaar de fietsachterlicht wel inschakelt, maar dat dit achterlicht zelf de LED’s aanzet als dat nodig is. En het is pas nodig als er onvoldoende omgevingslicht is, én de fiets in beweging is. Ik heb enkele goedkope LED-fietsachterlichten gekocht. Hierin zitten 2 penlight-batterijen en 3 LED’s met elk een serieweerstand van 390 ohm. De 3 LED’s gebruiken gezamenlijk 70 mA.
Beetje Arduino, beetje Processing, beetje ISP Uit de vorige jaren heb ik nog wat Arduino-spullen verzameld. Dit is allemaal te groot (en te duur) voor een fietsachterlicht, maar Atmel, de fabrikant van de microcontrollers die ook voor de Arduino’s worden gebruikt, heeft kleine chips op de markt die de ATtiny heten. Deze is er ondermeer in een 8-pins behuizing, met 5 universele I/O pennen, 8K aan flash-programmageheugen en 512 bytes werkgeheugen (de “ATtiny85”). En met een beetje moeite programmeerbaar met een Arduino, die zich voor die gelegenheid als “In Circuit Programmer” gedraagt. In dezelfde Processing taal als voor de Arduino geschikt is. En, belangrijk, de ATtiny85 is voor minder dan een euro te verkrijgen.
Sensoren Om vast te stellen dat er onvoldoende omgevingslicht beschikbaar is, is een LDR prima geschikt. De ATtiny85 kan de weerstand hiervan inlezen met een analoge ingangspin. Een tiltschakelaar gedraagt zich als een soort bewegingssensor, prima te detecteren met een digitale ingangspin. En de LED’s kunnen, middels een transistor met open collector, met een digitale uitgangspin worden geschakeld (deze digitale pinnen kunnen maximaal 40 mA aansturen, nipt te weinig voor de benodigde 70 mA, vandaar de transistor). Kortom: het hele circuit gaat bestaan uit de volgende onderdelen:
ATtiny85 als regelneef
LDR voor het meting van omgevingslicht
Tiltschakelaar voor het bepalen van beweging
BC547 transistor voor het aansturen van de LED’s
Enkele weerstanden
De bestaande onderdelen: batterijen, schakelaar, LED’s
Het schema hieronder laat zien, dat de ATtiny85 het hart vormt van een schakeling waarin verder een tilt-schakelaar (horizontaal installeren zodat bij beweging van de fiets steeds het contact “stuitert”), een lichtgevoelige weerstand en een transistor zijn opgenomen. De LED’s en bijbehorende serieweerstanden, de batterijen en de schakelaar S1 zijn onderdeel van de bestaande achterlamp. Het geheel past op een stukje gaatjesprint van 3 x 3 centimeter.
Het leukst is natuurlijk, om hier een eigen stukje software voor te schrijven. Immers, dat opent de deur naar een persoonlijke noot. Ik heb ervoor gekozen om bij het aanschakelen van het achterlight de lamp even 3 keer te laten knipperen. Op die manier is het goed vast te stellen dat de elektronica het doet.
/*
Bicycle automatic tail light
Placed in the public domain
Written by Rudi Niemeijer (10-2012)
Switches an LED based on light conditions
_______
RESET ADC0 PB5 x|1 ^ 8|x VCC (+)
PWM ADC3 PB3 x|2 7|x PB2 ADC1
PWM ADC2 PB4 x|3 6|x PB1 PWM
(-) GND x|4_____5|x PB0 PWM
*/// Some constant valuesint ledPin =0;// Digital Output PB0 (also PWM), AtTiny85 pin 5int ldrPin =3;// Analog Input ADC3, AtTiny85 pin 2 int numberOfResamples =10;// Light value is average of this many samplesint treshold =80;// Light below this value will make the LED go onint measuredLightValue;// Contains the actual light measurement from the LDRint resetCounter;// It has to be light this many cycles before light switches offvoid flashLed(int numTimes){// Flash the LED numTimesfor(int i =0; i < numTimes; i++){
digitalWrite(ledPin, HIGH);// turn the LED on (HIGH is the voltage level)
delay(200);// wait for a second
digitalWrite(ledPin, LOW);// turn the LED off by making the voltage LOW
delay(100);// wait for a second}}int readLdr(){int analogValue;
analogValue = analogRead(ldrPin);return analogValue;}void burstLed(){for(int i =0; i <25; i++){
digitalWrite(ledPin, HIGH);
delay(25);
digitalWrite(ledPin, LOW);
delay(25);}}void setup(){
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
resetCounter =10;
flashLed(3);}// the loop routine runs over and over again forever:void loop(){
measuredLightValue =0;for(int i =0; i < numberOfResamples; i++){
measuredLightValue = measuredLightValue + readLdr();}
measuredLightValue = measuredLightValue / numberOfResamples;if(measuredLightValue < treshold){
resetCounter =10;
digitalWrite(ledPin, HIGH);}else{
resetCounter--;if(resetCounter ==0){
burstLed();
digitalWrite(ledPin, LOW);}}
delay(500);// Do nothing for half a second// This means it has to be light AT LEAST 10 * 500 ms before light switches on}
/*
Bicycle automatic tail light
Placed in the public domain
Written by Rudi Niemeijer (10-2012)
Switches an LED based on light conditions
_______
RESET ADC0 PB5 x|1 ^ 8|x VCC (+)
PWM ADC3 PB3 x|2 7|x PB2 ADC1
PWM ADC2 PB4 x|3 6|x PB1 PWM
(-) GND x|4_____5|x PB0 PWM
*/
// Some constant values
int ledPin = 0; // Digital Output PB0 (also PWM), AtTiny85 pin 5
int ldrPin = 3; // Analog Input ADC3, AtTiny85 pin 2
int numberOfResamples = 10; // Light value is average of this many samples
int treshold = 80; // Light below this value will make the LED go on
int measuredLightValue; // Contains the actual light measurement from the LDR
int resetCounter; // It has to be light this many cycles before light switches off
void flashLed(int numTimes) { // Flash the LED numTimes
for (int i = 0; i < numTimes; i++) {
digitalWrite(ledPin, HIGH); // turn the LED on (HIGH is the voltage level)
delay(200); // wait for a second
digitalWrite(ledPin, LOW); // turn the LED off by making the voltage LOW
delay(100); // wait for a second
}
}
int readLdr() {
int analogValue;
analogValue = analogRead(ldrPin);
return analogValue;
}
void burstLed() {
for (int i = 0; i < 25; i++) {
digitalWrite(ledPin, HIGH);
delay(25);
digitalWrite(ledPin, LOW);
delay(25);
}
}
void setup() {
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
resetCounter = 10;
flashLed(3);
}
// the loop routine runs over and over again forever:
void loop() {
measuredLightValue = 0;
for (int i = 0; i < numberOfResamples; i++) {
measuredLightValue = measuredLightValue + readLdr();
}
measuredLightValue = measuredLightValue / numberOfResamples;
if (measuredLightValue < treshold) {
resetCounter = 10;
digitalWrite(ledPin, HIGH);
} else {
resetCounter--;
if (resetCounter == 0) {
burstLed();
digitalWrite(ledPin, LOW);
}
}
delay(500); // Do nothing for half a second
// This means it has to be light AT LEAST 10 * 500 ms before light switches on
}
Slotwoord Het maken van een zelfschakelend achterlicht is ook voor een minder ervaren hobbyist eenvoudig genoeg te doen. Het is niet moeilijk. Maar het kost wat tijd om de ontwikkelstraat op poten te zetten. Als je eenmaal de smaak te pakken hebt om een ATtiny wat willekeurig eenvoudig regelwerk te laten doen, dan zijn de mogelijkheden onbeperkt.
In het schema heb ik ervoor gekozen om geen basisweerstand bij de transistor te gebruiken. Dat is niet zoals het hoort: de basisweerstand beperkt de collectorstroom door de transistor. Zonder basisweerstand wordt de stroom echter beperkt door de weerstanden R1..R3, waardoor er geen ongewenste situaties kunnen ontstaan.
In het schema is ook een tiltschakelaar te zien, die ik niet in de praktische schakeling en evenmin in de software heb toegepast. Het idee hiervan is, om gebruik te maken van de wetenschap dat een fiets in beweging is. Dat zou helpen om een fietslicht aan te laten bij (tijdelijk) lichte omstandigheden. Geen gebruik van gemaakt.
De elektrische installatie van ieder huis in Nederland begint met een hoofdzekering, gevolgd door een elektriciteitsmeter. Deze zekering en meter zijn eigendom van de elektriciteitsleverancier. Op de meter is een groepenkast aangesloten, van waaruit het huis groepsgewijs van elektriciteit wordt voorzien. Het wijzigen of uitbreiden van de groepen is niet al te moeilijk, maar er zijn wat regels die gevolgd moeten worden.
Vanaf de groepenkast Boven de elektriciteitsmeter bevindt zich de groepenkast. Iedere groep kan maximaal 16A leveren. In principe heeft iedere ruimte in huis een groep. Er zijn echter uitzonderingen. Ruimten die aan elkaar grenzen mogen samen op een groep en sommige zware verbruikers (oven, boiler, wasdroger) moeten een eigen groep. Het uitbreiden van de groepenkast (plaatsen van een extra groep bijvoorbeeld) mag door iemand die ’terzake kundig is’, het plaatsen van een geheel nieuwe groepenkast is werk voor een erkend installateur.
Normaaldozen, centraaldozen en aarding
Vroeger maakte men gebruik van een normaaldozensysteem: elektrische leidingen werden over de muren heen, meestal in het zicht, doorgelust. Voor iedere uitbreiding werd een verbindingsdoosje in een bestaande leiding opgenomen. Dit systeem wordt niet meer toegepast en is vervangen door een centraaldozensysteem, waarbij in het midden van een ruimte in de vloer of het plafond een grote doos is ingebouwd, vanuit waar alle aansluitpunten zijn bedraad. Sinds 1997 is het verplicht om iedere nieuwe wandcontactdoos te voorzien van randaarde. Verbindingen in de elektrische installatie worden gemaakt met installatiedraad met een massieve koperen kern van 2,5mm² (1,5mm² voor draden die tussen een schakelaar en een lichtpunt lopen).
Aansluitpunten Vanuit de groepenkast lopen installatiebuizen. In elk van deze buizen zitten de drie draden van precies één groep: groen/geel, blauw en bruin. De buizen lopen naar de centraaldoos in de ruimte waar deze groep voor is bedoeld. Vanuit de centraaldoos loopt een installatiebuis naar iedere wandcontactdoos, schakelaar of lichtpunt. Hieronder de kleuren draden voor ieder aansluitpunt:
Wandcontactdoos: groen/geel, bruin, blauw
Enkelvoudige schakelaar: bruin, zwart
Wisselschakelaar: bruin, zwart, zwart
Lichtpunt: blauw, zwart
In de centraaldoos worden de juiste verbindingen gemaakt middels geveerde contactblokjes zodat wandcontactdozen van stroom worden voorzien en lichtpunten (al dan niet met een hotelschakeling) kunnen worden geschakeld.
Kleuren, functies en diameters Er worden vier kleuren installatiedraad gebruikt: geel/groen, bruin, blauw en zwart. Iedere kleur heeft zijn eigen functie:
Geel/groen: dit is de aardingsdraad die is verbonden met een aardpin in de meterkast. De aardpin is een koperen staaf die enkele meters in de grond is geslagen en op dit manier verbinding maakt met de aarde. De aardingsdraad wordt gebruikt om elektrocutie tegen te gaan. Vroeger werd de aardingsdraad verbonden met de (koperen) waterleiding maar omdat tegenwoordig veel kunststof waterleidingen worden gebruikt, is meestal een aardpin in de meterkast nodig. In sommige installaties is de aardedraad als een zilverkleurige draad in het zicht gemonteerd. In oudere installaties is een aardingsdraad grijs.
Bruin: dit is de fasedraad, in schema’s aangeduid met L, die de elektrische stroom aanvoert. Als een elektrische installatie goed is aangelegd dan is de fasedraad de enige draad die onder spanning staat. In oudere installaties is een fasedraad groen.
Blauw: dit is de nuldraad, aangeduid met N, die de elektrische stroom weer afvoert. In oudere installaties is een nuldraad rood.
Zwart: dit is een schakeldraad bedoeld voor een lichtpunt. Een zwarte draad wordt met een schakelaar met een bruine draad verbonden en vormt zo een geschakelde verbinding met een fasedraad.
In een huisinstallatie worden twee draaddiameters toegepast: 1,5mm² en 2,5mm². De draden geel/groen, bruin en blauw hebben een diameter van 2,5mm², de zwarte draad heeft een diameter van 1,5mm². Het aantal draden in een buis is niet onbeperkt. In een buis mogen alleen draden van één groep. Verder hangt het maximaal aantal toegestane draden af van de diameter van de buis, de aard van de buis en de diameter van de draad:
vaste buis 16mm: 3 x 2,5mm² + 2 x 1,5mm² of 2 x 2,5mm² + 3 x 1,5mm²
flexibele buis 16mm: 3 x 2,5mm² + 1 x 1,5mm² of 2 x 2,5mm² + 2 x 1,5mm²
De maximale stroom die per groep gevoerd kan worden is 16A. De totale stroom die een elektrische installatie voor alle groepen gelijktijdig kan leveren is tenminste 25A, begrensd door de hoofdzekering. Welke stroom maximaal door een verbruikstoestel kan worden afgenomen hangt af van de contactstop (‘stekker’) en het gebruikte aansluitsnoer: soepele snoeren met een aangegoten randaardestekker zijn voor maximaal 6A gespecificeerd, gebaseerd op de preventie van al te grote warmteontwikkeling in het snoer en tussen wandcontactdoos en contactstop.
Mijn oude Trio CO-1303D oscilloscoop (ook bekend als de BK Precision 1405) ziet er nog prima uit maar heeft “extreem zuinige specificaties” en is daarom niet echt bruikbaar als meetinstrument (maar zónder oscilloscoop is foutzoeken haast niet te doen). Maar misschien zijn er wel andere toepassingen voor, ook al is retromaand nog lang niet in zicht.
Oscilloscoop klok Een slimme combinatie van een snelle digitaal naar analoog-omzetter of R-2R netwerk, programmeerbare microcontroller, niftige software en een XY-ingang maakt het mogelijk om graphics op een oscilloscoopscherm te toveren, hetgeen dan bijvoorbeeld een mooie klok kan opleveren.
Oscilloscoop game console
De kloktoepassingen hierboven laten zien dat het oscilloscoopscherm voor allerlei grafische doeleinden te gebruiken is. En dan kom je natuurlijk ook bij spelletjes terecht.
Elektronica is een groot avonturenbos waar je je als jongeling volledig in kunt storten. Niet alleen helpt het om je een bepaalde mate van theoretische kennis eigen te maken, ook zijn er een schier oneindig lijkend aantal technische vaardigheden aan te leren, waaronder solderen, printen ontwerpen en maken, onderdelen kennen en kiezen, een doel nastreven en vooral, het opbouwen van een elektronische schakeling aan de hand van een schema. Als je een jaar of vijftien bent dan maakt dat allemaal weinig uit en wordt de kortste weg naar een werkende schakeling gekozen. Of een vlammende hoop onderdelen. En zo kwam ik op de rommelzolder een geheimzinnige doos van een jaar of twintig 37 oud tegen, getuige het jongste onderdeel van de schakeling uit 1987. Een blik aan de binnenkant leert twee dingen: het hart van de schakeling wordt gevormd door de SPO256-AL2 woordklank-generator, waarbij een CTS256-AL2 is gebruikt om Engelse teksten om te zetten naar de bijbehorende woordklanken, en de bedrading van de print is geheel opgebouwd met een enkele kleur montagedraad.
Enkele kleur montagedraad maakt alle benodigde aansluitingen
Het gebruik van montagedraad bij het opbouwen van een print vormt nog een hele uitdaging (‘had ik deze verbinding nou al gehad of niet? Even kijken…’) maar is wel verreweg de goedkoopste manier van werken. Ik kan me nú nog herinneren hoe dat ging: het schema op een stuk papier uitgetekend en iedere verbinding één voor één op de achterkant van de experimenteerprint aanbrengen en met een rood potlood afstrepen in het schema. Ik kan me echter niet meer herinneren of de schakeling het bij de eerste keer gelijk deed, maar ik kan me ook niet voorstellen dat ik heel veel heb hoeven corrigeren: die ruimte was er gewoon niet. De bedrading ziet er in elk geval niet uit alsof er heel veel mee gerommeld is; betrekkelijk weinig schroeiplekken. Ik vraag me af of ik het op deze manier nogmaals zou doen: de online printenbakkers lonken dan toch meer dan een avondje straf bedraden.
Schema van de SPO256 en CTS256 uit het datablad van laatstgenoemde dat ongetwijfeld aan de basis heeft gestaan van de schakeling
Als ik de datasheets van de gebruikte onderdelen erbij pak, dan lijkt het erop dat ik het schema heb gevolgd die als voorbeeld is meegegeven in de datasheet van de CTS256-AL2. De SPO256-AL2 en de CTS256-AL2 werden in mijn geboortestad Winschoten bij de plaatselijke Tandy verkocht en ik moet deze ergens rond of na 1986 gekocht hebben. De IC’s werden in een blisterverpakking verkocht, met een afgedrukte datasheet veelvuldig gevouwen aan de achterzijde van de verpakking geniet. Een zoektochtje op het internet brengt veel herinneringen terug.
Elektronische onderdelen zoals deze bij Tandy werden verkocht
Het ontwerpen van een passende print voor deze schakeling zou tegenwoordig niet veel werk meer zijn, misschien moet ik er eens een paar uurtjes aan besteden. Misschien een ’tribute’ aan mijn jongere ik, exact dezelfde componenten en -opstelling, maar dan een KiCad of Eagle PCB. Of het ontwerp en de print van Scott Baker, al dan niet met aanpassingen, gebruiken. Ik heb nog een paar SPO256-AL2’s in de onderdelendozen liggen, maar kan niet zo één-twee-drie een CTS256-AL2 vinden. Ach, en de noodzaak. Maar ja, dat hoeft de lol van het laten herbeleven van het maken van zo’n magische schakeling toch niet tegen te houden.
De afgelopen 50 jaar hebben toegezien op verschillende parallelle ontwikkelingen in computer architectuur, chipfabricatie en massaproductie, met de microprocessor als tekenend resultaat. Deze microprocessor werd voor het eerst in 1971 een commercieel succes door de introductie van de 4-bit 4004 van een toen nog klein en onbekend bedrijfje genaamd Intel. Veel bedrijven volgden Intel’s voorbeeld en tegen het eind van de jaren ’70 kon je uit een half dozijn microprocessoren kiezen. In die jaren explodeerde het aantal computergebruikers van een handvol ondernemende hobbyisten en technisch onderlegde ‘hackers’ naar miljoenen zakelijke, industriële, ambtelijke, educatieve en enthousiaste thuisgebruikers, die allemaal de beschikbaarheid hadden over relatief betaalbare computeroplossingen.
Gelijktijdig aan de microprocessor, gebruikmakend van dezelfde ontwikkelingen, ontstond het concept microcontroller, met hierbij de TMS1000 van Texas Instruments als lichtend voorbeeld. Microcontrollers zijn voor het grote publiek minder als eindproduct bekend dan de veel vaker genoemde microprocessoren, hoewel termen als ‘Arduino‘ en ‘ESP32’ ook bij de gemiddelde consument bekend beginnen te raken. Het grote publiek is zich echter wel bewust van het feit dat ‘iets’ verantwoordelijk is voor de slimmigheid in huishoudelijke apparaten zoals broodroosters, koffiemachines, televisies, ovens, wasmachines, koelkasten, elektrische tandenborstels en ontelbare andere ‘gadgets’.
Een microcontroller bestaat intern uit een microprocessor, werkgeheugen, programmaopslaggeheugen en I/O voorzieningen. Dit maakt een microcontroller in veel opzichten een regelcomputer-in-een-chip, waarbij er slechts een externe voedingsspanning nodig is om een programma uit te voeren. De eerste microcontroller was de voornoemde TMS1000 van Texas Instruments (1974), gevolgd door de 8048 van Intel (1977). Een opvolger van de 8048 was de 8051 (1980), met als speciale uitvoering de hier beschreven 8052AH-BASIC (1986).
Het grootste verschil tussen microprocessoren en microcontrollers is gelegen in hun toepassingsgebieden: waar de microprocessor bedoeld is voor generieke toepassingen met veel aanvullende onderdelen zoals geheugen, invoer en uitvoer, video, audio en opslag is de microcontroller bedoeld voor besturingstoepassingen met minimale externe componenten. Zo heeft een microprocessor over het algemeen geen intern werk- of opslaggeheugen, terwijl een microcontroller dat wel heeft. Een microcontroller heeft meer bitvergelijkingsinstructies en vaak een beperktere instructieset, die ook nog eens vooral op verwerkingssnelheid is ingericht. Ook de mogelijkheden om met andere chips en direct met digitale en analoge elektronica te communiceren is bij een microcontroller vaak meer uitgemeten dan bij een microprocessor.
8051 chiparchitectuur, met herkenbare verschillen ON-CHIP ROM, ON-CHIP RAM, I/O PORTS, TIMER en SERIAL PORT
De MCS-51 is een familie van microcontroller IC’s, ontwikkeld, geproduceerd en op de markt gebracht door Intel, gebaseerd op hun archetype 8051. Andere IC-fabrikanten zoals Siemens, Advanced Micro Devices (AMD), Fujitsu en Philips zijn door Intel gelicenseerde fabrikanten van deze microcontrollers. De microcontrollers uit de MCS-51 familie zijn geoptimaliseerd voor besturingstoepassingen met in de instructieset een verscheidenheid aan adresseringsmodi, handige 8-bits rekenkundige instructies, ínclusief instructies voor vermenigvuldigen en delen en ondersteuning voor één-bit variabelen met bijbehorende bitmanipulatiemogelijkheden.
In de tabel zijn enkele van de MCS-51 microcontrollers weergegeven met hierbij aangegeven de hoeveelheid interne geheugen. Het interne gebeugen ligt in hetzelfde adresbereik als het externe geheugen, wat de uitwisselbaarheid van de microcontrollers vergroot.
Configuraties in de MCS-51 familie van microcontrollers
Zoals in de tabel weergegeven is de 8052AH een microcontroller met 8K interne ROM en 256 bytes RAM geheugen. De interne ROM wordt bij het maken van de chip al geprogrammeerd. Een speciale variant van de 8052AH, de 8052AH-BASIC, heeft een af-fabriek in het ROM ondergebrachte drijvendekomma-BASIC genaamd MCS-BASIC, een terminalserver en een EPROM programmeercircuit voor de opslag van programma’s. Intel bracht deze speciale 40-pins microcontroller in 1986 op de markt.
Intel 8052AH-BASIC, een 8052AH microcontroller uit de MCS-51 familie met firmware in maskeerbaar ROM (foto Rudi Niemeijer)
De 8052AH-BASIC was bij de introductie in 1986 om verschillende redenen bijzonder: het bevatte een eenvoudige terminalserver met een ingebouwde editor, zodat programma’s met een seriële terminal of terminalemulatieprogramma beheerd konden worden. Ook de ingebouwde MCS-51 BASIC maakte deze microcontroller speciaal. Nog niet eerder was er een besturingschip met een ingebouwde hogere programmeertaal beschikbaar geweest.
Elektuur kwam met het november 1987 nummer met het ontwerp van een microcontrollerboard gebaseerd op de 8052AH-BASIC, ongeveer rondom de tijd waarin ik zelf ook voor mijn studie met deze microcontroller bezig was. Het ontwerp was opgebouwd rondom een 8052AH-BASIC V1.1, twee 6264 RAM’s, een 2764 of 27128 EEPROM, wat bus logica, een programmeerspanning-beveiliging, RS232 niveau-aanpassing en een reset-schakelaar.
Schema van de 8052AH-BASIC V1.1 schakeling (schema Elektuur)
De opgebouwde microcontroller was een dubbelzijdige, doorgemetaliseerde printplaat met afmetingen van 10×15 centimeter. Twee connectoren maakten I/O en busuitbreidingen mogelijk. Op de printplaat zaten, buiten de 8052AH-BASIC micocontroller, twee RAM-chips, een EPROM-voet en enkele logicachips. De seriële ansluiting voor een terminal of computer met terminalsoftware bestond uit een 5-polige DIN-aansluiting, in die tijd bekend als audioconnector waarmee audioapparaten onderling konden worden verbonden. De toepassing hiervan was niet standaard (een 9-polige D-connector was hier toepasselijker geweest), zodat er een kabel op maat gemaakt moest worden. Twee leds en een schakelaar maakten het geheel af. De printplaat was voorzien van montagegaten zodat het eenvoudig in een behuizing kon worden ingebouwd, een en ander overgelaten aan de creatieve vaardigheden van de constructeur.
Elektuur’s 8052AH-BASIC board, voorzien van twee RAM IC’s en een EPROM voet (foto Rudi Niemeijer)
Na het aansluiten van een geschikte terminal aan de 5-pins DIN-aansluiting en het inschakelen van de voeding start de ingebouwde BASIC programmeertaal en editor op, wordt een prompt via de seriële poort naar een aangesloten terminal verzonden en kan een programma worden ingetoetst:
*MCS-51(tm) BASIC V1.1*
READY
>10FOR I=1TO3
>20 PRINT I
>30NEXT I
>RUN
123
READY
>
*MCS-51(tm) BASIC V1.1*
READY
>10 FOR I=1 TO 3
>20 PRINT I
>30 NEXT I
>RUN
1
2
3
READY
>
Op de prompt kunnen enkele commando’s worden gegeven: RUN, LIST, NEW, NULL, RAM, ROM, XFER, PROG, BAUD, CALL en variaties hierop. Met LIST (of LIST met een regelbereik) wordt het programma (of een deel hiervan) naar de terminal teruggegeven. Een regel wordt gecorrigeerd door deze opnieuw in te voeren.
De geplaatste EPROM kan vanuit de controller worden geprogrammeerd met het commando PROG en programma’s kunnen eenvoudig vanuit de EPROM worden opgestart met het commando ROM:
>LIST
10FOR I=1TO320 PRINT I
30NEXT I
READY
>PROG
12
READY
>NEW
READY
>LIST
READY
>ROM 12
READY
>LIST
10FOR I=1TO320 PRINT I
30NEXT I
READY
>
>LIST
10 FOR I=1 TO 3
20 PRINT I
30 NEXT I
READY
>PROG
12
READY
>NEW
READY
>LIST
READY
>ROM 12
READY
>LIST
10 FOR I=1 TO 3
20 PRINT I
30 NEXT I
READY
>
De EPROM technologie wordt tegenwoordig niet meer toegepast, omdat hiervoor EEPROM (of ‘flash’) voor in de plaats is gekomen: elektrisch wisbare EPROM’s. Maar de EPROM’s uit de tijd van de 8052AH-BASIC konden alleen met ultraviolet licht (vandaar het doorzichtig venster) worden gewist. Een programmeur in die tijd had altijd de beschikking over een wisapparaatje: een doosje met een UV lamp, waar de EPROM in werd geplaatst en een paar minuten belicht.