Read 7segment displays from scale

Morning All.

I have tried the below to read the weight of a scale and output to cloud. However my readings are erratic and not correct. Could it be that the scale is switching between the 7 segments to fast and the Time hold is to little for the Argon to read correctly.

for testing I wrote some simple code just to see if I can get the correct values

include "Particle.h"
#include "wire.h"

/********************************************************************************************/
//SerialLogHandler logHandler(LOG_LEVEL_TRACE);

SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(AUTOMATIC);

bool DIGIT_CC_0;//hold value of weight LSB
bool DIGIT_CC_1;//hold value of weight 
bool DIGIT_CC_2;//hold value of weight 
bool DIGIT_CC_3;//hold value of weight 
bool DIGIT_CC_4;//hold value of weight MSB
bool segment_a;
bool segment_b;
bool segment_c;
bool segment_d;
bool segment_e;
bool segment_f;
bool segment_g;
bool segment_dp;


#define CC_0 A0//address line for digit 0
#define CC_1 A1//address line for digit 1
#define CC_2 A2//address line for digit 2
#define CC_3 A3//address line for digit 3
#define CC_4 A4//address line for digit 4
#define a D0//data read a from 7 segment
#define b D1//data read b from 7 segment
#define g D2//data read g from 7 segment
#define c D3//data read c from 7 segment
#define f D4//data read f from 7 segment
#define d D5//data read d from 7 segment
#define e D6//data read e from 7 segment
#define dp D7//data read dp from 7 segment

//setup remote cloud reset
#define DELAY_BEFORE_REBOOT 2000
unsigned int rebootDelayMillis = DELAY_BEFORE_REBOOT;
unsigned long rebootSync = millis();
bool resetFlag = false;

