Go Down

Topic: 7 Segment Library for Arduino 1.0 (Read 3007 times) previous topic - next topic

Qtechknow

Hi Everyone,
I was just wanting to make a 7 segment display library.  I was going to name it soda.  The first file I have here is the .h file.   
Code: [Select]

#ifndef Soda_h
#define Soda_h

#include "Arduino.h"

class Soda
{
public:
    void pins(int a, int b, int c, int d, int e, int f, int g, int dp);
   
    void setup();
   
    void write(int number);
   
private:
    int a, b, c, d, e, f, g, dp, number;
};

#endif


And here is the .cpp file to go along with it.

Code: [Select]
#include "Arduino.h"
#include "Soda.h"

void Soda::pins(int a, int b, int c, int d, int e, int f, int g, int dp) {
   
    const byte numeral[10] = {
        B11111100,  // 0
        B01100000,  // 1
        B11011010,  // 2
        B11110010,  // 3
        B01100110,  // 4
        B10110110,  // 5
        B10111110,  // 6
        B11100000,  // 7
        B11111110,  // 8
        B11100110,  // 9
    };
   
    const int segmentPins[8] = { dp, g, f, e, d, c, b, a };
   
}

void Soda::setup()  {
   
    for(int i=0; i < 8; i++) {
       
        pinMode(segmentPins[i], OUTPUT);
    }
}

void Soda::write(int number) {
    boolean isBitSet;
   
    for(int segment=1; segment < 8; segment++) {
        if(number < 0 || number > 9) {
            isBitSet = 0;
        }
        else{
            isBitSet = bitRead(numberal[number], segment);
        }
        isBitSet = ! isBitSet;
        digitalWrite(segmentPins[segment], isBitSet);
    }
}



When I compile a simple program, like the one below, I get the error message "SodaDemo:6: error: expected constructor, destructor, or type conversion before '.' token"  I am not sure why.  I think that you are allowed to have multiple integers in a "void"?

Code: [Select]
// Soda Demo

#include <Soda.h>

Soda Soda;

Soda.pins(2, 3, 4, 5, 6, 7, 8, 9);

void setup() {
  Soda.setup();
}

void loop() {
  for(int i=0; i<10; i++) {
    Soda.write(i);
    delay(1000);
  }
}


Thanks,
Qtechknow

WizenedEE

You need to put the soda.pins(...) call inside setup()

By the way, it's not called a void (that's the return type), it's a function (or a member function since it's in a class)

Qtechknow

#2
Apr 13, 2012, 01:40 am Last Edit: Apr 13, 2012, 02:22 am by Qtechknow Reason: 1
Thanks for the reply.  Would it be an int, byte, or void?  Oh, and by the way, here is the most recent code.  First is the .cpp then the .h.  When I compile the sketch up above (without the soda.pins function) I get the error message in the Arduino IDE,

/Users/hereismyrealname/Documents/Arduino/libraries/Soda/Soda.cpp: In member function 'void Soda::write(int)':
/Users/hereismyrealname/Documents/Arduino/libraries/Soda/Soda.cpp:46: error: 'numeral' was not declared in this scope
/Users/hereismyrealname/Documents/Arduino/libraries/Soda/Soda.cpp:49: error: 'segmentPins' was not declared in this scope

Any Help?

Code: [Select]
#include "Arduino.h"
#include "Soda.h"

Soda::Soda()
{
   const byte numeral[10] = {
       B11111100,  // 0
       B01100000,  // 1
       B11011010,  // 2
       B11110010,  // 3
       B01100110,  // 4
       B10110110,  // 5
       B10111110,  // 6
       B11100000,  // 7
       B11111110,  // 8
       B11100110,  // 9
   };
}
int Soda::pins(int a, int b, int c, int d, int e, int f, int g, int dp) {
   
   const int segmentPins[8] = { dp, g, f, e, d, c, b, a };
   
   for(int i=0; i < 8; i++) {
       
       pinMode(segmentPins[i], OUTPUT);
   }
   
   
}

