We program an Arduino sketch that creates an up/down counter from 0 to 99 managed by 2 buttons, one for increasing and the other for decreasing, and the system prints the status of the count on 2 seven-segment displays. The circuit is shown in the figure and can also be implemented in practice.
The two buttons are mounted in pull-down with 10kOhm resistors. Arduino accepts a voltage of 5V for the high level and 0V for the low level on the digital pins. The display LEDs are protected with 220Ohm resistors. Arduino generates a voltage of 5V on the digital pins for the high level and supplies a current of about 40mA.

2 display 7 segmenti up'n down.jpg

Here is the link for the simulation with Tinkercad: https://www.tinkercad.com/things/i5TAs15Ckri

In the sketch below I found a software solution to button bouncing. For information on how to program the debounce of a button you can see my article: https://www.filipposfactory.com/index.php/8-arduino/37-switch-debouncing

Also for information on how to use the Arduino Uno port registers see this article of mine: https://www.filipposfactory.com/index.php/8-arduino/35-counter-0-9-with-7-segments-display-and-arduino-uno or you go to Arduino site: https://www.arduino.cc/en/Reference/PortManipulation.

int d, u, i=0;
// look-up table to encode numbers on display
byte numero [10]={B00111111, B00000110, B01011011, B01001111, B01100110,
B01101101, B01111101, B00000111, B01111111, B01101111 };

// boolean state variables:
// 1 = true = HIGH, 0 = false = LOW
int upnow=1;
int upbefore=1;
int downnow=1;
int downbefore=1;

void setup() {
    // pinMode OUTPUT to digital pins from 0 to 7
   DDRD = B11111111;
   /* pinMode(8,OUTPUT);
    pinMode(9,OUTPUT);
   pinMode(10,INPUT);
   pinMode(11,INPUT);
   */
   DDRB = B11110011;
}

void loop() {
   // Arduino reads the buttons in polling
   upnow=digitalRead (10);
    downnow=digitalRead (11);

    // up button pressed
   if((upnow==HIGH) && (upbefore==0))
   {
      if (i<99)
         i++;
   }
   upbefore=upnow;

   // down button pressed
   if((downnow==HIGH) && (downbefore==0))
    {
      if (i>0)
         i--;
   }
   downbefore=downnow;

   // display management: encoding from decimal 0-99
   // to 2 digits for 7 segment displays
    d=i/10;
    u=i-(d*10);

   // print tens
   digitalWrite(9,LOW);
   digitalWrite(8,HIGH);
    PORTD=numero[d];
   delay(10);

    // print units
   digitalWrite(8,LOW);
   digitalWrite(9,HIGH);
    PORTD= numero[u];
   delay(15);
}

The displays are of the common cathode type. The cathode (central pin, above or below) must then be grounded, while to illuminate each of the LEDs it is necessary to supply the relative pin with a positive voltage of about 1.2V. If an impulsive signal is applied to the common cathode, current can be saved by turning on the displays intermittently, but with a frequency such as to make the image appear stable; this technique, called duration modulation
pulse (PWM: Pulse Width Modulation) takes advantage of the properties of the human eye to present a certain persistence of the image on the retina and to possess a lower sensitivity towards impulsive signals.
Thus the respective LEDs of the two displays are connected together and to the same Arduino pin of PORTD (from 0 to 7). Two NPN type BJTs with a 1kOhm resistor connected to the base operate in an ON-OFF configuration. The bases are connected to pins 8 or 9 of the Arduino. When there is 0 voltage in the base, the relative transistor is off, while when I supply 5V, the transistor is on and so the dipslay to which its collector is connected is active.
The sketch is programmed so that to print the tens it sends a HIGH signal to the BJT connected to its cathode, LOW to the other BJT and on the PORTD pins it sends the tens digit; while a few milliseconds later it sends a HIGH signal to the BJT connected to the cathode of the display that displays the units, LOW to the BJT of the tens and on the pins of PORTD it sends the digit of the units; now wait a few milliseconds and this repeats cyclically.

When I use a button the main problem I have to solve in the management via microcontroller is the switch bouncing, when I press it. When a switch mechanism moves from one position to another, it doesn't do so instantly. It takes some time for the mechanism to stabilize in its new position. Meanwhile, the mechanism performs some oscillations such that, if we try to read the state of the switch at that moment, the result will be random.
Arduino (which works at 16 MHz) reads the digital pin to which the button is connected several times within its settling transient and perceives the event as if the button is pressed and released several times.

There are several ways to eliminate the bounce of a switch, both hardware and software. Hardware debouncing involves using an additional circuit to eliminate wobble and receive a smooth, smooth transition from HIGH to LOW or LOW to HIGH. It has the advantage that the process does not occupy the microcontroller, but requires additional components. The other approach is software debouncing. This involves delaying the acceptance of the button press until the transient has passed, in order to be sure that the button has actually been pressed and not an abnormal event.

Arduino 3 LED with debouncing.jpg