void setup() {
   //(void)logHandler; // Does nothing, just to eliminate the unused variable warning
  SYSTEM_MODE(AUTOMATIC);
  SYSTEM_THREAD(ENABLED);
  Particle.keepAlive(20);
  Serial.begin(115200);
  
  pinMode(CC_0, INPUT);//common cathode digit 0 LSB
  pinMode(CC_1, INPUT);//common cathode digit 1
  pinMode(CC_2, INPUT);//common cathode digit 2
  pinMode(CC_3, INPUT);//common cathode digit 3
  pinMode(CC_4, INPUT);//common cathode digit 4 MSB

  pinMode(a, INPUT);//7 segmant read
  pinMode(b, INPUT);//7 segmant read
  pinMode(c, INPUT);//7 segmant read
  pinMode(d, INPUT);//7 segmant read
  pinMode(e, INPUT);//7 segmant read
  pinMode(f, INPUT);//7 segmant read
  pinMode(g, INPUT);//7 segmant read
  pinMode(dp, INPUT);//7 segmant read
  digitalWrite (a, LOW);//off
  digitalWrite (b, LOW);//off
  digitalWrite (c, LOW);//off
  digitalWrite (d, LOW);//off
  digitalWrite (e, LOW);//off
  digitalWrite (f, LOW);//off
  digitalWrite (g, LOW);//off
  digitalWrite (CC_0, LOW);//off
  digitalWrite (CC_1, LOW);//off
  digitalWrite (CC_2, LOW);//off
  digitalWrite (CC_3, LOW);//of
}
void loop() {
  DIGIT_CC_0 = digitalRead(CC_0);//check if cc_1 selected
  DIGIT_CC_1 = digitalRead(CC_1);//check if cc_1 selected
  DIGIT_CC_2 = digitalRead(CC_2);//check if cc_1 selected
  DIGIT_CC_3 = digitalRead(CC_3);//check if cc_1 selected
  DIGIT_CC_4 = digitalRead(CC_4);//check if cc_1 selected

  Serial.printf("DIGIT_CC_0 :%d \n",DIGIT_CC_0);
  Serial.printf("DIGIT_CC_1 :%d \n",DIGIT_CC_1);
  Serial.printf("DIGIT_CC_2 :%d \n",DIGIT_CC_2);
  Serial.printf("DIGIT_CC_3 :%d \n",DIGIT_CC_3);
  Serial.printf("DIGIT_CC_4 :%d \n",DIGIT_CC_4);
          Serial.printf("\n");
             Serial.printf("\n");
 if ((DIGIT_CC_0 == 1)&&(DIGIT_CC_1 == 0)&&(DIGIT_CC_2 == 1)&&(DIGIT_CC_3 == 1)&&(DIGIT_CC_4 == 1)){  
     segment_a = digitalRead(D0);//
     segment_b = digitalRead(D1);//
     segment_c = digitalRead(D3);//
     segment_d = digitalRead(D5);//
     segment_e = digitalRead(D6);//
     segment_f = digitalRead(D4);//
     segment_g = digitalRead(D2);//
     
     Serial.printf("segment a:%d \n",segment_a);
    Serial.printf("segment b:%d \n",segment_b);
    Serial.printf("segment c:%d \n",segment_c);
    Serial.printf("segment d:%d \n",segment_d);
    Serial.printf("segment e:%d \n",segment_e);
    Serial.printf("segment f:%d \n",segment_f);
    Serial.printf("segment g:%d \n",segment_g);

   if ((segment_e == 1)&&(segment_d == 1)&&(segment_f == 1)&&(segment_c == 1)&&(segment_g == 1)&&(segment_b == 1)&&(segment_a == 1)){
     Serial.print("the number is 0\n");
   }
     if ((segment_e == 0)&&(segment_d == 0)&&(segment_f == 0)&&(segment_c == 1)&&(segment_g == 0)&&(segment_b == 1)&&(segment_a == 0)){
     Serial.print("the number is 1\n");
   }
  /*   if ((segment_e == 1)&&(segment_d == 1)&&(segment_f == 1)&&(segment_c == 1)&&(segment_g == 0)&&(segment_b == 1)&&(segment_a == 1)) {
     Serial.print("the number is 2\n");
   }
     if ((segment_e == 1)&&(segment_d == 1)&&(segment_f == 1)&&(segment_c == 1)&&(segment_g == 0)&&(segment_b == 1)&&(segment_a == 1)) {
     Serial.print("the number is 3\n");
   }
     if ((segment_e == 1)&&(segment_d == 1)&&(segment_f == 1)&&(segment_c == 1)&&(segment_g == 0)&&(segment_b == 1)&&(segment_a == 1)) {
     Serial.print("the number is 4\n");
   }
    if ((segment_e == 1)&&(segment_d == 1)&&(segment_f == 1)&&(segment_c == 1)&&(segment_g == 0)&&(segment_b == 1)&&(segment_a == 1)){
     Serial.print("the number is 5\n");
   }
    if ((segment_e == 1)&&(segment_d == 1)&&(segment_f == 1)&&(segment_c == 1)&&(segment_g == 0)&&(segment_b == 1)&&(segment_a == 1)){
     Serial.print("the number is 6\n");
   }
    if ((segment_e == 1)&&(segment_d == 1)&&(segment_f == 1)&&(segment_c == 1)&&(segment_g == 0)&&(segment_b == 1)&&(segment_a == 1)){
     Serial.print("the number is 7\n");
   }
    if ((segment_e == 1)&&(segment_d == 1)&&(segment_f == 1)&&(segment_c == 1)&&(segment_g == 0)&&(segment_b == 1)&&(segment_a == 1)){
     Serial.print("the number is 8\n");
   }
    if((segment_e == 1)&&(segment_d == 1)&&(segment_f == 1)&&(segment_c == 1)&&(segment_g == 0)&&(segment_b == 1)&&(segment_a == 1)){
     Serial.print("the number is 9\n");
   }*/
  }

}//end of main

//*****************************************************************************************
//Custom functions
//*****************************************************************************************
//Softdelay function
inline void softDelay(uint32_t msDelay){
 for (uint32_t ms = millis(); 
 millis() - ms < msDelay;  
 Particle.process());
}

