Automatisch fietsachterlicht met ATtiny85

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.
Schema van het automatisch fietsachterlicht
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.
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
/*
  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.

Het achterlicht doet het ondertussen.

Automatisch fietsachterlicht met ATtiny85