Go Down

Topic: Arduino parking lot project- problem with code (Read 186 times) previous topic - next topic

nick13

Hello guys, i have been working on a project which is a parking lot that can get up to 30 cars. It has a counter that counts the car entering and leaving the parking, then displays the available space to a 2digit 7 segment led. My problem is that while everything works fine until the number 9, then i cant display the 2digit numbers. Probably is my code, so i need some ideas..
Code: [Select]
#include <Servo.h>
Servo myservo;  // create servo object to control a servo

#define ServoM    12        //Connected to the servo motor.
#define Bright    11        //servo library disable PWM on pins 9 and 10.
#define  CA1      11
#define  CA2      10
#define Exit      9         //Pin connected to the EXIT button.
#define In        8         //Pin connected to the IN button.

#define BarLow    177       //Low position of the barrier.
#define BarUp     95        //Up position of the barrier.
#define CAPACITY  30         //Capacity of the parking lot.
#define INTEN     80        //Display intensity %

//Pins conections to segments (cathodes).
#define  segA  0
#define  segB  1
#define  segC  2
#define  segD  3
#define  segE  4
#define  segF  5
#define  segG  6

//Array with the segments to represent the decimal numbers (0-9).
byte segments[10] = {
// pgfedcba  <--- segments
  B00111111, // number 0
  B00000110, // number 1
  B01011011, // number 2
  B01001111, // number 3
  B01100110, // number 4
  B01101101, // number 5
  B01111101, // number 6
  B00000111, // number 7
  B01111111, // number 8
  B01101111  // number 9
};

void setup(){
  myservo.attach(ServoM);          // attaches the servo.

  pinMode(Exit, INPUT);           // set "EXIT" button pin to input
  pinMode(In, INPUT);             // set "IN" button pin to input
  digitalWrite(Exit, HIGH);       // Connect Pull-Up resistor.
  digitalWrite(In, HIGH);         // Connect Pull-Up resistor.
  pinMode(segA,OUTPUT);
  pinMode(segB,OUTPUT);
  pinMode(segC,OUTPUT);
  pinMode(segD,OUTPUT);
  pinMode(segE,OUTPUT);
  pinMode(segF,OUTPUT);
  pinMode(segG,OUTPUT);
  pinMode(CA1,OUTPUT);
  pinMode(CA2,OUTPUT);
  analogWrite(Bright,255*INTEN/100);
  myservo.write(BarLow);          //Barrier in the low position
//  delay(1000);
}

int  Available= 30;                    // Number of places available.

//================================================================
void loop(){
Display(Available);
if(digitalRead(In)==0)
{
  if(Available != 0){
    Available--;
    myservo.write(BarUp);
    delay(3000);
    myservo.write(BarLow);
    }
  }
if(digitalRead(Exit)==0)
{
  if(Available != CAPACITY){
    Available++;
    myservo.write(BarUp);
    delay(3000);
    myservo.write(BarLow);
    }
  }
}

/*-------------------------------------------------------------------
Put the segments according to the number.
--------------------------------------------------------------------*/
void Display(int number){
byte segs =  segments[number]; 
if (Available <= 9) {
digitalWrite(CA1,LOW);
digitalWrite(CA2,HIGH);
digitalWrite(segA, bitRead(segs, 0) );
digitalWrite(segB, bitRead(segs, 1) );
digitalWrite(segC, bitRead(segs, 2) );
digitalWrite(segD, bitRead(segs, 3) );
digitalWrite(segE, bitRead(segs, 4) );
digitalWrite(segF, bitRead(segs, 5) );
digitalWrite(segG, bitRead(segs, 6) );
}
if(Available > 9){
digitalWrite(CA1,HIGH);
digitalWrite(CA2,HIGH);
digitalWrite(segA, bitRead(segs, 0) );
digitalWrite(segB, bitRead(segs, 1) );
digitalWrite(segC, bitRead(segs, 2) );
digitalWrite(segD, bitRead(segs, 3) );
digitalWrite(segE, bitRead(segs, 4) );
digitalWrite(segF, bitRead(segs, 5) );
digitalWrite(segG, bitRead(segs, 6) );
}
}
  cant find out what loop needs in the diplay function..

sterretje

#1
Aug 13, 2017, 12:41 pm Last Edit: Aug 13, 2017, 12:42 pm by sterretje
This is a bug
Code: [Select]
  byte segs =  segments[number];

What happens if number is greater than or equal to 10? You will access something that is not part of the segments array.