The Argon should be able to detect the segments lighting up - but usually they are multiplexed and only on briefly - which makes for tricky logic. Personally I’d look for pins with (no) activity on them for xms and use that to figure out what segments are on/off. Keep in mind that while the segments are scanned the driver is also moving across the array, so it could be tricky.

Do you have a scope to hook up to the segments?

A note about your code;

  SYSTEM_MODE(AUTOMATIC);
  SYSTEM_THREAD(ENABLED);

This should not be called in setup, but right at the top of your code (as you’ve done).

When you set a pin as input it is configured as a high-impedance input, you should not be driving it low. If the intent is to set it as a pull_down you should configure it as INPUT_PULLDOWN
pinMode(a, INPUT);//7 segmant read
…
digitalWrite (a, LOW);//off

Your cathode PINs should be configured with pull-ups: INPUT_PULLUP

Your serial prints will eat up a lot of processing time, complete your readings before printing out the results.

2 Likes

Have you considered using interrupts to catch the individual digit scans?

1 Like

Chris thanks for that, I have amended as suggested, it is better but my output on my terminal just counts even when the reading is stable. i.e if I look at only one digit from the 5 the out put one every loop increase by 1. (1,2,3,4,5,6,7,8,9,0…then starts over)

I have also inverted the capture by looking at non active segments with the same result

I do have a 4 channel scope will hook it up this weekend to see what I can see.

#include "Particle.h"
#include "wire.h"

SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(AUTOMATIC);

bool DIGIT_CC_0;//hold value of weight LSB
bool DIGIT_CC_1;//hold value of weight 
bool DIGIT_CC_2;//hold value of weight 
bool DIGIT_CC_3;//hold value of weight 
bool DIGIT_CC_4;//hold value of weight MSB
bool segment_a;
bool segment_b;
bool segment_c;
bool segment_d;
bool segment_e;
bool segment_f;
bool segment_g;
bool segment_dp;

#define CC_0 A0//address line for digit 0
#define CC_1 A1//address line for digit 1
#define CC_2 A2//address line for digit 2
#define CC_3 A3//address line for digit 3
#define CC_4 A4//address line for digit 4
#define a D0//data read a from 7 segment
#define b D1//data read b from 7 segment
#define g D2//data read g from 7 segment
#define c D3//data read c from 7 segment
#define f D4//data read f from 7 segment
#define d D5//data read d from 7 segment
#define e D6//data read e from 7 segment
#define dp D7//data read dp from 7 segment

