Hoe kan een visueel gehandicapte persoon ‘s morgens kleding kiezen met bij elkaar passende kleuren? Het idee achter dit project is om kleurinformatie om te zetten in een geluidssignaal. De kleur wordt omgezet naar de toonhoogte van een geluid en de helderheid naar de tijdsduur. In figuur 1 ziet u het schema van een prototype met een piëzo-buzzer zoemer en een TCS34725 kleursensor op een klein break-out-board. Beide zijn verbonden met een Arduino Nano.
 

A piezo buzzer and color sensor connected to an Arduino Nano.
Figuur 1: Schema van het prototype. Een piëzo-buzzer en een TCS34725 kleur sensor, gemonteerd op een klein break-out-board, aangesloten op een Arduino Nano.

Dit prototype is ontwikkeld als onderdeel van de cursus “From Sensor to Report” bij Uppsala University, een cursus over data-acquisitie en het interfacen van sensoren en microcontrollers met de buitenwereld. Daarom gebruiken we geen kant-en-klare bibliotheken voor de sensorinterface, maar coderen we de basisfuncties voor het uitlezen van de sensoren zelf. Overigens zat de logica voor het toewijzen van klanken aan de kleuren in het begin nog in een Python-script op een laptop, en niet op de microcontroller. De PC en de microcontroller communiceren via een seriële interface. We hebben een communicatieprotocol ontwikkeld, waarbij sensordata van de Nano naar de PC gaat en commando’s voor het activeren van de buzzer in de andere richting. Later hebben we de functionaliteit uitgebreid, zodat de Nano standalone kan werken. Toch is dit nog geen productierijp systeem, maar een prototype dat de basisfunctionaliteit laat zien en de lezer uitnodigt om verder te experimenteren.

Voordat we de schakeling gaan opbouwen, moeten we eerst het Arduino-ontwikkelsysteem (IDE) voor het ontwikkelen van programma’s voor de Nano installeren. De IDE is beschikbaar voor alle gebruikelijke besturingssystemen. Volg de aanwijzingen voor uw systeem. Als u nog nooit met Arduino’s hebt gewerkt, volg dan deze link om vertrouwd te raken met de Arduino-IDE. Als tweede voorwaarde hebben we Python nodig, ook dat is beschikbaar voor alle systemen. Executables voor Windows en MAC OS vindt u hier en vrijwel alle Linux-distributies hebben packages in hun repository. Volg ook hier de aanwijzingen voor uw systeem. Tot zo ver de voorbereidingen, laten we aan de slag gaan!
 

De kleursensor

Het hart van dit project is de TCS34725-kleursensor [6], die bestaat uit een 3x4 matrix van fotodiodes (figuur 2).

The TCS34725 color sensor
​Figuur 2: De TCS34725-kleursensor bevat een 3x4 matrix van fotodiodes. Kleurgevoelige filters voor de diodes maken ze gevoelig naar rood, groen of blauw licht. (Bron: ams).

Kleurgevoelige filters voor de diodes maken ze gevoelig naar rood, groen of blauw licht. Verder is er een heldere diode zonder een filter die informatie levert over de helderheid. Het analoge signaal van de diodes wordt omgezet naar digitale vorm door A/D-converters in de sensor. De kleurinformatie is beschikbaar via een I2C-interface. Die maakt de verbinding met een microcontroller via slechts twee draden voor de communicatie, één voor het kloksignaal (SCL) en één voor data (SDA). De kleursensor wordt dan bestuurd door registers in de sensor te lezen en te schrijven, we komen daar later op terug bij de beschrijving van de software.

De hardware wordt samengebouwd op een breadboard (figuur 3), min of meer zoals in figuur 1. De Nano staat links en de TCS34725-kleursensor staat rechts.

The hardware on a solder-less breadboard
Figuur 3: De hardware (zie figuur 1) wordt samengebouwd op een breadboard (hier zonder de drukknop).

De voeding voor de sensor komt via de zwarte en rode draden naar massa en +5 V onderaan. Ook de Nano wordt op die manier gevoed. De groene en gele draden verbinden de data- (SDA) en klokpennen (SCL) met de corresponderende pennen op de Nano, dat zijn respectievelijk A4 en A5. De blauwe draad verbindt de digitale outputpen D2 met de pen LED op de kleursensor. Hiermee wordt een witte LED aangestuurd die ook op het break-out-board zit. De buzzer is verbonden met pen D8 op de Nano. De drukknop die pen D3 met de massa verbindt (de bruine draad in figuur 1) start een meting als de Nano in standalone modus werkt. We komen daar nog op terug.

