Oddities

Hello all,

Got a machine running on a modified arduino. Only thing is its got a couple of glitches that I can’t seem to figure out.

  1. When the machine powers up, the arduino gets stuck in a constant boot, doesn’t initialize the main program. This is not everytime and actually semi-rare but still an issue I would like to solve.

  2. When the program fires, it checks a proximity sensor. When the sensor is NOT activated, it should run a part of the main loop in my sketch that I will highlight below. This works flawlessly EXCEPT if the sensor isn’t activated on boot. If you move something in front of it to activate it, then pull it away, it begins running normally.

I figured maybe I missed the initialization of HIGH or LOW in my program but i’ve tried both and no results.

Heres the Prox code:

  RailCheck = digitalRead(HookRailFull);
  if ((RailCheck == HIGH) && (RailCheckNext == 0)){
    Serial.println("Rail Check Activated");
    previousTimer2 = currentTime;
    digitalWrite(PanelLed5, HIGH);
    digitalWrite(HookShaker, HIGH);
    RailCheckNext = 1;
  }
  if (RailCheckNext == 1){
    RailCheck = digitalRead(HookRailFull);
    if (RailCheck == LOW){
      previousTimer2 = currentTime;
      RailCheckNext = 2;
    }
  }
  if (RailCheckNext == 2){
    RailCheck = digitalRead(HookRailFull);
    if (RailCheck == HIGH){
      RailCheckNext = 1;
    }  
    if ((RailCheck == LOW) && (currentTime - previousTimer2 >= y[5])){
      digitalWrite(HookShaker, LOW);
      digitalWrite(PanelLed5, LOW);
      previousTimer2 = currentTime;
      Serial.println("Rail Check Finished");
      RailCheckNext = 0;
    }
  }

and the setup code:

#include <Keypad.h>
#include <LiquidCrystal.h>
#include <EEPROM.h>

//Panel Buttons
const int StartFeedButton = 6;
const int NextButton = 42;
const int SaveButton = 46;
const int UpButton = 48;
const int DownButton = 44;
const int ToggleButton = 50;
// Panel LEDs
const int PanelLed1 = 51;
const int PanelLed2 = 49;
const int PanelLed3 = 47;
const int PanelLed4 = 45;
const int PanelLed5 = 43;
const int ErrorLed = 13;
//Sensors
const int HookRailEmpty = A0;
const int HookRailFull = A4;
const int HangerRackFull = A1;
const int HookCycleStart = A2;
const int HeadUp = A7;
const int HeadDown = A6;
const int StripOffOut = A5;
const int CrimpCycleStart = A3;
//Solenoids
const int ToolHead = 16;
const int StripOff = 17;
const int HookStopper = 8;
const int CrimpStopper = 18;
const int Crimp = 19;
const int FeedTable = 7;
const int MainAir = 14;
const int HookShaker = 15;
//LCD Variables
int BSelLogic = 0;
int x = 0;
int seq = 1;
int LCDClearTime = 8000;
int pos=15;
int j = 0;
char arraya [] = {0, 1, 2, 3, 0};
//Time Controls
unsigned long buttonWait = 200;
unsigned long preLCDClear = 0;
unsigned long buttonPreviousTime = 0;
unsigned long previousTimer1 = 0;
unsigned long previousTimer2 = 0;
unsigned long previousTimer3 = 0;
unsigned long previousTimer4 = 0;
unsigned long y[] = {1000, 1000, 1000, 1000, 2300, 2000, 3000};
//LiquidCrystal
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
//Keypad
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {25, 27, 29, 31}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {33, 35, 37, 39};
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

//System Variables
boolean Active = LOW;
int ToggleLogic = 0;
int FeedLoop = 0;
int FeedCheck = 0;
int FeedNext = 0;
int HookNext = 0;
int HookLoop = 0;
int HookCheck = 0;
int CrimpLoop = 0;
int CrimpNext = 0;
int RailCheck = LOW;
int RailCheckNext = 0;
int rswitch = 0;
int SOverride = 1;
char StateArray[] = {0, 0, 0, 0, 0, 0}; //Include extra 0 for the NULL END
int passcode = 7777;
int Error = 0;
//LOGIC CONTROLS
int BNextLogic = 0;
int BUpLogic = 0;
int BDownLogic = 0;
int SaveButtonTrigger = 0;
int ManualFeed = 0;
int SecStart = 0;