In the next sketch we look at a software approach. It is a simple process that is based on two states of the button: the previous one, stored in the past iteration of the loop(), and the current one, measured at the beginning of the key press and then the signal transition. If these two values are different, we will accept the button press, otherwise we will not. Furthermore, we must consider that not all switches have the same responses and transients. So, remember that in your projects you will have to adjust a delay() for this (do some testing and find out what is the transition period of your switches).

The sketch that I show you uses three LEDs, each time the button is pressed, one LED lights up and the previous one switches off in a continuous cycle. You can find it to this link: https://www.tinkercad.com/things/3yaJikfCIwn

// definizioni da usare nel codice
#define ledRed 3
#define ledYellow 4
#define ledGreen 5
#define button 7

// dichiarazione variabili di stato
// e assegnamento valore iniziale
int led = 0;
int buttonnow = LOW;
int buttonbefore= LOW;

// setup led e pulsante
void setup(){
    pinMode(ledRed, OUTPUT);
    pinMode(ledYellow, OUTPUT);
    pinMode(ledGreen, OUTPUT);
    pinMode(button, INPUT);
}

void loop(){
    // polling pulsante con debouncing
    buttonnow=digitalRead(button);
    if ((buttonnow==HIGH)&&(buttonbefore==LOW)) {
        led++;
        if (led>3){
            led=1;
        }
    }
    buttonbefore=buttonnow;
    delay (50);
   

    // gestione LED
    if (led==1){
       digitalWrite (ledRed, HIGH);
       digitalWrite (ledYellow, LOW);
       digitalWrite (ledGreen, LOW);
    }
    if (led==2){
        digitalWrite (ledRed, LOW);
        digitalWrite (ledYellow, HIGH);
        digitalWrite (ledGreen, LOW);
    }
    if (led==3){
        digitalWrite (ledRed, LOW);
        digitalWrite (ledYellow, LOW);
        digitalWrite (ledGreen, HIGH);
    }
}

During this Covid-19 period I was forced to use online education with my students so I increased the use of simulation tools, especially online simulation tools. These are very useful for me during this time, although they are not important and effective like a real laboratory at school, which I prefer, but only a temporary remedy. 
In these days I'm using Tinkercad  that is free program to online 3D modeling and Electonics circuits that runs in a web browser, known for its simplicity and ease of use. It is very useful for teachers who want to create a class with their students and is easily combined with Google Classroom. 

This is an example of an exercise by a student of mine: https://www.filipposfactory.com/index.php/8-arduino/35-counter-0-9-with-7-segments-display-and-arduino-uno

 

Counter 0-9 with 7 segments display and Arduino Uno.jpg

In this example I propose a simple simulation with Tinkercad of a circuit that creates a counter from 0 to 9 with a 7-segment display, programmed using Arduino Uno. The display is of the common cathode type.

The sketch that I propose to you is really working. This is the link: https://www.tinkercad.com/things/6ok3zL0QW2L. It is based on a look-up table made with an array where I have coded the digits of the numbers to be shown on the display.
I used port registers based programming and I choosed the ATMega 328 pin group called port D which is 8 bit and is convenient for managing an LED display. Here you can find information about Arduino port registers: https://www.arduino.cc/en/Reference/PortManipulation.

It is important that when you load the sketch in the Arduino FLASH memory, you momentarily disconnect pins 0 and 1, because they are used by the USB as serial TX and RX, otherwise the loading fails.

This is the sketch:

byte numero [10]={B00111111, B00000110, B01011011, B01001111, B01100110, B01101101, B01111101, B00000111, B01111111, B01101111};

int i=0;

void setup()
{
   DDRD = B11111111;
}

void loop()
{
   PORTD = numero[i];
   delay(500);
   i++;
   if (i>9)
      i=0;
}

20180123 arduino condensatore breadboard01

I propose a new measurement experiment using Arduino, working as DAQ (data acquisition instrument). I proceed as described in the articles Arduino and Excel with PLX-DAQ and Voltage divider measurements with PLX-DAQ: I mount my circuit on breadboard powered by the Arduino board at 5V. I propose to analyze the charge and discharge of a capacitor and collect data in a Excel spreadsheet.
In this lab test, I use the following devices: 1 capacitor 3300µF (electrolytic), 1 resistor 1kΩ,1 switch, 5V Arduino supply.

I write the Arduino sketch reported below.

#define sensorPin A0 // select the input pin for the potentiometer
int sensorValue = 0; // variable to store the value coming from the sensor 0-1023
float sensorVoltage = 0; // variable to store the voltage coming from the sensor 0-5V
int cont = 0;

void setup() {
  Serial.begin(9600);
  Serial.println("CLEARDATA");
  Serial.println("LABEL,t,COUNTER,V-CONDENSATORE");
}

void loop() {
  // read the value from the sensor
  sensorValue = analogRead(sensorPin);
  // calculate voltage
  sensorVoltage = sensorValue*5.0/1023.0;
  // send value to USB
  Serial.print("DATA,TIME,");
  Serial.print(cont++);
  Serial.print(",");
  Serial.println(sensorVoltage);
  // delay 100ms
  delay(100);
}

The figure below shows a measurement test with data collection in Excel and a 2-Dline type graph to represent voltage measured on capacitor.

20180123 arduino condensatore breadboard02

 

Advertising

Advertising

Advertising