Binaire klok

Arduino specifieke Software
Berichten: 21
Geregistreerd: 27 Feb 2013, 15:17

Binaire klok

Berichtdoor Dedier » 24 Okt 2013, 14:13

Hallo allemaal,


Ik ben nu bezig met een projectje waarbij ik een binaire klok probeer te maken. Ik heb dit projectje "gekopieerd" van het internet. Hierbij de link van de pagina waar ik dit project van daan heb http://www.thingiverse.com/thing:23436
Hier bij een plaatje van de pagina waar ik dit project vandaan heb voor de visualisatie. De rode ledjes geven de seconden weer. De groene de minuten en de gele de uren. De meest linker AM of PM.
DSCF3475_preview_featured (640x480).jpg
DSCF3475_preview_featured (640x480).jpg (195.06 KiB) 10809 keer bekeken


Maar nu heb ik een probleem. Als ik bijvoorbeeld het 3e en 2e seconde ledje aan heb gaat de 2e minuten ledje ook een klein beetje aan. Mijn vermoede is dat het door het charlyplexen komt. Ik heb even gegoogled en het wordt ook wel gosht ledje genoemd.
Ik zou graag de code zo veranderen dat het niet meer voor komt alleen lukt het mij niet/ weet ik niet precies hoe ik dit voor elkaar moet krijgen.

Hierbij de code:

Code: Alles selecteren
// Example: Charlieplexing Test

// The total LED count.
const int LED_COUNT = 19;
long LED_BITS_VAL = 0;             // Initialized on setup.

// These mark the min and max pins used for the LEDs.
const int LED_PIN_MIN = 8;
const int LED_PIN_MAX = 12;

const int SEC_BUTTON = 4;          // The pin for the second reset button.
const int MIN_BUTTON = 3;          // The Pin for the minute set button.
const int HOUR_BUTTON = 2;         // The Pin for the hour set button.
const int BUTTON_LED = 7;          // The LED pin assocated with the button.

const long BUTTON_LIGHT_DELAY = 50;// The delay time to light the button light.
long lastButtonLightTime = -1;     // The last time the button light was lit.
long lastSecondTime = 0;           // The elapsed seconds timer.

// Pin arrays for each LED.
//  The first pin is the HIGH.
//  The second pin is the LOW.
//  All non-listed pins will be inputs so they do not affect the current.
const int LED[LED_COUNT][2] = {{ 8, 9}, { 9, 8}, { 8,10}, {10, 8},
                               { 8, 11}, {11, 8}, { 8, 12},
                               { 12, 8}, { 9, 10}, {10, 9}, { 9,11},
                               { 11, 9}, { 9, 12}, {12, 9},
                               { 10, 11}, {11, 10}, {10, 12}, {12, 10},
                               { 11, 12}};
                               
long onSecBits = 0;        // List of all the second LEDs that are currently on.
long onMinBits = 0;        // List of all the minute LEDs that are currently on.
long onHourBits = 0;       // List of all the hour LEDs that are currently on.
long onAmPmBits = 0;       // AM or PM LED.
int currentLight = -1;     // The current light we are cycling on.

// Current Button States
int secondButtonState = LOW;
int minuteButtonState = LOW;
int hourButtonState = LOW;

// Debouncing is a method to reduce the amount of flicker that
// buttons sometimes have with imperfect connections.
long lastDebounceTime = -1;
const long DEBOUNCE_DELAY = 50;

// We want to switch LEDs really fast, because of the way these lights are wired,
// we can only have one light on at a time.  Switching really fast causes an
// illusion that more than one is on.  If you see flicker, you want to reduce
// the refresh rate to make the lights blink faster.
long lastLEDswitch = 0;
long LEDRefreshRate = 1;  // Time, in milliseconds, to switch lit LEDs.

// Method declarations.
void LightLED(int LEDIndex = -1);

/**
 * Initialization.
 */
void setup()
{
  pinMode(MIN_BUTTON, INPUT);
  pinMode(HOUR_BUTTON, INPUT);
  pinMode(BUTTON_LED, OUTPUT);
 
  // Enable a bit for each light, this is used for easy switching between
  // light states.
  LED_BITS_VAL = 0;
  for (int index = 0; index < LED_COUNT; ++index)
  {
    bitSet(LED_BITS_VAL, index);
  }
}

/**
 * Main Loop
 */
void loop()
{
  UpdateTimer();
 
  UpdateButtonStatus();

  UpdateLEDStatus();
}

/**
 * Updates the current second timer.
 */