This also might not work
Code: [Select]
  if (Available <= 9)
  {
    digitalWrite(CA1, LOW);
    digitalWrite(CA2, HIGH);

...
...
  if (Available > 9)
  {
    digitalWrite(CA1, HIGH);
    digitalWrite(CA2, HIGH);

CA meaning common anode? If so, in the one if you switch one display on (or off), in the other you switch both displays on (or off) and they will display the same data.
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

nick13

No my led is common cathode. So i cant diplay different digits?

sterretje

That's not what I said. So when you make the CA pin low, the display it will light up. In which case the question is why you make both CA pins HIGH when you want to display two digits?
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

kenwood120s

You may find it useful to have a look at the seven segment display library here in the playground.


nick13

Yeah that was my bad, what do you suggest? How should i display both of the digits?

sterretje

Code: [Select]
/*-------------------------------------------------------------------
  Put the segments according to the number.
  IN:
    number  the number to display
  --------------------------------------------------------------------*/
void Display(int number)
{
  // 'filter' least significant digit
  byte segs =  segments[number % 10];

  // and always display it
  digitalWrite(CA1, LOW);
  digitalWrite(CA2, HIGH);
  digitalWrite(segA, bitRead(segs, 0) );
  digitalWrite(segB, bitRead(segs, 1) );
  digitalWrite(segC, bitRead(segs, 2) );
  digitalWrite(segD, bitRead(segs, 3) );
  digitalWrite(segE, bitRead(segs, 4) );
  digitalWrite(segF, bitRead(segs, 5) );
  digitalWrite(segG, bitRead(segs, 6) );

  // if more than one digit
  if (number > 9)     <-- changed this to use number instead of Available
  {
    // 'filter' most significant digit
    segs =  segments[number / 10];

    digitalWrite(CA1, HIGH);
    digitalWrite(CA2, LOW);
    digitalWrite(segA, bitRead(segs, 0) );
    digitalWrite(segB, bitRead(segs, 1) );
    digitalWrite(segC, bitRead(segs, 2) );
    digitalWrite(segD, bitRead(segs, 3) );
    digitalWrite(segE, bitRead(segs, 4) );
    digitalWrite(segF, bitRead(segs, 5) );
    digitalWrite(segG, bitRead(segs, 6) );
  }
  else
  {
    // switch most significant digit off
    digitalWrite(CA2, HIGH);
  }
}

I made one other change as it does not make sens to me to pass a number and next use Available as well.

I further suggest that you change
Code: [Select]
int  Available = 30;                   // Number of places available.

to
Code: [Select]
int  Available = CAPACITY;

So when changing the capacity, you only have to do it in one place.
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

nick13

It seems that there is a bug, at the start it just lights up all the sgments (88) and when the button is pushed just decreases one number and then goes again to 88... :/

sterretje

For the '88', you need a start value. E.g. in setup, call Display(Available).

You're basically on your own for the debugging; code looks OK to me and is purely based on my interpretation  of what you provided earlier. You can write a small test loop in setup
Code: [Select]

for(int cnt=0;cnt<=30;cnt++)
{
  Display(cnt);
  delay(500);
}


For more help, please provide a diagram (photo/scan of hand-drawn one is OK).
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

nick13

Code: [Select]
Well it seems good but actually isnt..
[codebyte segs =  segments[number % 10];

  // and always display it
  digitalWrite(CA1, LOW);
  digitalWrite(CA2, HIGH);
  digitalWrite(segA, bitRead(segs, 0) );
  digitalWrite(segB, bitRead(segs, 1) );
  digitalWrite(segC, bitRead(segs, 2) );
  digitalWrite(segD, bitRead(segs, 3) );
  digitalWrite(segE, bitRead(segs, 4) );
  digitalWrite(segF, bitRead(segs, 5) );
  digitalWrite(segG, bitRead(segs, 6) );

  // if more than one digit
  if (number > 9)     <-- changed this to use number instead of Available
  {
    // 'filter' most significant digit
    segs =  segments[number / 10];

    digitalWrite(CA1, HIGH);
    digitalWrite(CA2, LOW);
    digitalWrite(segA, bitRead(segs, 0) );
    digitalWrite(segB, bitRead(segs, 1) );
    digitalWrite(segC, bitRead(segs, 2) );
    digitalWrite(segD, bitRead(segs, 3) );
    digitalWrite(segE, bitRead(segs, 4) );
    digitalWrite(segF, bitRead(segs, 5) );
    digitalWrite(segG, bitRead(segs, 6) );
  }
  else]
Yes it finds out the least significant digit and the most significant d, but it keeps the value from the previous one. In the start we have  CA1,LOW and CA2, HIGH and then CA1,HIGH and CA2,LOW. They are not separated so thats why i get 88 all segments on. I hope you understand what i mean. Maybe i need to find the solution from the seven segment library.

sterretje

How do you mean, not separated? CA1 and CA2 are on different pins.
How do you mean, keeps the previous value?

Please provide full schematic.
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

nick13




With the difference is use a 2 digit display

sterretje

Your diagram, not something copied that does not match what you have. Common cathode / common anode?
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

nick13

Common Cathode, thats the sketch i got the idea from

Go Up