void setup() {
   //(void)logHandler; // Does nothing, just to eliminate the unused variable warning
  Particle.keepAlive(20);
  Serial.begin(115200);

  pinMode(CC_0, INPUT_PULLUP);//common cathode digit 0 LSB
  pinMode(CC_1, INPUT_PULLUP);//common cathode digit 1
  pinMode(CC_2, INPUT_PULLUP);//common cathode digit 2
  pinMode(CC_3, INPUT_PULLUP);//common cathode digit 3
  pinMode(CC_4, INPUT_PULLUP);//common cathode digit 4 MSB

  pinMode(a, INPUT_PULLDOWN);//7 segment read
  pinMode(b, INPUT_PULLDOWN);//7 segment read
  pinMode(c, INPUT_PULLDOWN);//7 segment read
  pinMode(d, INPUT_PULLDOWN);//7 segment read
  pinMode(e, INPUT_PULLDOWN);//7 segment read
  pinMode(f, INPUT_PULLDOWN);//7 segment read
  pinMode(g, INPUT_PULLDOWN);//7 segment read
  pinMode(dp, INPUT_PULLDOWN);//7 segment read
 
}
void loop() {
  DIGIT_CC_0 = digitalRead(CC_0);//check if cc_1 selected
  DIGIT_CC_1 = digitalRead(CC_1);//check if cc_1 selected
  DIGIT_CC_2 = digitalRead(CC_2);//check if cc_1 selected
  DIGIT_CC_3 = digitalRead(CC_3);//check if cc_1 selected
  DIGIT_CC_4 = digitalRead(CC_4);//check if cc_1 selected
  
//((DIGIT_CC_0 == 1)&&(DIGIT_CC_1 == 0)&&(DIGIT_CC_2 == 1)&&(DIGIT_CC_3 == 1)&&(DIGIT_CC_4 == 1)){  
 //try shorten the capture if statement --- same as above
 while (DIGIT_CC_0 == 1){ 
     segment_a = digitalRead(D0);//
     segment_b = digitalRead(D1);//
     segment_c = digitalRead(D3);//
     segment_d = digitalRead(D5);//
     segment_e = digitalRead(D6);//
     segment_f = digitalRead(D4);//
     segment_g = digitalRead(D2);//
  if ((segment_e == 1)&&(segment_d == 1)&&(segment_f == 1)&&(segment_c == 1)&&(segment_g == 0)&&(segment_b == 1)&&(segment_a == 1)){
     Serial.print("the number is 0\n");
     
   }
     else if ((segment_e == 0)&&(segment_d == 0)&&(segment_f == 0)&&(segment_c == 1)&&(segment_g == 0)&&(segment_b == 1)&&(segment_a == 0)){
     Serial.print("the number is 1\n");
      
   }
    else if ((segment_e == 1)&&(segment_d == 1)&&(segment_f == 1)&&(segment_c == 1)&&(segment_g == 0)&&(segment_b == 1)&&(segment_a == 1)) {
     Serial.print("the number is 2\n");
      
   }
     else if ((segment_e == 1)&&(segment_d == 1)&&(segment_f == 1)&&(segment_c == 1)&&(segment_g == 0)&&(segment_b == 1)&&(segment_a == 1)) {
     Serial.print("the number is 3\n");
      
   }
     else if ((segment_e == 1)&&(segment_d == 1)&&(segment_f == 1)&&(segment_c == 1)&&(segment_g == 0)&&(segment_b == 1)&&(segment_a == 1)) {
     Serial.print("the number is 4\n");
      
   }
    else if ((segment_e == 1)&&(segment_d == 0)&&(segment_f == 0)&&(segment_c == 0)&&(segment_g == 0)&&(segment_b == 1)&&(segment_a == 0)){
     Serial.print("the number is 5\n");
     
   }
    else if ((segment_e == 1)&&(segment_d == 1)&&(segment_f == 1)&&(segment_c == 1)&&(segment_g == 0)&&(segment_b == 1)&&(segment_a == 1)){
     Serial.print("the number is 6\n");
     
   }
    else if ((segment_e == 1)&&(segment_d == 1)&&(segment_f == 1)&&(segment_c == 1)&&(segment_g == 0)&&(segment_b == 1)&&(segment_a == 1)){
     Serial.print("the number is 7\n");
     
   }
    else if ((segment_e == 1)&&(segment_d == 1)&&(segment_f == 1)&&(segment_c == 1)&&(segment_g == 0)&&(segment_b == 1)&&(segment_a == 1)){
     Serial.print("the number is 8\n");
     
   }
    else if ((segment_e == 1)&&(segment_d == 1)&&(segment_f == 1)&&(segment_c == 1)&&(segment_g == 0)&&(segment_b == 1)&&(segment_a == 1)){
     Serial.print("the number is 9\n");
  
   }   
 }
}//end of main

@scruff think its worth a try I will set an interrupt for the digit then capture the display on that digit. Have not done interrupts before but sure i will find an example on this forum.

Thanks Guys

1 Like

I have managed to get this working over the weekend using interrupts :slight_smile: , and pinReadFast(). Code needs to be cleaned out but working 100%

Update code below but I was wondering about the following.

  1. the 7 segments that I capture as a Character array then convert to an INT is actually a Binary number. Is it possible to capture as Binary straight then use a 8421(BCD) conversion. This will allow me to get rid of the 5 switch statements.
  2. I am using atoi to convert the 7 segment “binary” char array to an INT which works perfectly. But when I take my final 5 digit Weight character array it does not convert to an INT using atoi. At first I thought it has something to do with NULL termination but whether I add it or not my INT weight remains zero.
