Need a little help withe barcode reading

Hello folks,

I have been working on this project for whole this month . And it is almost complete when this problem happened.

The hardware that I have used

arduino uno
micro sd module
i2c lcd display
4x4 matrix keypad
waveshare barcode reader module


#include<SPI.h>
#include<SD.h>
#include<SoftwareSerial.h>
#include<Keypad.h>
#include<LiquidCrystal_I2C.h>

SoftwareSerial scanner(0,1);
File myFile;

const byte row =4;
const byte col =4;

char keys[row][col] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'},
};
byte rowPin[row] = {2,3,4,5};
byte colPin[col] = {6,7,8,9};
Keypad kpd(makeKeymap(keys),rowPin,colPin,row,col);
LiquidCrystal_I2C lcd(0x27,16,2);

char buff[20];
char barcode[10];
//int amount;
//char button;
int posi;
int old_bal;
                
void setup() { 
                   Serial.begin(9600);
                   Serial.println(F("initialized"));                
                  char cut[10];
                  
              memset(cut,' ',sizeof(cut));       //this is our EARESER
              cut[9]='\0';
             
                  
                
                
                
                                    //      Serial.begin(9600);
                scanner.begin(9600);
                scanner.listen();
                scanner.setTimeout(50);
                lcd.begin(16,2);
                lcd.clear();
                lcd.backlight();
                 if(  !SD.begin(10))
                {lcd.print("No SD");     // Serial.print("No SD");
                while(1);}
                lcd.print("----------------");
                lcd.setCursor(4,0);
                lcd.print("Foodlay");
               delay(2500);
               lcd.clear();
               lcd.setCursor(4,0); 
               lcd.print("made by");
               lcd.setCursor(4,1);
               lcd.print("NEERAJ");
               delay(1000); 
              
                
            
            top:                             //  Serial.println("SD initialized");
              lcd.clear();              // Serial.println("Scanner ready");
              lcd.setCursor(4,0);
              lcd.print("place card");
            
               resetValues();     Serial.println("value reset");
         while(1){ 
                   if(scanner.available()){       
                    scanner.readBytes(barcode,sizeof(barcode)-1);
                 
                                           // Serial.println(barcode);
                   
                    break;
                   }         
                 }
                 Serial.println("scanned barcode");

//WHEN I RUN THIS CODE GIVEN UNDER BOUNDERY, BARCODE READER WORKS WELL BUT WHEN THE 
// WHOLE CODE GETS COMPILED IT JUST HALTS HERE.
//-------------------------------------------------------------

/*
           while(2){
            char push =kpd.getKey();
            if(push=='A')
            { Serial.println("entered A");
              int money =100-detectNumber();
              lcd.clear();
              lcd.setCursor(0,0);
              lcd.print(money);
              delay(2000);
              lcd.clear();
              lcd.print("press button"); 
              Serial.println("Going back to while loop");

            }
           }*/
//--------------------------------------------------------------


              
                Serial.println("searching in database");
                myFile = SD.open("suraj.txt",(O_READ|O_WRITE));
         if(myFile)  {  
         
          while(myFile.available())
            {  posi= myFile.position();              // position to later fill line with white space
              myFile.readBytesUntil('\n',buff,17);
           
               
               char *ptr = strchr(buff,' ');
              *ptr ='\0';
              char *ptr_bar = strchr(barcode,' ');
              *ptr_bar = '\0';
              old_bal = atoi(++ptr);
           
              
              if (strcmp(buff,barcode)==0)
              { Serial.println("user exist");
              lcd.clear();                    // Serial.println("user exists");
              lcd.setCursor(0,0);
                                             //  Serial.print(buff);
               lcd.print("Amount: ");
               lcd.setCursor(7,0);
                lcd.print(old_bal);
               Serial.println("printed user information");
               Serial.println("press button"); 
                while(1){
                char button = kpd.getKey();
                   if(button=='A')
                   
                   {Serial.println("Entered A");
                    int amount=old_bal-detectNumber(); 
                lcd.clear();
                lcd.setCursor(0,0);
                lcd.print("New bal:");
                lcd.setCursor(9,0);
                lcd.print(amount);                
                 Serial.print("New bal:");
                 Serial.println(amount);
                 Serial.println("printing data to file");
                myFile.seek(posi);              //going to the position where match happend
                myFile.print(cut);
                myFile.seek(posi);                               //filling the whole line with SPACES (pretending erase)
                myFile.print(buff);             //its same as before cause we only want to change amount value
                myFile.print(" ");
                myFile.print(amount);
                myFile.flush();
               
                myFile.close();
                delay(2000);
                Serial.println("going scan mode again");
                goto top;
                   }
                   else {
                    Serial.println("you entered key Other then A");
                    myFile.close();
                    Serial.println("going to scan mode");
                    goto top;
                   }   
                }
         
                                  //not using break just skip to "No user exist" line
                
              }
             
            }  
              Serial.println("whole file scanned :No user");
              Serial.println("press A to add other to go scan mode");
              lcd.clear();
              lcd.setCursor(0,0);
              lcd.print("NO user ");
               while(1){
               
                char button=kpd.getKey();
               if(button=='A')
               {Serial.println("A detected");  
               int amount = detectNumber();
                myFile.seek(myFile.size()+1);
                myFile.print(barcode);
                myFile.print(" ");
                myFile.print(amount);
                myFile.println("    ");
                myFile.flush();
                lcd.clear();
                lcd.print("USER ADDED");
                Serial.println("user added to file");
                delay(500);
                lcd.clear();
                lcd.setCursor(0,0);
                lcd.print("Bal:");
                lcd.setCursor(4,0);
                lcd.print(amount);
                Serial.println("closing the file");
                myFile.close();
                Serial.println("going to scan mode");
                goto top;
               }
               else { 
                Serial.println("Entered Key other than A");
                myFile.close();
                goto top;
               }
               } 
            
         }
}

