Ik heb het idee dat ik iets over het hoofd zie.
Momenteel ben ik bezig om zoiets zelf te maken: http://flic.io/
Hard- en software zijn gereed, maar ik heb een fout in het registreren van de verschillende functies van de button. Het vermoeden bestaat dat dit komt door het bouncen van de microswitch. Ik kan daar helaas geen hardwarematige oplossing voor implementeren in verband met de fysieke ruimte in mijn behuizing.
Ik werk met een Arduino (Pro Mini), 433mhz transmitter en twee CR2032 batterijtjes. Om de knop zo lang mogelijk mee te laten gaan wil ik het systeem in principe altijd in power down hebben. Pas als de knop ingedrukt wordt dan moet alles beginnen, en daarna zo snel mogelijk weer wakker worden. Het is wat betreft energieverbruik dus ook geen mogelijkheid om niet met interrupts te werken, maar bijvoorbeeld met elke keer 100ms deep sleep en dan checken of er iets is veranderd.
Het probleem is dat soms drie clicks achter elkaar als twee double clicks wordt gezien en dat bij elke double en long click óók de single click wordt gedetecteerd. Dit kan dus komen door het debouncen, maar elke standaard oplossing die ik daarvoor implementeer (millis() bijhouden en < x ms gewoon afkappen of iets dergelijks, bijvoorbeeld debounce oplossing van Arduino documentatie) zorgt er voor dat er óf niets veranderd aan het probleem, óf dat geen enkele click wordt geregistreerd.
Dit is mijn code waarbij het probleem optreedt:
Dit is een versimpelde versie die ik gebruik om de verschillende clicks te testen.
Schema is simpel:
GND -- 10k -- pin 3 -- switch -- Vcc
Sorry, ik heb geen kunde om zoiets netjes te tekenen.
Inmiddels heb ik het idee dat ik de interrupts gewoon niet goed begrijp. Als een interrupt wordt getriggerd, moet daar niets gebeuren verder en moet loop() verder gaan. Bij een tussenkomende interrupt zou niets moeten gebeuren en moet het systeem simpelweg doorgaan met het uitvoeren waar die mee bezig was. Althans, zo heb ik het in mijn gedachte als logisch zitten.
Na twee dagen dit weekend ben ik ten einde raad. Pak ik het nu echt zo verkeerd aan?
Momenteel ben ik bezig om zoiets zelf te maken: http://flic.io/
Hard- en software zijn gereed, maar ik heb een fout in het registreren van de verschillende functies van de button. Het vermoeden bestaat dat dit komt door het bouncen van de microswitch. Ik kan daar helaas geen hardwarematige oplossing voor implementeren in verband met de fysieke ruimte in mijn behuizing.
Ik werk met een Arduino (Pro Mini), 433mhz transmitter en twee CR2032 batterijtjes. Om de knop zo lang mogelijk mee te laten gaan wil ik het systeem in principe altijd in power down hebben. Pas als de knop ingedrukt wordt dan moet alles beginnen, en daarna zo snel mogelijk weer wakker worden. Het is wat betreft energieverbruik dus ook geen mogelijkheid om niet met interrupts te werken, maar bijvoorbeeld met elke keer 100ms deep sleep en dan checken of er iets is veranderd.
Het probleem is dat soms drie clicks achter elkaar als twee double clicks wordt gezien en dat bij elke double en long click óók de single click wordt gedetecteerd. Dit kan dus komen door het debouncen, maar elke standaard oplossing die ik daarvoor implementeer (millis() bijhouden en < x ms gewoon afkappen of iets dergelijks, bijvoorbeeld debounce oplossing van Arduino documentatie) zorgt er voor dat er óf niets veranderd aan het probleem, óf dat geen enkele click wordt geregistreerd.
Dit is mijn code waarbij het probleem optreedt:
C:
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
| #include <Ports.h> #include <RF12.h> #include <avr/sleep.h> #include <PinChangeInt.h> #include <VirtualWire.h> ISR(WDT_vect) { Sleepy::watchdogEvent(); } char *controller; const int buttonPin = 3; bool stateSingle = false; bool stateDouble = false; bool stateLong = false; void setup() { pinMode(13, OUTPUT); pinMode(6, OUTPUT); pinMode(7, OUTPUT); pinMode(5, OUTPUT); Serial.begin(9600); PCintPort::attachInterrupt(buttonPin, wakeUp, HIGH); } void wakeUp() { } void loop() { int i = 0; while (digitalRead(buttonPin) == HIGH) { // Wait until button is LOW, or has been high for more than 600ms Sleepy::loseSomeTime(50); if (i > 12) break; i++; } if (digitalRead(buttonPin) == HIGH) longTapAction(); else { i = 0; while (digitalRead(buttonPin) == LOW) { // Wait for possible double press Sleepy::loseSomeTime(50); if (i > 8) break; i++; } if (digitalRead(buttonPin) == HIGH) { doubleTapAction(); while (digitalRead(buttonPin) == HIGH) Sleepy::loseSomeTime(50); } else singleTapAction(); } } void singleTapAction() { stateSingle = !stateSingle; digitalWrite(5, stateSingle ? HIGH : LOW); Sleepy::powerDown(); } void doubleTapAction() { stateDouble = !stateDouble; digitalWrite(6, stateDouble ? HIGH : LOW); Sleepy::powerDown(); } void longTapAction() { stateLong = !stateLong; digitalWrite(7, stateLong ? HIGH : LOW); Sleepy::powerDown(); } |
Dit is een versimpelde versie die ik gebruik om de verschillende clicks te testen.
Schema is simpel:
GND -- 10k -- pin 3 -- switch -- Vcc
Sorry, ik heb geen kunde om zoiets netjes te tekenen.
Inmiddels heb ik het idee dat ik de interrupts gewoon niet goed begrijp. Als een interrupt wordt getriggerd, moet daar niets gebeuren verder en moet loop() verder gaan. Bij een tussenkomende interrupt zou niets moeten gebeuren en moet het systeem simpelweg doorgaan met het uitvoeren waar die mee bezig was. Althans, zo heb ik het in mijn gedachte als logisch zitten.
Na twee dagen dit weekend ben ik ten einde raad. Pak ik het nu echt zo verkeerd aan?