#include "Particle.h"
#include "wire.h"

/********************************************************************************************/
//SerialLogHandler logHandler(LOG_LEVEL_TRACE);
char VARIABLE_LABEL[32] = "";//keeps the device name

char dev_name[32] = "";//keeps the device name
bool publishName = false;//to publich the name
SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(AUTOMATIC);

bool DIGIT_CC_0;//hold value of weight LSB
bool DIGIT_CC_1;//hold value of weight 
bool DIGIT_CC_2;//hold value of weight 
bool DIGIT_CC_3;//hold value of weight 
bool DIGIT_CC_4;//hold value of weight MSB
bool segment_a;
bool segment_b;
bool segment_c;
bool segment_d;
bool segment_e;
bool segment_f;
bool segment_g;
bool segment_dp;
char valueDigit_0_string [8];//holds the value of the 1 of 5 weight digits
char valueDigit_1_string [8];//holds the value of the 1 of 5 weight digits
char valueDigit_2_string [8];//holds the value of the 1 of 5 weight digits
char valueDigit_3_string [8];//holds the value of the 1 of 5 weight digits
char valueDigit_4_string [8];//holds the value of the 1 of 5 weight digits
char weight_complete [6];//hold the complete weight to send to cloud or serial port
int weight_complete_int = 0;//hold the string weight complete in int form 
int valueDigit_0 = 0;
int valueDigit_1 = 0;
int valueDigit_2 = 0;
int valueDigit_3 = 0;
int valueDigit_4 = 0;
int decimal_Digit_0 = 0;
int decimal_Digit_1 = 0;
int decimal_Digit_2 = 0;
int decimal_Digit_3 = 0 ;
int decimal_Digit_4 = 0 ;
int valueDigit_0_return = 0;
int valueDigit_1_return = 0;
int valueDigit_2_return = 0;
int valueDigit_3_return = 0;
int valueDigit_4_return = 0 ;
int valueDigit_sign = 0;

int savedweight;//holds a copy of the weight
int compareweight;//holds a copy of the weight


void Read_segment0(void);
void Read_segment1(void);
void Read_segment2(void);
void Read_segment3(void);
void Read_segment4(void);
#define CC_0 A0//address line for digit 0
#define CC_1 A1//address line for digit 1
#define CC_2 A2//address line for digit 2
#define CC_3 A3//address line for digit 3
#define CC_4 A4//address line for digit 4
#define a D0//data read a from 7 segment
#define b D1//data read b from 7 segment
#define g D2//data read g from 7 segment
#define c D3//data read c from 7 segment
#define f D4//data read f from 7 segment
#define d D5//data read d from 7 segment
#define e D6//data read e from 7 segment
#define dp D7//data read dp from 7 segment

//setup remote cloud reset
#define DELAY_BEFORE_REBOOT 2000
unsigned int rebootDelayMillis = DELAY_BEFORE_REBOOT;
unsigned long rebootSync = millis();
bool resetFlag = false;

// used for getting the device name
void Name_of_Device(const char *topic, const char *data){
 strncpy(dev_name, data, sizeof(dev_name)-1);
 Serial.printlnf("received in supscribe/publish request%s: %s", topic, dev_name);
 publishName = true;
 strncpy(VARIABLE_LABEL, dev_name, sizeof(dev_name));
 Serial.printlnf("variable label  that is copied from dev_name : %s", VARIABLE_LABEL);
}