void loop() {
  // put your main code here, to run repeatedly:

}

void resetValues(void)
{  
   memset(barcode,'\0',sizeof(barcode));
   memset(buff,'\0',sizeof(buff));
   
  
   posi =0;
   old_bal = 0;
 
  
}
int detectNumber(void)

{ Serial.println("detectNumber function called");
  int temp=0;
    int num=0;
    char key;
    lcd.clear();
    while(1){
    top_det:
    key =kpd.getKey();
    
    if (key=='1')
    {   if(num==0)
          num=1;
          else
          num=(num*10)+1; 
    }
    if (key=='2')
    {   if(num==0)
          num=2;
          else
          num=(num*10)+2;
    }
    if (key=='3')
    {    if(num==0)
          num=3;
          else
          num=(num*10)+3;
      
    }
    if  (key=='4')
    {    if (num==0)
          num= 4;
          else
          num=(num*10)+4;
    }
    if  (key=='5')
    {    if(num==0)
          num=5;
          else
          num=(num*10)+5;
    }
    if  (key=='6')
    {    if(num==0)
         num=6;
         else
         num=(num*10)+6;  
    }
    if   (key=='7')
    {    if(num==0)
         num=7;
         else
         num=(num*10)+7;
    }
    if   (key=='8')
    {    if(num==0)
          num=8;
          else
          num=(num*10)+8;
    }
    if    (key=='9')
    {     if(num==0)
          num=9;
          else
          num=(num*10)+9;
    }
    if    (key=='0')
    {     if (num==0)
          num=0;
          else
          num=(num*10)+0;

    }
    if    (key=='*')
    {    lcd.clear();
         if(num<=9)
          num=0;
          else
          {
          temp=num/10;  
          num=(num-(num-((temp)*10)))/10;
          }
    }
    if    (key=='#')
          { 
            num=0;
            lcd.clear();
            goto top_det;
                
    }
     if    (key=='A')
          { Serial.println("returning num");
            return num;     
          }

    
       lcd.setCursor(0,0);
       lcd.print(num);
         
    }
}

