Before connecting the Digispark to the USB port, check for any shorts (direct positive voltage to ground connection) as this could damage both the Digispark board and the USB/PC.
Toggle Switch no Debouncing
A single button is connect to ATtiny85/Digispark pin B4 so that when the button is unpressed a logical zero or low is present, and conversely when the button is pressed a logical one or high is present.
The sketch presented in Code Snippet 1 demonstrates the simplest scenario in which a single button is used to control a LED, with the LED only changing state (either on or off) if the button is pressed or released. However, all buttons due to inherent 'noisy' nature to the contacts that form the switch do not give a single signal transition when pressed (i.e., either high to low or vise-versa) but rather a series of voltage spikes (in very rapid succession) before flattening out to a steady state, either high or low depending upon the current state of the button.
Therefore, when using the circuit and code in Snippet 1, it would appear that each time the button is pressed that the LED is illuminated. However, due to the ATtiny85 rapidly cycling through the loop() routine, in fact the LED is turned on and off a number of times depending upon the noise of the switch, but the slowness of the human eye fails to detect this, and it appears that the LED just turns on or off in response to the button. While perhaps this is not a problem in this scenario (just turning the LED on or off), if the situation was incrementing a counter with each button press, this would clearly lead to error.
This 'noisy' switch problem (and apparent 'intermitent' errors that this can lead to) is demonstrated by using a counter to trace the number of times a logical high is actually recorded for each button press, and display this on the Arduino serial monitor, rather than just relying on the human eye and a LED.
The extra code for this serial output of the counter to the Arduino serial monitor is given in code Snippet 2 and the results presented in the Video Section. How to use serial communications with the ATtiny85 is detailed in ATtiny85 serial communications.
The solution to the 'noisy' switch problem is to use 'debouncing' which can be done via hardware and or software. The software approach is advantageous in that additional hardware components are avoided, which in a situation using an ATtiny85, it is likely the small size of the ATtiny85 was attrative in keeping project PCB size small and inexpensive. See the next section for software debouncing code example.
When installing Digispark boards as part of the Arduino IDE (see ATtiny85 introduction) the SoftSerial.h library for serial communications is available (1).
Code Snippet 1: Toggle Switch no Debouncing
#define buttonPin 4 // the number of the pushbutton pin
#define ledPin 1 // the number of the LED pin
int buttonState = 0; // variable for reading the pushbutton status
int lastButtonState = LOW;
void setup() {
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
}
void loop() {
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
// if the pushbutton is pressed the buttonState is HIGH
if (buttonState != lastButtonState) {
if (buttonState == HIGH) {
digitalWrite(ledPin, HIGH); //turn LED on
} else {
digitalWrite(ledPin, LOW); //turn LED off
}
lastButtonState = buttonState;
}
}
Code Snippet 2: Toggle Switch no Debouncing/Serial Output
#include
TinyDebugSerial mySerial = TinyDebugSerial();
#define buttonPin 4 // the number of the pushbutton pin
#define ledPin 1 // the number of the LED pin
int buttonState = 0; // variable for reading the pushbutton status
int lastButtonState = LOW;
unsigned int counter=0;
void setup() {
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
mySerial.begin(115200);
delay(3000); //give a delay so can connect the port in the receiving software
mySerial.println("hello");
}
void loop() {
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
// if the pushbutton is pressed the buttonState is HIGH
if (buttonState != lastButtonState) {
if (buttonState == HIGH) {
digitalWrite(ledPin, HIGH); //turn LED on
counter=counter+1;
} else {
digitalWrite(ledPin, LOW); //turn LED off
}
lastButtonState = buttonState;
}
if (counter==10) {
mySerial.print("="); mySerial.println(counter);
counter=0;
}
}
Toggle Switch with Software Debouncing
As previously discussed, push buttons and toggle switchs etc often generate extra 'spurious' pulses when pressed, due to the mechanical nature of these components, and these extra pulses may be read as multiple presses in a very short time and therefore lead to the software/firmware giving incorrect response. The usual software approach to 'debouncing' these 'bouncing' signals when a button is pressed or released is to record the signal from the button, and then check the signal again after a short time period (a few milliseconds). If the signal is the same between the first and next reading after this short interval, then the program can interpret the signal as being a definite single press or release of the button.
The following code snippet demonstrates how to use the millis() function to use this 'multiple reading after a short time period' approach to debouncing a button input. The extra code in relation to the 'counter' and TinyDebugSerial library is added in order to demonstrate that the debouncing algorithm is actually working. The results of the ATtiny85 running this code is demonstrated by a video in the Video Section.
Code Snippet 3: Toggle Switch with Software Debouncing
#include
TinyDebugSerial mySerial = TinyDebugSerial();
#define buttonPin 4 // the number of the pushbutton pin
#define ledPin 1 // the number of the LED pin
int buttonState = 0; // variable for reading the pushbutton status
int lastButtonState = LOW;
unsigned long lastDebounceTime = 0; // the last time the LED was toggled
unsigned long debounceDelay = 50; // the debounce time
unsigned int counter=0;
void setup() {
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
mySerial.begin(115200);
delay(3000); //give a delay so can connect the port in the receiving software
mySerial.println("hello");
}
void loop() {
// read the state of the pushbutton value:
int reading = digitalRead(buttonPin);
if (reading != lastButtonState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != buttonState) {
buttonState = reading;
if (buttonState == HIGH) {
// turn LED on:
digitalWrite(ledPin, HIGH);
counter=counter+1;
} else {
// turn LED off:
digitalWrite(ledPin, LOW);
}
}
}
if (counter==10) {
mySerial.print("="); mySerial.println(counter);
counter=0;
}
}
Toggle Switch with Button Library
text
The Button library for handling interfacing of switches is available (2).
Code Snippet 4: Toggle Switch with Button Library
text
Only Logged-In Members can add comments