void setup() {
   //(void)logHandler; // Does nothing, just to eliminate the unused variable warning
  Particle.keepAlive(20);
  Serial.begin(115200);

  pinMode(CC_0, INPUT_PULLUP);//common cathode digit 0 LSB
  attachInterrupt(CC_0, Read_segment0, FALLING);
  pinMode(CC_1, INPUT_PULLUP);//common cathode digit 1
  attachInterrupt(CC_1, Read_segment1, FALLING);
  pinMode(CC_2, INPUT_PULLUP);//common cathode digit 2
  attachInterrupt(CC_2, Read_segment2, FALLING);
  pinMode(CC_3, INPUT_PULLUP);//common cathode digit 3
  attachInterrupt(CC_3, Read_segment3, FALLING);
  pinMode(CC_4, INPUT_PULLUP);//common cathode digit 4 MSB
  attachInterrupt(CC_4, Read_segment4, FALLING);

  pinMode(a, INPUT_PULLDOWN);//7 segment read
  pinMode(b, INPUT_PULLDOWN);//7 segment read
  pinMode(c, INPUT_PULLDOWN);//7 segment read
  pinMode(d, INPUT_PULLDOWN);//7 segment read
  pinMode(e, INPUT_PULLDOWN);//7 segment read
  pinMode(f, INPUT_PULLDOWN);//7 segment read
  pinMode(g, INPUT_PULLDOWN);//7 segment read
  pinMode(dp, INPUT_PULLDOWN);//7 segment read
 
}

void loop() {

  valueDigit_0 = atoi(valueDigit_0_string);
  valueDigit_1 = atoi(valueDigit_1_string);
  valueDigit_2 = atoi(valueDigit_2_string);
  valueDigit_3 = atoi(valueDigit_3_string);
  valueDigit_4 = atoi(valueDigit_4_string);

    decimal_Digit_0 = valueDigit_0;
    weight_complete[0] = valueDigit_0_return;
    decimal_Digit_1 = valueDigit_1;
    weight_complete[1] = valueDigit_1_return;
    decimal_Digit_2 = valueDigit_2;
    weight_complete[2] = valueDigit_2_return;
    decimal_Digit_3 = valueDigit_3;
    weight_complete[3] = valueDigit_3_return;
    decimal_Digit_4 = valueDigit_4;
    weight_complete[4] = valueDigit_4_return;

//below is not working
  weight_complete_int = atoi(weight_complete); //This result in zero
  Serial.printf("weight complete int = : %d",weight_complete_int);//print zero?????????????????????

//below is sending correct value to serial port
       Serial.printf("Weight:%d%d%d%d%d g\n",weight_complete[4],weight_complete[3],weight_complete[2],weight_complete[1],weight_complete[0]);
      
// for the 5 digits build the number dislayed
switch (decimal_Digit_0) {
    case 1111011:
      //Serial.println("0");
      valueDigit_0_return = 0;
      break;
    case 1010:
       valueDigit_0_return = 1;
       break;
    case 1100111:
       //Serial.println("2");
       valueDigit_0_return = 2;
       break;
    case 101111:
       valueDigit_0_return = 3;
       break;
    case 11110:
       valueDigit_0_return = 4;
       break;
    case 111101:
       valueDigit_0_return = 5;
       break;
    case 1111101:
       //Serial.println("6");
       valueDigit_0_return = 6;
       break;
    case 1011:
       valueDigit_0_return = 7;
       break;
    case 1111111:
       valueDigit_0_return = 8;
       break;
    case 111111:
       valueDigit_0_return = 9;
       break;
    case 100://"-" on bit 0
       valueDigit_0_return = 0;
       valueDigit_1_return = 0;
       valueDigit_2_return = 0;
       valueDigit_3_return = 0;
       valueDigit_4_return = 0;
      break;
  }

switch (decimal_Digit_1) {
    case 1111011:
       valueDigit_1_return = 0;
      break;
    case 1010:
       valueDigit_1_return = 1;
       break;
    case 1100111:
       valueDigit_1_return = 2;
       break;
    case 101111:
       valueDigit_1_return = 3;
       break;
    case 11110:
       valueDigit_1_return = 4;
       break;
    case 111101:
      valueDigit_1_return = 5;
       break;
    case 1111101:
       valueDigit_1_return = 6;
       break;
    case 1011:
      valueDigit_1_return = 7;
       break;
    case 1111111:
       valueDigit_1_return = 8;
       break;
    case 111111:
       valueDigit_1_return = 9;
       break;
  }

switch (decimal_Digit_2) {
    case 1111011:
       valueDigit_2_return = 0;
      break;
    case 1010:
       valueDigit_2_return = 1;
       break;
    case 1100111:
       valueDigit_2_return = 2;
       break;
    case 101111:
       valueDigit_2_return = 3;
       break;
    case 11110:
       valueDigit_2_return = 4;
       break;
    case 111101:
       valueDigit_2_return = 5;
       break;
    case 1111101:
       valueDigit_2_return = 6;
       break;
    case 1011:
       valueDigit_2_return = 7;
       break;
    case 1111111:
       valueDigit_2_return = 8;
       break;
    case 111111:
       valueDigit_2_return = 9;
       break;
  }

switch (decimal_Digit_3) {
    case 1111011:
       valueDigit_3_return = 0;
      break;
    case 1010:
       valueDigit_3_return = 1;
       break;
    case 1100111:
       valueDigit_3_return = 2;
       break;
    case 101111:
       valueDigit_3_return = 3;
       break;
    case 11110:
       valueDigit_3_return = 4;
       break;
    case 111101:
       valueDigit_3_return = 5;
       break;
    case 1111101:
       valueDigit_3_return = 6;
       break;
    case 1011:
       valueDigit_3_return = 7;
       break;
    case 1111111:
       valueDigit_3_return = 8;
       break;
    case 111111:
       valueDigit_3_return = 9;
       break;
  }

switch (decimal_Digit_4) {
    case 1111011:
      valueDigit_4_return = 0;
      break;
    case 1010:
       valueDigit_4_return = 1;
       break;
    case 1100111:
       valueDigit_4_return = 2;
       break;
    case 101111:
       valueDigit_4_return = 3;
       break;
    case 11110:
       valueDigit_4_return = 4;
       break;
    case 111101:
       valueDigit_4_return = 5;
       break;
    case 1111101:
      valueDigit_4_return = 6;
       break;
    case 1011:
       valueDigit_4_return = 7;
       break;
    case 1111111:
       valueDigit_4_return = 8;
       break;
    case 111111:
       valueDigit_4_return = 9;
       break;

  }




}//end of main