when compiling whole code execution halts at barcode reading stage.

then i entered little sample code to check ( that is enclosed in /* */ section.

then the execution goes normally.

I cannot understand why this is happening.

everything else working fine.

this is the output with whole code compiled.

initialized
value reset

this is the output with sample code inserted in /* */ in the main code.

initialized
value reset
scanned barcode
entered A
detectNumber function called
returning num
Going back to while loop
entered A
detectNumber function called
returning num
Going back to while loop
 

this is "suraj.txt" file

101 210    
102 220    
103 230    
104 240    
105 250    
106 260    
107 270    
108 280    
109 290    
110 300    
111 310    
112 320    
113 330    
114 340    
115 350    
116 360    
117 370    
118 380    
119 390    
120 400    
121 410    
122 420    
123 430    
124 440    
125 450    
126 460    
127 470    
128 480    
129 490    
130 500    
131 510    
132 520    
133 530    
134 540    
135 550    
136 560    
137 570    
138 580    
139 590    
140 600    
141 610    
142 620    
143 630    
144 640    
145 650    
146 660    
147 670    
148 680    
149 690    
150 700    

what we want to do?

the first column is barcode and second is amount

with the help of barcode reader we are searching the scanned barcode in the "suraj.txt" file

if found we might want to change the amount related to that barcode or again go to barcode scan mode.

if scanned barcode not found in "suraj.txt" , we might want to add scanned barcode and add it's amount using keypad , and save it to "suraj.txt" file at the end.
Or go back to scanning mode.

Any help would be greatly appriciated.

Uh-oh

Could you maybe run the IDE's auto format tool on your code, and repost?

    if (key == '1')
    { if (num == 0)
        num = 1;
      else
        num = (num * 10) + 1;
    }
    if (key == '2')
    { if (num == 0)
        num = 2;
      else
        num = (num * 10) + 2;
    }
// etc, etc

Waaaayyy too much code.

    if (key >= '0' && key <= '9') {
      num *= 10;
      num += key - '0';
    }

And what happened to your comments?

I started to look for the problem, but I find your code unreadable. Apart from the very awkward formatting, you seem to be going about things in a rather odd way. Such as using 'while(1)' loops or 'while(2)' (???) loops and then escaping from them with 'break'. If you go about it like this I'm not surprised your code hangs from time to time; it's a deadlock waiting to happen. I'm also weary of what you're doing once you've opened the file and start juggling with pointers - I haven't thoroughly analyzed that part of the code (it's virtually unreadable and poorly documented, so frankly I can't be bothered), but I'd look into that bit carefully.

My advise would be to unit test this code a bit better; make separate sketches to test the barcode reader part and the file handling part. My money is on the file handling part overwriting a memory location that shouldn't be overwritten, causing your code to crash.

thanks for paying attention Sir,

i know the detectnumber() function is way lengthy , I have not touched it just to focus on other things ( file data manuplating ,barcode reading etc) as this is working ok

here is auto formatted code ..


#include<SPI.h>
#include<SD.h>
#include<SoftwareSerial.h>
#include<Keypad.h>
#include<LiquidCrystal_I2C.h>

SoftwareSerial scanner(0,1);
File myFile;

const byte row =4;
const byte col =4;

char keys[row][col] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'},
};
byte rowPin[row] = {2,3,4,5};
byte colPin[col] = {6,7,8,9};
Keypad kpd(makeKeymap(keys),rowPin,colPin,row,col);
LiquidCrystal_I2C lcd(0x27,16,2);

char buff[20];
char barcode[10];
//int amount;
//char button;
int posi;
int old_bal;
                