void UpdateTimer()
{
  long elapsedSeconds = millis() - lastSecondTime;
  if (elapsedSeconds >= 1000)
  {
    elapsedSeconds -= 1000;
    lastSecondTime = millis() - elapsedSeconds;
    IncreaseSecond();
  }
}

/**
 * Updates the status of all buttons.
 */
void UpdateButtonStatus()
{
  if (lastDebounceTime == -1)
  {
    // Read the state of our button.
    int secondState = digitalRead(SEC_BUTTON);
    int minuteState = digitalRead(MIN_BUTTON);
    int hourState = digitalRead(HOUR_BUTTON);
 
    // If the button was pressed and was previously un-pressed...
    if (secondState != secondButtonState)
    {
      // Setup for debouncing.
      lastDebounceTime = millis();

      secondButtonState = secondState;
      if (secondButtonState == HIGH)
      {
        ResetSecondsButton();
      }
    }
    else if (minuteState != minuteButtonState)
    {
      // Setup for debouncing.
      lastDebounceTime = millis();

      minuteButtonState = minuteState;
      if (minuteButtonState == HIGH)
      {
        ToggleMinuteButton();
      }
    }
    else if (hourState != hourButtonState)
    {
      // Setup for debouncing.
      lastDebounceTime = millis();
     
      hourButtonState = hourState;
      if (hourButtonState == HIGH)
      {
        ToggleHourButton();
      }
    }
  }
  else
  {
    long elapsedTime = millis() - lastDebounceTime;

    // Toggle the button if it was just pressed.
    if (elapsedTime > DEBOUNCE_DELAY)
    {
      lastDebounceTime = -1;
    }
  }
 
  // Update the status of the button light.
  if (lastButtonLightTime > -1)
  {
    long elapsedTime = millis() - lastButtonLightTime;
     
    // Turn the light off after the delay time has elapsed.
    if (elapsedTime >= BUTTON_LIGHT_DELAY)
    {
      digitalWrite(BUTTON_LED, LOW);
    }
  }
}

/**
 * Updates all LEDs
 */
void UpdateLEDStatus()
{
  // On refresh rate, we want to swap the currently lit LED.
  if (millis() - lastLEDswitch > LEDRefreshRate)
  {
    lastLEDswitch = millis();
    CycleActiveLight();
  }
 
  LightLED(currentLight);
}

/**
 * Increases the current elapsed second timer.
 */
void IncreaseSecond()
{
  onSecBits++;
  if (onSecBits > 59)
  {
    onSecBits = 0;
    onMinBits++;
   
    if (onMinBits > 59)
    {
      onMinBits = 0;
      onHourBits++;
     
      if (onHourBits > 11)
      {
        onHourBits = 0;
        onAmPmBits++;
       
        if (onAmPmBits > 1)
        {
          onAmPmBits = 0;
        }
      }
    }
  }
}

/**
 * Event handler when the second button is toggled.
 */
 void ResetSecondsButton()
{
  lastSecondTime = millis();

  lastButtonLightTime = millis();
 
  // Turn the button light on to show that the button has been pressed.
  digitalWrite(BUTTON_LED, HIGH);

  onSecBits = 0;
}

/**
 * Event handler when the minute button is toggled.
 */
void ToggleMinuteButton()
{
  lastButtonLightTime = millis();
 
  // Turn the button light on to show that the button has been pressed.
  digitalWrite(BUTTON_LED, HIGH);
 
  onMinBits++;
  if (onMinBits > 59)
  {
    onMinBits = 0;
  }
}

/**
 * Event handler when the hour button is toggled.
 */
void ToggleHourButton()
{
  lastButtonLightTime = millis();
 
  // Turn the button light on to show that the button has been pressed.
  digitalWrite(BUTTON_LED, HIGH);
 
  onHourBits++;
 
  if (onHourBits > 11)
  {
    onHourBits = 0;
    onAmPmBits++;
   
    if (onAmPmBits > 1)
    {
      onAmPmBits = 0;
    }
  }
}

/**
 * Toggles on a given LED index.
 *
 * @param[in]  LEDIndex  The index of the LED to light.
 *                       Use -1 to turn off all LEDs.
 */