//*******************************************************************************************************************************
//custom functions
//*******************************************************************************************************************************
//read the 7 segments and store as a string representing a number
 void Read_segment0(){
     segment_a = pinReadFast(D0);//
     segment_b = pinReadFast(D1);//
     segment_c = pinReadFast(D3);//
     segment_d = pinReadFast(D5);//
     segment_e = pinReadFast(D6);//
     segment_f = pinReadFast(D4);//
     segment_g = pinReadFast(D2);//
     sprintf(valueDigit_0_string,"%d%d%d%d%d%d%d",segment_e,segment_d,segment_f,segment_c,segment_g,segment_b,segment_a);
  }

   void Read_segment1(){
     segment_a = pinReadFast(D0);//
     segment_b = pinReadFast(D1);//
     segment_c = pinReadFast(D3);//
     segment_d = pinReadFast(D5);//
     segment_e = pinReadFast(D6);//
     segment_f = pinReadFast(D4);//
     segment_g = pinReadFast(D2);//
     sprintf(valueDigit_1_string,"%d%d%d%d%d%d%d",segment_e,segment_d,segment_f,segment_c,segment_g,segment_b,segment_a);
  }

  void Read_segment2(){
     segment_a = pinReadFast(D0);//
     segment_b = pinReadFast(D1);//
     segment_c = pinReadFast(D3);//
     segment_d = pinReadFast(D5);//
     segment_e = pinReadFast(D6);//
     segment_f = pinReadFast(D4);//
     segment_g = pinReadFast(D2);//
     sprintf(valueDigit_2_string,"%d%d%d%d%d%d%d",segment_e,segment_d,segment_f,segment_c,segment_g,segment_b,segment_a);
  }

  void Read_segment3(){
     segment_a = pinReadFast(D0);//
     segment_b = pinReadFast(D1);//
     segment_c = pinReadFast(D3);//
     segment_d = pinReadFast(D5);//
     segment_e = pinReadFast(D6);//
     segment_f = pinReadFast(D4);//
     segment_g = pinReadFast(D2);//
     sprintf(valueDigit_3_string,"%d%d%d%d%d%d%d",segment_e,segment_d,segment_f,segment_c,segment_g,segment_b,segment_a);
 }

  void Read_segment4(){
     segment_a = pinReadFast(D0);//
     segment_b = pinReadFast(D1);//
     segment_c = pinReadFast(D3);//
     segment_d = pinReadFast(D5);//
     segment_e = pinReadFast(D6);//
     segment_f = pinReadFast(D4);//
     segment_g = pinReadFast(D2);//
    sprintf(valueDigit_4_string,"%d%d%d%d%d%d%d",segment_e,segment_d,segment_f,segment_c,segment_g,segment_b,segment_a);
   }