void Soda::write(int number) {
   boolean isBitSet;
   
   for(int segment=1; segment < 8; segment++) {
       if(number < 0 || number > 9) {
           isBitSet = 0;
       }
       else{
           isBitSet = bitRead(numberal[number], segment);
       }
       isBitSet = ! isBitSet;
       digitalWrite(segmentPins[segment], isBitSet);
   }
}


And here is the .h file.

Code: [Select]
#ifndef Soda_h
#define Soda_h

#include "Arduino.h"

class Soda
{
public:
   int pins(int a, int b, int c, int d, int e, int f, int g, int dp);
   
   void Soda();
   void write(int number);
   
private:
   int a, b, c, d, e, f, g, dp, number, hi;
};

#endif

WizenedEE

numeral is a local variable to the constructor (the Soda::Soda()), and segmentPins is a local variable to the pins() function. You need to make them class variables by declaring them inside the class declaration (in the .h file)

Code: [Select]

#ifndef Soda_h
#define Soda_h

#include "Arduino.h"

class Soda
{
public:
    int pins(int a, int b, int c, int d, int e, int f, int g, int dp);
   
    void Soda();
    void write(int number);
   
private:
    int a, b, c, d, e, f, g, dp, number, hi;
    int segmentPins[8];
    int numeral[10];
};

#endif


If you do that, you'll also have to change the definitions where you put in the values. You'll have to assign each numer separately:
Code: [Select]

numeral[0] = B11010100;
numeral[1] = B00011000;
numeral[2] = ...


and same for segmentPins

lloyddean

#4
Apr 14, 2012, 05:10 am Last Edit: Apr 15, 2012, 06:07 am by lloyddean Reason: 1
No further response so, a possible simple (and untested) implementation.

Code: [Select]

/* =====================================================================================================================
* File - Soda.h
* ---------------------------------------------------------------------------------------------------------------------
*/

#ifndef Soda_H
#define Soda_H


/* =====================================================================================================================
* ---------------------------------------------------------------------------------------------------------------------
*/

class Soda
{
public:
   enum { A,  B,  C,  D,  E,  F,  G,  DP, PIN_COUNT, SEG_COUNT = DP };


   Soda(   const uint8_t segOff, const uint8_t segOn
       ,   uint8_t segA, uint8_t segB, uint8_t segC, uint8_t segD, uint8_t segE, uint8_t segF, uint8_t segG
       ,   uint8_t segDP);

   void write(uint8_t const digit);                        // Display Numeral
   void write(uint8_t const segment, bool const state);    // Turn Segment Off, On

private:
   // --- Instance Constants
   const uint8_t   kSEG_OFF;
   const uint8_t   kSEG_ON;

   uint8_t         _pins[PIN_COUNT];

   void init(uint8_t segA, uint8_t segB, uint8_t segC, uint8_t segD, uint8_t segE, uint8_t segF, uint8_t segG
       ,   uint8_t segDP);

   Soda();                                                 // don't allow accidental construction

};

#endif


Code: [Select]

/* =====================================================================================================================
* File - Soda.cpp
* ---------------------------------------------------------------------------------------------------------------------
*/

/* =====================================================================================================================
* ---------------------------------------------------------------------------------------------------------------------
*/

#if defined(ARDUINO) && ARDUINO >= 100
 #include "Arduino.h"
#else
 #include "WProgram.h"
#endif

#include "Soda.h"


/* =====================================================================================================================
* ---------------------------------------------------------------------------------------------------------------------
*/

Soda::Soda(
       const uint8_t segOff, const uint8_t segOn
   ,   uint8_t segA, uint8_t segB, uint8_t segC, uint8_t segD, uint8_t segE, uint8_t segF, uint8_t segG, uint8_t segDP)

   :   kSEG_OFF(segOff),  kSEG_ON(segOn)
{
   init(segA, segB, segC, segD, segE, segF, segG, segDP);
}