void setup() { 
                   Serial.begin(9600);
                   Serial.println(F("initialized"));                
                  char cut[10];
                  
              memset(cut,' ',sizeof(cut));       //this is our EARESER
              cut[9]='\0';
             
                  
                
                
                
                                    //      Serial.begin(9600);
                scanner.begin(9600);
                scanner.listen();
                scanner.setTimeout(50);
                lcd.begin(16,2);
                lcd.clear();
                lcd.backlight();
                 if(  !SD.begin(10))
                {lcd.print("No SD");     // Serial.print("No SD");
                while(1);}
                lcd.print("----------------");
                lcd.setCursor(4,0);
                lcd.print("Foodlay");
               delay(2500);
               lcd.clear();
               lcd.setCursor(4,0); 
               lcd.print("made by");
               lcd.setCursor(4,1);
               lcd.print("NEERAJ");
               delay(1000); 
              
                
            
            top:                             //  Serial.println("SD initialized");
              lcd.clear();              // Serial.println("Scanner ready");
              lcd.setCursor(4,0);
              lcd.print("place card");
            
               resetValues();     Serial.println("value reset");
         while(1){ 
                   if(scanner.available()){       
                    scanner.readBytes(barcode,sizeof(barcode)-1);
                 
                                           // Serial.println(barcode);
                   
                    break;
                   }         
                 }
                 Serial.println("scanned barcode");

//WHEN I RUN THIS CODE GIVEN UNDER BOUNDERY, BARCODE READER WORKS WELL BUT WHEN THE 
// WHOLE CODE GETS COMPILED IT JUST HALTS HERE.
//-------------------------------------------------------------

/*
           while(2){
            char push =kpd.getKey();
            if(push=='A')
            { Serial.println("entered A");
              int money =100-detectNumber();
              lcd.clear();
              lcd.setCursor(0,0);
              lcd.print(money);
              delay(2000);
              lcd.clear();
              lcd.print("press button"); 
              Serial.println("Going back to while loop");

            }
           }*/
//--------------------------------------------------------------


              
                Serial.println("searching in database");
                myFile = SD.open("suraj.txt",(O_READ|O_WRITE));
         if(myFile)  {  
         
          while(myFile.available())
            {  posi= myFile.position();              // position to later fill line with white space
              myFile.readBytesUntil('\n',buff,17);
           
               
               char *ptr = strchr(buff,' ');
              *ptr ='\0';
              char *ptr_bar = strchr(barcode,' ');
              *ptr_bar = '\0';
              old_bal = atoi(++ptr);
           
              
              if (strcmp(buff,barcode)==0)
              { Serial.println("user exist");
              lcd.clear();                    // Serial.println("user exists");
              lcd.setCursor(0,0);
                                             //  Serial.print(buff);
               lcd.print("Amount: ");
               lcd.setCursor(7,0);
                lcd.print(old_bal);
               Serial.println("printed user information");
               Serial.println("press button"); 
                while(1){
                char button = kpd.getKey();
                   if(button=='A')
                   
                   {Serial.println("Entered A");
                    int amount=old_bal-detectNumber(); 
                lcd.clear();
                lcd.setCursor(0,0);
                lcd.print("New bal:");
                lcd.setCursor(9,0);
                lcd.print(amount);                
                 Serial.print("New bal:");
                 Serial.println(amount);
                 Serial.println("printing data to file");
                myFile.seek(posi);              //going to the position where match happend
                myFile.print(cut);
                myFile.seek(posi);                               //filling the whole line with SPACES (pretending erase)
                myFile.print(buff);             //its same as before cause we only want to change amount value
                myFile.print(" ");
                myFile.print(amount);
                myFile.flush();
               
                myFile.close();
                delay(2000);
                Serial.println("going scan mode again");
                goto top;
                   }
                   else {
                    Serial.println("you entered key Other then A");
                    myFile.close();
                    Serial.println("going to scan mode");
                    goto top;
                   }   
                }
         
                                  //not using break just skip to "No user exist" line
                
              }
             
            }  
              Serial.println("whole file scanned :No user");
              Serial.println("press A to add other to go scan mode");
              lcd.clear();
              lcd.setCursor(0,0);
              lcd.print("NO user ");
               while(1){
               
                char button=kpd.getKey();
               if(button=='A')
               {Serial.println("A detected");  
               int amount = detectNumber();
                myFile.seek(myFile.size()+1);
                myFile.print(barcode);
                myFile.print(" ");
                myFile.print(amount);
                myFile.println("    ");
                myFile.flush();
                lcd.clear();
                lcd.print("USER ADDED");
                Serial.println("user added to file");
                delay(500);
                lcd.clear();
                lcd.setCursor(0,0);
                lcd.print("Bal:");
                lcd.setCursor(4,0);
                lcd.print(amount);
                Serial.println("closing the file");
                myFile.close();
                Serial.println("going to scan mode");
                goto top;
               }
               else { 
                Serial.println("Entered Key other than A");
                myFile.close();
                goto top;
               }
               } 
            
         }
}