1 Like

When you use strtol(str, NULL, 2) instead of atoi() you can convert the pattern into a binary value directly. With that you can replace the switch statements with an array where the binary value of your bit pattern is used as the index in the array and the value of the field stands for the digit.
Granted there will be 117 dummy entries wasted, but as long memory isn't an issue, I'd take that trade-off.

BTW, if you used an array instead of decimal_Digit_x you would already reduce the five switch statements to only one inside a for(i = 0; i < 5; i++) loop - along with all the other copy/paste code for 0..4 :wink:

Alternatively if you don't store the individual digits but the entire value (digitValue * 10^digitIndex) you can use the result much more comfortably.

e.g.

uint8_t          digit[128];
int32_t          value;
volatile uint8_t decDigit[5];

void setup() {
  digit[0b1111011] = 0;
  digit[0b0001010] = 1;
  digit[0b1100111] = 2;
  digit[0b0010111] = 3;  
  digit[0b0011110] = 4;
  digit[0b0111101] = 5;
  digit[0b1111101] = 6;
  digit[0b0001011] = 7;
  digit[0b1111111] = 8;
  digit[0b0111111] = 9;
  digit[0b0000100] = -1;

  ...
}

void loop() {
  value = 0;
  for(int32_t i = 0, factor = 1; i < 5; i--, factor *= 10) {
    if (decDigit[i] >= 0) 
      value += decDigit[i] * factor;
    else {        // in case a minus sign was found, discard and break
      value = -1; // indication of error
      break;
    }
    ...
  }
} 

I'd also change the ISRs to avoid using the string representation of the bit pattern.
Just stay in the binary realm as long as you can.

void readSegment0() { decDigit[0] = parseSegment(); }
void readSegment1() { decDigit[1] = parseSegment(); }
void readSegment2() { decDigit[2] = parseSegment(); }
void readSegment3() { decDigit[3] = parseSegment(); }
void readSegment4() { decDigit[4] = parseSegment(); }

inline uint8_t parseSegment(uint8_t d) {
  return pinReadFast(D0) << 0
       + pinReadFast(D1) << 1
       + pinReadFast(D2) << 2
       + pinReadFast(D3) << 3
       + pinReadFast(D4) << 4
       + pinReadFast(D5) << 5
       + pinReadFast(D6) << 6;
}

I'm also rather confused about the order of your read statements and segment naming in this :wink:

Since you are not bound to the datasheet's naming convention in your code, I'd avoid making the code more confusing by mixing things around. It would be enough to preface the code with a comment block that clarifies the pin/segment correlation, but after that readability of the code should be a priority.

3 Likes

thanks for that Scruff, a lot of food for thought. Going to give the binary solution a go. Regarding

I’m also rather confused about the order of your read statements and segment naming in this :wink:

Just tried to stick to the schematic, I used a ribbon cable from the scale to the Argon and did not want to cross the wires and that was the order.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.