/* =====================================================================================================================
* ---------------------------------------------------------------------------------------------------------------------
*/

void Soda::init(
     uint8_t segA, uint8_t segB, uint8_t segC, uint8_t segD, uint8_t segE, uint8_t segF, uint8_t segG, uint8_t segDP)
{
   uint8_t*    ptrDst  = _pins;

   *ptrDst++   = segA;
   *ptrDst++   = segB;
   *ptrDst++   = segC;
   *ptrDst++   = segD;
   *ptrDst++   = segE;
   *ptrDst++   = segF;
   *ptrDst++   = segG;

   *ptrDst++   = segDP;

   for ( size_t i = PIN_COUNT; i--; )
   {
       pinMode(_pins[i], OUTPUT);

       digitalWrite(_pins[i], kSEG_OFF);
   }
}


/* =====================================================================================================================
* ---------------------------------------------------------------------------------------------------------------------
*/

void Soda::write(uint8_t const digit)
{
   static const uint8_t   _bits[] =
   {
   //       ABCDEFG
         0b01111110    // 0
       , 0b00110000    // 1
       , 0b01101101    // 2
       , 0b01111001    // 3
       , 0b00110011    // 4
       , 0b01011011    // 5
       , 0b01011111    // 6
       , 0b01110000    // 7
       , 0b01111111    // 8
       , 0b01111011    // 9
   };

   uint8_t     bits = _bits[digit];

   for ( size_t i = SEG_COUNT; i--; bits >>= 1 )
   {
       digitalWrite(_pins[i], ((bits & 0b00000001) ? kSEG_ON : kSEG_OFF));
   }
}


/* =====================================================================================================================
* ---------------------------------------------------------------------------------------------------------------------
*/

void Soda::write(uint8_t segment, bool state)
{
   digitalWrite(_pins[segment], ((state) ? kSEG_ON : kSEG_OFF));
}


Code: [Select]

/* =====================================================================================================================
* File - Digit.pde
* ---------------------------------------------------------------------------------------------------------------------
*/

/* =====================================================================================================================
* ---------------------------------------------------------------------------------------------------------------------
*/

#if defined(ARDUINO) && ARDUINO >= 100
 #include "Arduino.h"
#else
 #include "WProgram.h"
#endif

#include "Soda.h"

const uint8_t pinSEG_A = 2;
const uint8_t pinSEG_B = 3;
const uint8_t pinSEG_C = 4;
const uint8_t pinSEG_D = 5;
const uint8_t pinSEG_E = 6;
const uint8_t pinSEG_F = 7;
const uint8_t pinSEG_G = 8;
const uint8_t pinSEG_DP = 9;

const uint8_t SEG_OFF = LOW;
const uint8_t SEG_ON = HIGH;


/* =====================================================================================================================
* ---------------------------------------------------------------------------------------------------------------------
*/

Soda    digit(SEG_OFF, SEG_ON, pinSEG_A, pinSEG_B, pinSEG_C, pinSEG_D, pinSEG_E, pinSEG_F, pinSEG_A, pinSEG_DP);


/* =====================================================================================================================
* ---------------------------------------------------------------------------------------------------------------------
*/

void loop()
{}


/* =====================================================================================================================
* ---------------------------------------------------------------------------------------------------------------------
*/

void setup()
{
   digit.write(Soda::A, true);     // Light Segment A
   digit.write(0);                 // Display Numeral Zero
}


EDIT:  Modified to suit your pin numbers!

Qtechknow

Hi all,
Thanks for the help.  I have edited the code, but in my example program, it gives me a ton of error messages.  Here is the current .h file. 
 
Code: [Select]
#ifndef Soda_h
#define Soda_h

#include "Arduino.h"