De schakeling wordt tot leven gebracht door een Arduino-sketch die gebruik maakt van de wire.h-bibliotheek voor de communicatie via de I2C lijnen. Die functies worden gebruikt in onze eigen twee functies I2Cread() en I2Cwrite(), waarin alle communicatie met de sensor is ingekapseld.

I2Cread() wordt gebruikt om een sensorwaarde of parameter uit te lezen uit een register. De functie krijgt het adres van de sensor op de I2C bus (hier 0x29) en het registeradres Als parameters. Het duurde even, voordat we ontdekten er dat 0x80 bij dat adres moet worden opgeteld. De functie geeft de inhoud van het register terug.

Met de functie I2Cwrite() zenden we commando’s van de controller naar de sensor, bijvoorbeeld om configuratiewaarden in te stellen. Deze functie krijgt als parameter, naast het adres van de sensor en het register, de nieuwe waarde die naar het register moet worden geschreven. Deze functie geeft geen retourwaarde terug (void).

De kleurherkenningsapplicatie

We gaan terug naar onze sketch. In de functie setup() initialiseren we de seriële communicatie, de I2C-functionaliteit en de sensor (met de functie color_begin()). In de functie loop(), die oneindig vaak herhaald wordt uitgevoerd, controleren we eerst of er een commando van de PC is aangekomen op de seriële lijn. Als dat het geval is, lezen we de registerinhoud van de sensor voor alle drie de kleuren. Voor elke kleur moeten we twee 8-bits registers uitlezen en de ontvangen bytes samenvoegen tot een 16-bits woord volgens de instructies in het datasheet. Voor de rode kleur doen we dat als volgt:
:

b3=I2Cread(TCS34725,0x16);   // raw data, red

b4=I2Cread(TCS34725,0x17);

red=b4*256+b3;

 

Hier bevat b3 het minst significante byte en b4 het meest significante byte. We vermenigvuldigen dat met 256 en tellen b3 er bij op om de 16-bits variabele red in te vullen. We behandelen de andere kleuren op dezelfde manier maar dan met hun eigen registeradressen.

Verder lezen we de helderheid van de ongefilterde diode en slaan die op in de variabele clea. Die bepaalt de tijdsduur d van het geluid. Als de waarde van clea kleiner is dan 1000, maken we een toon van 0,5 s, als de waarde groter is, maken we een toon van 1,5 s.

Dan lezen we het ontvangen commando en kopiëren het resultaat naar het character array line, zodat we de standaard C-functie strstr() kunnen gebruiken om te bepalen welk commando we hebben gekregen. Dat gaat met het volgende stukje code:

 

Serial.readStringUntil('\n').toCharArray(line,30);