void LightLED(int LEDIndex)
{
  int highPin = -1;
  int lowPin = -1;
 
  if (LEDIndex > -1 && LEDIndex < LED_COUNT)
  {
    highPin = LED[LEDIndex][0];
    lowPin  = LED[LEDIndex][1];
  }

  for (int index = LED_PIN_MIN; index <= LED_PIN_MAX; ++index)
  {
    if (index == highPin)
    {
      pinMode(index, OUTPUT);
      digitalWrite(index, HIGH);
    }
    else if (index == lowPin)
    {
      pinMode(index, OUTPUT);
      digitalWrite(index, LOW);
    }
    else
    {
      pinMode(index, INPUT);
    }
  }
}

/**
 * Cycles the currently active LED.
 */
void CycleActiveLight()
{
  int firstOnLED = -1;
 
  // Iterate through each LED index on the 'seconds' display and find the one that
  // is on and is at an index above our currently lit LED.
  for (int index = 0; index < 7; ++index)
  {
    int isOn = bitRead(onSecBits, index);
   
    // If the light is on, this is a potential switch.
    if (isOn)
    {
      // if this is our first on light, store this index for later jus in case.
      if (firstOnLED == -1)
      {
        firstOnLED = index;
      }
     
      // If this light is on and it is an iteration above our current
      // light index, swap to this light as our current and bail.
      if (index > currentLight)
      {
        currentLight = index;
        return;
      }
    }
  }

  // Iterate through each LED index on the 'minutes' display and find the one that
  // is on and is at an index above our currently lit LED.
  for (int index = 0; index < 7; ++index)
  {
    int isOn = bitRead(onMinBits, index);
   
    // If the light is on, this is a potential switch.
    if (isOn)
    {
      // if this is our first on light, store this index for later jus in case.
      if (firstOnLED == -1)
      {
        firstOnLED = index + 7;
      }
     
      // If this light is on and it is an iteration above our current
      // light index, swap to this light as our current and bail.
      if (index + 7 > currentLight)
      {
        currentLight = index + 7;
        return;
      }
    }
  }

  // Iterate through each LED index on the 'hours' display and find the one that
  // is on and is at an index above our currently lit LED.
  for (int index = 0; index < 4; ++index)
  {
    int isOn = bitRead(onHourBits, index);
   
    // If the light is on, this is a potential switch.
    if (isOn)
    {
      // if this is our first on light, store this index for later jus in case.
      if (firstOnLED == -1)
      {
        firstOnLED = index + 14;
      }
     
      // If this light is on and it is an iteration above our current
      // light index, swap to this light as our current and bail.
      if (index + 14 > currentLight)
      {
        currentLight = index + 14;
        return;
      }
    }
  }

  // Iterate through each LED index on the 'hours' display and find the one that
  // is on and is at an index above our currently lit LED.
  for (int index = 0; index < 1; ++index)
  {
    int isOn = bitRead(onAmPmBits, index);
   
    // If the light is on, this is a potential switch.
    if (isOn)
    {
      // if this is our first on light, store this index for later jus in case.
      if (firstOnLED == -1)
      {
        firstOnLED = index + 18;
      }
     
      // If this light is on and it is an iteration above our current
      // light index, swap to this light as our current and bail.
      if (index + 18 > currentLight)
      {
        currentLight = index + 18;
        return;
      }
    }
  }
 
  // If we have gone through all lights and have not swapped our current
  // light.  Auto swap to the very first on light, creating a loop.
  // As an artifact, if there was no first light, then it will just
  // set the current light to no light as well.
  currentLight = firstOnLED;
}


Ik hoop dat er iemand is die mij hiermee kan helpen.

Advertisement

Gebruikers-avatar
Berichten: 5043
Geregistreerd: 13 Mei 2013, 20:57
Woonplaats: Heemskerk

Re: Binaire klok

Berichtdoor nicoverduin » 24 Okt 2013, 18:02

Ik ben nog bezig te proberen het te begrijpen :) Maar als ik het goed begrijp is de bedoeling:

Per seconde telt hij op binair (maar dan zou je aan 6 leds voldoende hebben (2^6 = 64)
en hoe zit het dan met de minuten en uren?

En jammer dat ie niet ff een schema erbij heeft gedaan......
Docent HBO Technische Informatica, Embedded ontwikkelaar & elektronicus
http://www.verelec.nl

Berichten: 21
Geregistreerd: 27 Feb 2013, 15:17

Re: Binaire klok

Berichtdoor Dedier » 24 Okt 2013, 20:53

Hierbij een zelf gemaakt schema. https://www.dropbox.com/s/ikvws62o66scly4/schema.png het schema was te groot om hier te kunnen uploaden en daarom via een dropbox link.
In mijn schema gebruik ik een atmega 8 ipv een arduino omdat ik het als stand alone wil gebruiken. En heb ik voor de ledjes weerstandjes geplaatst voor de zekerheid. Ik hoop dat het helpt.
Hoe de klok werkt: de eerste 4 rode ledjes geven de eerste 15 seconden aan. Zodra deze vol zijn gaat de 2e rij met ledjes het eerste lampje branden wat dus 16 seconden aangeeft. Vervolgens telt de eerste rij weer door tot 15 en zo door. Na 60 seconden gaan alle rode ledjes uit en gaat het eerste groene ledje aan. Wat op de zelfde manier als de seconden telt. Na een uur gaan de minuten ledjes ook uit en gaat het uren klokje branden. na 12 uur reset deze zich ook en gaat het meest linker lampje branden. Dit laat AM en PM zien. Ik hoop dat het zo duidelijk uitgelegd is en dat je wat aan mijn schema hebt. Alvast heel erg bedankt voor de hulp.

Gebruikers-avatar
Berichten: 270
Geregistreerd: 30 Dec 2012, 11:42

Re: Binaire klok

Berichtdoor Rudi » 24 Okt 2013, 21:35

Het is niet zo een goed idee om zonder voorschakelweerstanden te werken als je je Arduino lang wil blijven gebruiken.
Wanneer je voor iedere gecharlieplexte led een weerstand gebruikt zoals in je schema dan vrees ik dat de lichtopbrengst wat minder gaat zijn.
Waarschijnlijk ga je het beste resultaat hebben door een voorschakelweerstand van pakweg 100 ohm tussen ieder van de 5 stuurlijnen (pin 8 t/m 12) en de leds te plaatsen.
Arduinows!
Why do computer programmers confuse Halloween with Christmas? Because Oct 31 = Dec 25
I got 01100011 problems but a bit ain't 00000001

Berichten: 21
Geregistreerd: 27 Feb 2013, 15:17

Re: Binaire klok

Berichtdoor Dedier » 24 Okt 2013, 21:46

En dan een voorschakel weerstand tussen pin en dan ground? Of bedoel je dat anders?

Gebruikers-avatar
Berichten: 5043
Geregistreerd: 13 Mei 2013, 20:57
Woonplaats: Heemskerk

Re: Binaire klok

Berichtdoor nicoverduin » 24 Okt 2013, 22:59

tussen de pin en het signaal.
Docent HBO Technische Informatica, Embedded ontwikkelaar & elektronicus
http://www.verelec.nl

Berichten: 21
Geregistreerd: 27 Feb 2013, 15:17

Re: Binaire klok

Berichtdoor Dedier » 24 Okt 2013, 23:10

Ow ja tuurlijk. Bedankt. Was mijn uitleg een beetje te begrijpen?

Berichten: 21
Geregistreerd: 27 Feb 2013, 15:17

Re: Binaire klok

Berichtdoor Dedier » 25 Okt 2013, 11:49

Ik heb nu een voorschakel weerstand geplaatst. En je hebt gelijk het werkt beter dan een weerstandje voor elk ledje. Maar ik blijf het probleem houden dat ledjes branden terwijl dit niet de bedoeling is. Ik heb al geprobeerd in de code de lastLEDswitch en LEDRefreshRate aan te passen maar dit had minimaal effect. Ik denk dat het te maken heeft dat de input/output niet goed gedefinieerd is. Zou dat een mogelijkheid zijn?

Gebruikers-avatar
Berichten: 5043
Geregistreerd: 13 Mei 2013, 20:57
Woonplaats: Heemskerk

Re: Binaire klok

Berichtdoor nicoverduin » 25 Okt 2013, 12:22

Je weet zeker dat de bedrading helemaal goed is?
Docent HBO Technische Informatica, Embedded ontwikkelaar & elektronicus
http://www.verelec.nl

Berichten: 21
Geregistreerd: 27 Feb 2013, 15:17

Re: Binaire klok

Berichtdoor Dedier » 25 Okt 2013, 12:51

Ja ik ben er vrij zeker van dat de bedrading juist is. Anders zou de klok waarschijnlijk niet helemaal werken. Want hij werkt wel gewoon goed alleen soms gaan er lampjes aan wanneer dit niet moet. Ik heb een fotootje gemaakt hierbij zie je dat de rode lampjes wel gewoon aan gaan zoals het hoort. En een groen lampje wat heel zwak brand, wat dus niet hoort.
IMAG0175 (640x362).jpg
IMAG0175 (640x362).jpg (175.97 KiB) 10714 keer bekeken

Volgende

Terug naar Arduino software

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 51 gasten