void setup() {
  //LEDs
  pinMode(PanelLed1, OUTPUT);
  pinMode(PanelLed2, OUTPUT);
  pinMode(PanelLed3, OUTPUT);
  pinMode(PanelLed4, OUTPUT);
  pinMode(PanelLed5, OUTPUT);
  pinMode(ErrorLed, OUTPUT);
  //Buttons
  pinMode(StartFeedButton, INPUT);
  pinMode(NextButton, INPUT);
  pinMode(SaveButton, INPUT);
  pinMode(UpButton, INPUT);
  pinMode(DownButton, INPUT);
  pinMode(ToggleButton, INPUT);
  //Solenoids
  pinMode(ToolHead, OUTPUT);
  pinMode(HookStopper, OUTPUT);
  pinMode(CrimpStopper, OUTPUT);
  pinMode(Crimp, OUTPUT);
  pinMode(FeedTable, OUTPUT);
  pinMode(MainAir, OUTPUT);
  pinMode(HookShaker, OUTPUT);
  pinMode(StripOff, OUTPUT);
    //Photo
  pinMode(HookCycleStart, INPUT_PULLUP);
  pinMode(HangerRackFull, INPUT_PULLUP);
  pinMode(CrimpCycleStart, INPUT_PULLUP);
    //Prox
  pinMode(HookRailEmpty, INPUT_PULLUP);
  pinMode(HookRailFull, INPUT_PULLUP);
  pinMode(HeadUp, INPUT_PULLUP);
  pinMode(HeadDown, INPUT_PULLUP);
  pinMode(StripOffOut, INPUT_PULLUP);
  // END OF PINMODE
  Serial.begin(9600);
  Serial.println("Starting...");
  lcd.begin(20,4);
  lcd.setCursor(0,0);
  lcd.print("Run Time: ");
  lcd.setCursor(2,1);
  lcd.print("*** BOOTING ***");
  lcd.setCursor(0,2);
  lcd.print("Time:");
  for(int k = 0; k < 6; k++){
    int f = 0;
    f = k*2;
    int ytemp = 0;
    int gtemp = 0;
    ytemp = EEPROM.read(f);
    ytemp = ytemp * 10;
    f++;
    gtemp = EEPROM.read(f);
    gtemp = gtemp * 10;
    y[k] = gtemp + ytemp;
    Serial.print("EEPROM[");
    Serial.print(k);
    Serial.print("]: ");
    Serial.println(y[k]);
    delay(10);
  }
  Serial.println("********** System Variables ***********");
  Serial.print("Button Wait Time: ");
  Serial.println(buttonWait);
  Serial.print("LCD Clear Time: ");
  Serial.println(LCDClearTime);
  Serial.print("LCD Default POS: ");
  Serial.println(pos);
  Serial.print("Override Passcode: ");
  Serial.println(passcode);
  Serial.println();
}

So obviously the sketch is pretty good size, that is my reason for not posting the whole sketch. and the sensor is using a pullup resistor built into the arduino MEGA.

Any other information I will be happy to provide.

Any other information I will be happy to provide.

The whole sketch, if the purpose of posting wasn't just to vent.

PaulS:
The whole sketch, if the purpose of posting wasn't just to vent.

Not really. Just grab yourself a cup of coffee. Shes a big one.

(Had to post this one on github. I hit the maximum character limit.
https://github.com/Blade2021/AssemblyAuto/blob/Blade2021-patch-1/AssemblyAutoBoard.ino

Ignore the commented out portions of course. Its still a work in progress but the majority of the code is written and working (minus the couple of bugs).

Check your RAM availability. Crashes can occur.

Had to post this one on github. I hit the maximum character limit.

You could have attached it to a post here.

mistergreen:
Check your RAM availability. Crashes can occur.

Its not that the board is crashing, its just not fully booting, and its runs fine normally.

UKHeliBob:
You could have attached it to a post here.

Didn't think about that...

Your indenting is horrid. There is no excuse for that, when Tools + Auto Format makes it so easy.

Spacesbetweenoperators,consistently,areagoodthing.

Stuffing{ the{ curly{ brace{ right{ up{ against{ the{ statement{ is{ not{ a{ good{ thing{ to{ do{.

     if (LogicCount == 0){
        unsigned long precountTime = 0;
        precountTime = currentTime;
      }

It is not
necessary
to use two
lines of code
when one will
do.

Actually, the whole test and block are useless. If LogicCount is 0, store the current time in a variable that will, nanoseconds later, cease to exist. Why bother?

       return;

Return statements almost never belong in loop(). I don't think this one does, either.

   int HeadCheckDown;
    HeadCheckDown = digitalRead(HeadDown);

Another case where two lines is not better than one. There are many more like this.

   if (HeadCheckDown == HIGH){
    }

Good thing you checked. Wouldn't want to have missed out on the opportunity to do nothing.

} // *****************************  End of LOOP Void ************************
void inactive(int x){

Finally...

Spaces between functions ARE good.

void TimeKeeper(unsigned long currentTime){

  LogicCount = 0;

WTF? Why would ANYONE expect a uselessly named function like this to be messing with LogicCount? Whatever the hell LogicCount means.

The LogicCount was just added. Its purpose is to keep track of how many of an item has ran, then when it reaches 100 it provides the time it took to run the 100 on the display.

All of this is irrelevant to the issue in my original post.

What type output do the prox switches have, push/pull, open collector NPN, open collector PNP, normally open or closed?

756E6C:
What type output do the prox switches have, push/pull, open collector NPN, open collector PNP, normally open or closed?

NPN