if (strstr(line,"color?")==line) {

Serial.print(clea); Serial.print(" ");

Serial.print(red); Serial.print(" ");

Serial.print(green); Serial.print(" ");

Serial.println(blue);

} else if (strstr(line,"tone_red")==line) {

tone(buzz, 262, d);

...

Bij het commando color? stuurt de Nano de waarden van de vier variabelen clea, red, green en blue terug over de seriële lijn. Als we tone_red hebben ontvangen, gebruiken we het ingebouwde commando tone() om de piëzo-buzzer te activeren, in dit geval met de frequentie die is toegewezen aan de kleur rood. Daarna volgt een aantal andere strstr()-blokken met een vergelijkbare structuur en bijbehorende acties.

We gebruiken dus een heel simpel protocol, waarbij tekststrings over en weer worden gestuurd. Een verzoek van de laptop eindigt met een vraagteken, bijvoorbeeld “color?”, en de Nano reageert daarop met het terugsturen van de gevraagde gegevens. Een opdracht wordt gegeven door alleen het commando te zenden, bijvoorbeeld “tone_red”, wat maakt dat de buzzer een geluid geeft van 262 Hz met een tijdsduur gespecificeerd door d. De communicatie lijkt wel wat op de SCPI-taal die moderne oscilloscopen en andere test- en meetapparaten ondersteunen. Dit maakt interfacen met externe programma’s die commando’s van de seriële lijn ondersteunen zeer eenvoudig; Python, Octave, Matlab en LabView ondersteunen dat allemaal.

Het PC-programma

We hebben op de laptop Python 3 gebruikt om te communiceren met de Nano. De heel eenvoudige programmacode is te zien in listing 1.

Python script for laptop communication with Arduino Nano.
Listing 1:  Python-script voor de laptop die praat met de Arduino Nano.

Na het importeren van ondersteuning voor de seriële communicatie en timing-functionaliteit openen we de seriële poort waar de Nano mee is verbonden met de baudrate die op de Nano is ingesteld. We geven het besturingssysteem 3 seconden om de verbinding op te bouwen en dan sturen we het commando “color?”.

Python 3 codeert strings als Unicode, terwijl de Nano normale ASCII-strings verwacht. Daarom moeten we de letter “b” voor het commando “color?” zetten. Als we dat doen, wordt de string als ASCII verzonden. Na nog even wachten, ontvangen we de respons van de Nano in de variabele reply. Die bevat dan dus de waarden van de vier kleuren, die we individueel ophalen met de methode .split() en toewijzen aan betekenisvolle namen, zoals red.

Nu we de waarden beschikbaar hebben, kunnen we de geluiden gaan toewijzen aan kleuren. We hebben flink moeten experimenteren met gekleurd papier, tot we een goede indeling hadden gevonden. We gebruikten papier met een lichte, middelmatige en donkere tint voor elk van de drie basiskleuren om de sensor te kalibreren. We hebben meermaals de verschillende kleurwaarden gemeten bij een vaste afstand en gebruikten die informatie om de juiste constanten te vinden voor de bovenstaande Python-code. Het commando tone_red wordt naar de Nano gestuurd, als de rode component, genormaliseerd voor de helderheid, groter is dan 0,6. Dan testen we de groene intensiteit en sturen tone_green als de drempelwaarde wordt overschreden. Tenslotte testen we de waarde van de blauwe component. Als er ook geen blauwe component is, wordt “no_color” naar de Nano, gestuurd, waarop die het bijpassende geluid maakt. Het zal zeker nodig zijn om wat te experimenteren met de constanten om het systeem af te stemmen op uw garderobe.

Standalone-versie

De standalone-versie van de code is beschikbaar als download onderaan deze pagina. Deze lijkt sterk op het bovenstaande voorbeeld, behalve dat nu niet gewacht wordt op commando’s via de seriële lijn. In deze versie wacht de Nano nu tot er op de knop wordt gedrukt, lees dan de sensor uit en speelt het geluid af. De kleurinformatie wordt dus rechtstreeks verwerkt op de Nano, zoals in het volgende codefragment:
 

if (red/clea > 0.6) {  

tone(buzz, 262, d);

} else if (green/clea > 0.3) {

...


Als u de kleding altijd wilt verlichten met de ingebouwde LED op het break-out-board, kunnen we die ontsteken met digitalWrite(led,HIGH) net voor het lezen van de registers van de TCS34725 en hem later weer doven.

Als derde stap kunnen we het systeem draagbaar maken, door een kale ATmega328 te gebruiken en die te flashen met een Arduino bootloader. U kunt het systeem dan voeden uit een accu of batterij zolang de knop is ingedrukt. Het systeem start dan op en converteert voortdurend kleur totdat de drukknop wordt losgelaten. De software is ook beschikbaar op de webpagina bij het artikel. De opbouw van het systeem is een leuke oefening voor enthousiaste lezers.

Bij  de cursus “Sensor to Report” was de kleursensor erg populair. Een tweede student, die de kleur van de hemel over een langere tijd wilde monitoren om de gegevens later te analyseren, gebruikte in essentie dezelfde opbouw met de Nano die communiceert met een host-computer via de seriële lijn. Ze gebruikte een Python-script op een Raspberry Pi om de data op te slaan in een MySQL-database, die ook op de Pi draaide, en gebruikte later Octave voor het maken van diagrammen van de kleuren die in de loop van een week waren geregistreerd. De gegevens werden kort voor Kerstmis geregistreerd en maakte ons pijnlijk duidelijk hoe kort de dagen kunnen zijn in Uppsala. Meer data-acquisitieprojecten, met een vergelijkbare opzet, vindt u hier.

I2C communication

Over de auteurs

Volker Ziemann and Annika SchlechterVolker Ziemann’s interesse in elektronica begon met Elektor, rond de tijd van de 40W Edwin-versterker (midden jaren ’70), maar hij dwaalde af naar zijn studie natuurkunde en heeft sindsdien gewerkt met deeltjesversnellers bij SLAC in de Verenigde Staten, CERN in Genève, en nu in Uppsala in Zweden. Omdat elektronica een belangrijke rol speelt bij het besturen en de data-acquisitie in versnellers, heeft vroege interesse hem tijdens zijn hele carrière geholpen. Hij geeft nu les bij Uppsala University en heeft drie boeken geschreven, één daarvan over data-acquisitie met Arduino-boards en de Raspberry Pi.

Annika Schlechter studeert natuurkunde bij de University of Heidelberg in Duitsland. Op dit moment werkt ze aan haar kandidaatsscriptie bij het Duitse Kankeronderzoek Instituut in Heidelberg. Dit project begon tijdens een Erasmus-semester bij de University of Uppsala in Zweden, waar ze Volker’s colleges over “Sensor to Report” volgde.


Vertaling: Evelien Snel