void loop() {
  // put your main code here, to run repeatedly:

}

void resetValues(void)
{  
   memset(barcode,'\0',sizeof(barcode));
   memset(buff,'\0',sizeof(buff));
   
  
   posi =0;
   old_bal = 0;
 
  
}
int detectNumber(void)

{ Serial.println("detectNumber function called");
  int temp=0;
    int num=0;
    char key;
    lcd.clear();
    while(1){
    top_det:
    key =kpd.getKey();
    
    if (key=='1')
    {   if(num==0)
          num=1;
          else
          num=(num*10)+1; 
    }
    if (key=='2')
    {   if(num==0)
          num=2;
          else
          num=(num*10)+2;
    }
    if (key=='3')
    {    if(num==0)
          num=3;
          else
          num=(num*10)+3;
      
    }
    if  (key=='4')
    {    if (num==0)
          num= 4;
          else
          num=(num*10)+4;
    }
    if  (key=='5')
    {    if(num==0)
          num=5;
          else
          num=(num*10)+5;
    }
    if  (key=='6')
    {    if(num==0)
         num=6;
         else
         num=(num*10)+6;  
    }
    if   (key=='7')
    {    if(num==0)
         num=7;
         else
         num=(num*10)+7;
    }
    if   (key=='8')
    {    if(num==0)
          num=8;
          else
          num=(num*10)+8;
    }
    if    (key=='9')
    {     if(num==0)
          num=9;
          else
          num=(num*10)+9;
    }
    if    (key=='0')
    {     if (num==0)
          num=0;
          else
          num=(num*10)+0;

    }
    if    (key=='*')
    {    lcd.clear();
         if(num<=9)
          num=0;
          else
          {
          temp=num/10;  
          num=(num-(num-((temp)*10)))/10;
          }
    }
    if    (key=='#')
          { 
            num=0;
            lcd.clear();
            goto top_det;
                
    }
     if    (key=='A')
          { Serial.println("returning num");
            return num;     
          }

    
       lcd.setCursor(0,0);
       lcd.print(num);
         
    }
}

If that code has been auto-formatted, there's something very wrong with your IDE.

//WHEN I RUN THIS CODE GIVEN UNDER BOUNDERY, BARCODE READER WORKS WELL BUT WHEN THE
  // WHOLE CODE GETS COMPILED IT JUST HALTS HERE.

It's a while loop with no break; what did you expect it to do?

Hence my recommendation to unit test properly.

If you do all the math you will find that this is the same as:

    if (key == '*')
    {
      lcd.clear();
      num /= 10;  
    }
1 Like

thank you Sir,

you have actually read the code ...AMAZING.

BTW I arbitrarily left that just to see if someone really goes through all this .

you are the Winner.

So you're saying you're making it deliberately difficult for others to help you?

Good luck to you, don't expect any help from me. See ya.

No sir,

That's not the case .

Actually I am new to this forum (or to say I am new to asking questions on the internet )
So I do not know to what extent other people really care about other's problems.

 So it was just a conditional check .

And Yes people really do care ..

My apologies if that is not appropriate way to do things.

Please...the laughing...it hurts.