class Soda
{
public:
    uint8_t pins(int a, int b, int c, int d, int e, int f, int g, int dp);
    void write(int number);
   
private:
    int _a, _b, _c, _d, _e, _f, _g, _dp, _number;
    const byte numeral[10];
    const int segmentPins[8];
   
#endif


And here is the latest .cpp file.

Code: [Select]
#include "Arduino.h"
#include "Soda.h"

uint8_t Soda::pins(int a, int b, int c, int d, int e, int f, int g, int dp) {
   
    a=_a;
    b=_b;
    c=_c;
    d=_d;
    e=_e;
    f=_f;
    g=_g;
    dp=_dp;
   
    segmentPins[0] = _dp;
    segmentPins[1] = _g;
    segmentPins[2] = _f;
    segmentPins[3] = _e;
    segmentPins[4] = _d;
    segmentPins[5] = _c;
    segmentPins[6] = _b;
    segmentPins[7] = _a;
   
    for(int i=0; i < 8; i++) {
       
        pinMode(segmentPins[i], OUTPUT);
    }
   
   
}

void Soda::write(int number) {
    boolean isBitSet;
   
    numeral[0] = B11111100;  // 0
    numeral[1] = B01100000;  // 1
    numeral[2] = B11011010;  // 2
    numeral[3] = B11110010;  // 3
    numeral[4] = B01100110;  // 4
    numeral[5] = B10110110;  // 5
    numeral[6] = B10111110;  // 6
    numeral[7] = B11100000;  // 7
    numeral[8] = B11111110;  // 8
    numeral[9] = B11100110;  // 9
   
    for(int segment=1; segment < 8; segment++) {
        if(number < 0 || number > 9) {
            isBitSet = 0;
        }else{
            isBitSet = bitRead(numeral[number], segment);
        }
        isBitSet = ! isBitSet;
        digitalWrite(segmentPins[segment], isBitSet);
    }
}


And here is the example code in the Arduino IDE.

Code: [Select]
// Soda Demo

#include "Soda.h"

void setup() {
  Soda.pins(2, 3, 4, 5, 6, 7, 8, 9);
}

void loop() {
  for(int i=0; i<10; i++) {
    Soda.write(i);
    delay(1000);
  }
}


I get the following error messages after I compile.

Code: [Select]

SodaDemo:4: error: 'void Soda::setup()' cannot be overloaded
SodaDemo:2: error: with 'void Soda::setup()'
SodaDemo:8: error: 'void Soda::loop()' cannot be overloaded
SodaDemo:3: error: with 'void Soda::loop()'
SodaDemo:13: error: expected `}' at end of input
SodaDemo.cpp: In member function 'void Soda::setup()':
SodaDemo:5: error: expected unqualified-id before '.' token
SodaDemo.cpp: In member function 'void Soda::loop()':
SodaDemo:10: error: expected unqualified-id before '.' token
SodaDemo.cpp: At global scope:
SodaDemo:13: error: expected unqualified-id at end of input


Any help?

lloyddean

#6
Apr 14, 2012, 08:22 pm Last Edit: Apr 14, 2012, 09:12 pm by lloyddean Reason: 1
Soda.h

Needs '};' before '#endif'

Soda.cpp

Your assignments

   a=_a;
   ...

need to be reversed

  _a=a;

Soda Demo

 Soda.pins(2, 3, 4, 5, 6, 7, 8, 9);

In this case 'pins(...)' is NOT a class method.

You probably meant something along the line of (at global scope)

   Soda    soda;

and change all occurences of 'Soda.' with 'soda.'

Example

    soda.pins(2, 3, 4, 5, 6, 7, 8, 9);

etc ...

EDIT:  There may be other issues as I didn't spend much time looking at, or bother trying, to compile the code you provided

Qtechknow

Thanks for the replies. I still have the following error message though.

Code: [Select]

SodaDemo:2: error: new types may not be defined in a return type
SodaDemo.cpp:6: note: (perhaps a semicolon is missing after the definition of 'Soda')
SodaDemo:2: error: two or more data types in declaration of 'setup'
SodaDemo:4: error: structure 'soda' with uninitialized const members


Could anyone help?

WizenedEE

You need to make an instance of the Soda object before you can use it:
Code: [Select]

Soda digit;

void setup() {
  digit.pins(...);
}

void loop() {
  digit.write(...);
}


If you get more errors, please post the latest revision again, so we don't have to guess at what changes you made.

Qtechknow

Sorry for the confusion.  Here are the latest files.  I am still getting an error message though.

Soda Demo:

Code: [Select]
// Soda Demo

#include "Soda.h"

Soda soda;

void setup() {
  soda.pins(2, 3, 4, 5, 6, 7, 8, 9);
}

void loop() {
  for(int i=0; i<10; i++) {
    soda.write(i);
    delay(1000);
  }
}


Soda.h

Code: [Select]
#ifndef Soda_h
#define Soda_h

#include "Arduino.h"

class Soda
{
public:
    uint8_t pins(int a, int b, int c, int d, int e, int f, int g, int dp);
    void write(int number);
   
private:
    int _a, _b, _c, _d, _e, _f, _g, _dp, _number;
    const byte numeral[10];
    const int segmentPins[8];
}

#endif


Soda.cpp
Code: [Select]
#include "Soda.h"

uint8_t Soda::pins(int a, int b, int c, int d, int e, int f, int g, int dp) {

    _a=a;
    _b=b;
    _c=c;
    _d=d;
    _e=e;
    _f=f;
    _g=g;
    _dp=dp;
   
    segmentPins[0] = _dp;
    segmentPins[1] = _g;
    segmentPins[2] = _f;
    segmentPins[3] = _e;
    segmentPins[4] = _d;
    segmentPins[5] = _c;
    segmentPins[6] = _b;
    segmentPins[7] = _a;
   
    for(int i=0; i < 8; i++) {
       
        pinMode(segmentPins[i], OUTPUT);
    }
   
   
}

void Soda::write(int number) {
    boolean isBitSet;
   
    numeral[0] = B11111100;  // 0
    numeral[1] = B01100000;  // 1
    numeral[2] = B11011010;  // 2
    numeral[3] = B11110010;  // 3
    numeral[4] = B01100110;  // 4
    numeral[5] = B10110110;  // 5
    numeral[6] = B10111110;  // 6
    numeral[7] = B11100000;  // 7
    numeral[8] = B11111110;  // 8
    numeral[9] = B11100110;  // 9
   
    for(int segment=1; segment < 8; segment++) {
        if(number < 0 || number > 9) {
            isBitSet = 0;
        }else{
            isBitSet = bitRead(numeral[number], segment);
        }
        isBitSet = ! isBitSet;
        digitalWrite(segmentPins[segment], isBitSet);
    }
}


And here is the same error message that comes up with soda demo.

Code: [Select]
SodaDemo:2: error: new types may not be defined in a return type
SodaDemo.cpp:6: note: (perhaps a semicolon is missing after the definition of 'Soda')
SodaDemo:2: error: two or more data types in declaration of 'setup'
SodaDemo:4: error: structure 'soda' with uninitialized const members


Any Help?

Thanks,
Qtechknow

lloyddean

You still need a semi-colon following that last '}' in Soda.h

Qtechknow

Thanks for the answers.  The library is successfully working.  The only thing is, I would like to drive two digits now.  Here are the most recent files.

The .h file

Code: [Select]
#ifndef Soda_h
#define Soda_h

#include "Arduino.h"

class Soda
{
public:
    uint8_t pins(int a, int b, int c, int d, int e, int f, int g, int dp, boolean common);
    void write(int number);
   
private:
    int _a, _b, _c, _d, _e, _f, _g, _dp, _number;
    byte numeral[10];
    int segmentPins[8];
    boolean _common;
};

#endif


The current .cpp file.
Code: [Select]
#include "Arduino.h"
#include "Soda.h"

uint8_t Soda::pins(int a, int b, int c, int d, int e, int f, int g, int dp, boolean common) {

    _a=a;
    _b=b;
    _c=c;
    _d=d;
    _e=e;
    _f=f;
    _g=g;
    _dp=dp;
    _common=common;
   
    segmentPins[0] = _dp;
    segmentPins[1] = _g;
    segmentPins[2] = _f;
    segmentPins[3] = _e;
    segmentPins[4] = _d;
    segmentPins[5] = _c;
    segmentPins[6] = _b;
    segmentPins[7] = _a;
   
    for(int i=0; i < 8; i++) {
       
        pinMode(segmentPins[i], OUTPUT);
    }
   
   
}

void Soda::write(int number) {
    boolean isBitSet;
   
    numeral[0] = B11111100;  // 0
    numeral[1] = B01100000;  // 1
    numeral[2] = B11011010;  // 2
    numeral[3] = B11110010;  // 3
    numeral[4] = B01100110;  // 4
    numeral[5] = B10110110;  // 5
    numeral[6] = B10111110;  // 6
    numeral[7] = B11100000;  // 7
    numeral[8] = B11111110;  // 8
    numeral[9] = B11100110;  // 9

    if (_common == HIGH) {

    for(int segment=1; segment < 8; segment++) {
        if(number < 0 || number > 9) {
            isBitSet = 0;
        }else{
            isBitSet = bitRead(numeral[number], segment);
        }
        isBitSet = ! isBitSet;
        digitalWrite(segmentPins[segment], isBitSet);
      }
    }
        if (_common == LOW) {
            for(int segment=1; segment < 8; segment++) {
                if(number < 0 || number > 9) {
                    isBitSet = 0;
                }else{
                    isBitSet = bitRead(numeral[number], segment);
                }
                digitalWrite(segmentPins[segment], isBitSet);
            }
        }
}


And the program I'm trying to run.

Code: [Select]
/* Soda Demo

Uses the soda library from Qtechknow.  Counts to 9 and then goes back to 0 on
a seven segment display. 

created 14 Apr 12
Made by Quin (Qtechknow)
*/

#include "Soda.h"

Soda Soda;   // initialize the first display
Soda Soda2;  // initialize the second display

void setup() {
// Segments A, B, C, D, E, F, G, DP pin numbers
  Soda.pins(2, 3, 4, 5, 6, 7, 8, 9, HIGH);  // set high for common anode, and
  Soda2.pins(10, 11, 12, 13, A0, A1, A2, A3, HIGH);  // low for common cathode display
}

void loop() {

  for(int i=0; i< 10; i++) {
    Soda.write(i);        // count to 9
    Soda2.write(i);
    delay(1000);          // delay for 1 second
  }
}


These are the error messages.
Code: [Select]
SodaDemo:12: error: 'Soda' does not name a type
SodaDemo.cpp: In function 'void setup()':
SodaDemo:17: error: 'Soda2' was not declared in this scope
SodaDemo.cpp: In function 'void loop()':
SodaDemo:24: error: 'Soda2' was not declared in this scope


Any Help?

Thanks,
Qtechknow

AWOL

#12
Apr 15, 2012, 09:00 pm Last Edit: Apr 15, 2012, 09:15 pm by AWOL Reason: 1
Your handling of common node vs. common cathode seems to repeat the same code, when all that is needed is a simple inversion.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Qtechknow

Do you know how to use 2 7-segment displays?

AWOL

#14
Apr 15, 2012, 09:17 pm Last Edit: Apr 15, 2012, 10:01 pm by AWOL Reason: 1
Instantiate a second object?

http://arduino.cc/forum/index.php/topic,8764.msg71789.html#msg71789
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Go Up