Button push->Check serial val->Operation Help

Starting off, I am brand new to arduino and am very limited on understanding C++, but I will try to properly explain and understand whatever input you can offer me.

I currently am working on a project interfacing an arduino with a weigh scale that will then perform 3 actions based on time and the reading from the scale.
I currently have the scale rs-232 serial line converted into TTL using a MAX233 chip and have the ardunio spitting out data points into the serial monitor.
I also have relays controlled on switching pins to high or low, and button pushes starting the loop that I wish to occur.
I have a switch statement lined out for reading serial and outputting high/low values to control an LED.

So what is my problem?
I am utterly lost on taking in the scales serial output (which is something like " N 500 lb") and converting it into just the useful numeric value which is the weight on the scale and having operations go on based on the weight.
So what I am after is that when I push a button it will first check the scale and for instance make sure that the scale reads 0 (which could be N 0 lb without needing conversion, but I cant even figure out how to have a switch() line without using standard bytes), then after reading 0 it will switch relay 1 on (which is a liquid), then it will wait until the weight reaches say 1000lbs (N 1000 lb), it will then switch off relay 1 and now switch on relay 2 (mixer motor), it will then switch on relay 3 which adds a solid and stay on until a certain weight again (ex. N 1100 lb) after that is reached relay 3 shuts off. Relay 2 (mix motor) will stay on with a delay command for say 5minutes and then shutoff. Then when I push the button I want it to do it all over again without interruptions or resetting by pressing the button or anything like that.

So my main problem in getting all of this to work is to have the serial input from the scale being properly read by the arduino so in my code I can make it do what I want.

I dont really have any code to paste here simply because up until now all of these individual controls I have achieved are all separate programs, but I was using

void setup() {
  // initialize serial communication:
  Serial.begin(9600); 
   // initialize the LED pins:
      for (int thisPin = 2; thisPin < 7; thisPin++) {
        pinMode(thisPin, OUTPUT);
      } 
}

void loop() {
  // read the sensor:
  if (Serial.available() > 0) {
    int inByte = Serial.read();
    // do something different depending on the character received.  
    // The switch statement expects single number values for each case;
    // in this exmaple, though, you're using single quotes to tell
    // the controller to get the ASCII value for the character.  For 
    // example 'a' = 97, 'b' = 98, and so forth:

    switch (inByte) {
    case 'a':    
      digitalWrite(13, LOW);
      Serial.println("You just turned it off idiot");
      break;
    case 'b':    
      digitalWrite(13, HIGH);
      Serial.println("You turned an LED on, want a cookie?");
      break;
    case 'c':    
      digitalWrite(4, HIGH);
      break;
    case 'd':    
      digitalWrite(5, HIGH);
      break;
    case 'e':    
      digitalWrite(6, HIGH);
      break;
    default:
      // turn all the LEDs off:
      for (int thisPin = 2; thisPin < 7; thisPin++) {
        digitalWrite(thisPin, LOW);
      }
    } 
  }
}

thanks in advance for any information you can offer me.

Here's a rough outline of what you have to do:

After your initial "if serial.available" where you check for any bytes ready, you could use a "while serial.available" and read all the available chars into a string. (or even better, you could just read until you reach a b)

Then you have to parse the string removing anything that is not a digit then you can use the "atoi" function to convert the string to an integer.

Ok so a while statement is going to basically constantly read it and put it into a string. I need to read up on string control then as I have no idea even beginning code to do what you suggest.

Parsing and removing everything not a digit is one thing I do not understand how to do, as well as "atoi" which I now am googling.

If you could give me a short example code I would be in your debt. I have been attempting to learn code for all of 2-3days now so I am just starting to get a hang of the basics.

So I now have exactly what the scale is sending me on the serial line and changed the output format to be closer to what I want:

If the Scoreboard Output Format is to be used then the Output Format parameter must be set to SCB (See Parameter Setup).

The Scoreboard Output Format is as follows: Value CR LF

Name        Characters      Description

Value       7           Displayed weight or quantity
CR      1           ASCII Carriage Return (0D Hex)
LF      1           ASCII Line Feed (0A Hex)

Although it doesnt include the fact that Overload on the scale is OL first, so essentially I can see something like: (blank blank)1000.00(blank)(blank) or I would just see OL Most of the time the print is sending me just " 0 " as the scale is not picking up any weight but there are still spaces that just don't show the lines. So I don't know if I need to identify anything, I just need to figure out how to pick that number. Can I just read that number as a value up to 7 and make commands based on numbers, or do the spaces that are blank indicate something I do not see in serial monitor that I need to account for in the programming?

Do I need to write an array and just pluck that 7value number out or will the fact that it normally only shows the value work to use it as such. I am sort of losing my mind jumping so deep into C++ without having the basics fully down.

I will just keeping posting my puttputt logic here until I can find someone to help me out or to suggest someone to ask, maybe someone can lead me on the right path.

I'm not sure I understand your problem. The scale appears to output 9 characters of serial data, 7 of which tell you something, and a carriage return and a line feed. The space, space, 1000.00, space, space example you show just isn't possible, since that is 11 characters.

I would read the serial data, until receiving a CR or LF. Both the CR and LF would be discarded, but would trigger parsing and re-initializing the buffer and index. Parsing would then consist of seeing if the string started with OL (overload?). If not, I'd see if any non-numeric values were present (the N you mentioned), and convert them to spaces. Finally, I'd pass the array to atof(), to get the weight converted to a number. Then, I'd use that number for whatever purpose.

Show your current code, and we can help you get where you want to go.

Alright, I will share the code I had a friend of a friend write for me. I have made several changes and picked at it to get it to work, but it appears I need a new approach to reading the output from serial.

// scalething.pde

// --- NOTES ---
// The various relay enables/disables set an explicit state for all three
// to prevent transient bugs. Check to make sure they're turning on/off
// at the appropriate times.

// When should the scale tare the weight?

// --- DEFINES ---

// Management style
// When SET, style 1 is used, otherwise style 2
// follow the #ifdef tags in the code to see what the difference is.
// Uncomment the next line to use style 2
//#define MSTYLE_ALT

// Pin number that the START button is on
// NOTE: Must be 2 or 3
#define START_BUTTON_PIN 2

// Pin number fo Emergency Stop button
// NOTE: Must be 2 or 3
#define ESTOP_BUTTON_PIN 3

// SoftwareSerial RX line
#define SS_RX_PIN 4

// SoftwareSerial TX line
#define SS_TX_PIN 5

// Relay 1 pin number
#define RELAY1_PIN 6

// Relay 2 pin number
#define RELAY2_PIN 7

// Relay 3 pin number
#define RELAY3_PIN 8

// E Stop LED indicator pin
#define ESTOP_LED_PIN 9

// Serial speed to/from scale
// NOTE: MUST match scale baud rate
#define SCALE_SERIAL_RATE 9600

// First weight threshold
#define WEIGHT_AMOUNT1 1263

// Second weight threshold
#define WEIGHT_AMOUNT2 2494

// Time to stay at mix stage in seconds
#define MIX_TIME 600

// --- INCLUDES ---
#include <SoftwareSerial.h>

// --- GLOBAL VARIABLES ---
// Emergency Stop status
int iEStopStatus = 0;

// Process completion; when 1, adding/mixing is done.
int iProcessStatus = 1;

// --- CLASS INSTANCES ---
SoftwareSerial scaleSerial = SoftwareSerial(SS_RX_PIN,SS_TX_PIN);

// --- FUNCTION PROTOTYPES ---
float getWeight    ( void );
void  setRelays    ( int iRelay1, int iRelay2, int iRelay3 );
void  eStop        ( void );
void  startProcess ( void );

void setup() {
	// Setup the pins.
	// NOTE: These two lines are for the emergency stop button.
	pinMode(ESTOP_BUTTON_PIN,INPUT);
	digitalWrite(ESTOP_BUTTON_PIN,LOW);

	pinMode(SS_RX_PIN,INPUT);
	digitalWrite(SS_RX_PIN,LOW);
	pinMode(SS_TX_PIN,OUTPUT);
	digitalWrite(SS_TX_PIN,LOW);
	pinMode(START_BUTTON_PIN,INPUT);
	digitalWrite(START_BUTTON_PIN,LOW);
	pinMode(RELAY1_PIN,OUTPUT);
	digitalWrite(RELAY1_PIN,LOW);
	pinMode(RELAY2_PIN,OUTPUT);
	digitalWrite(RELAY2_PIN,LOW);
	pinMode(RELAY3_PIN,OUTPUT);
	digitalWrite(RELAY3_PIN,LOW);
	pinMode(ESTOP_LED_PIN,OUTPUT);
	digitalWrite(ESTOP_LED_PIN,LOW);

	attachInterrupt((ESTOP_BUTTON_PIN-3),eStop,RISING); // call eStop() when button is pressed
	attachInterrupt((START_BUTTON_PIN-3),startProcess,RISING); // call startProcess() when button is pressed.

	scaleSerial.begin(SCALE_SERIAL_RATE);
}

void loop() {
	float fCurrentWeight;

#ifndef MSTYLE_ALT
	if ( iEStopStatus || iProcessStatus ) {
		// Disable all three relays when stopped.
		setRelays(LOW,LOW,LOW);
	} else {
		fCurrentWeight = getWeight();

		if ( fCurrentWeight < WEIGHT_AMOUNT1 ) {
			// Less than WEIGHT_AMOUNT1
			setRelays(HIGH,LOW,LOW);
		} else if ( WEIGHT_AMOUNT1 < fCurrentWeight < WEIGHT_AMOUNT2 ) {
			// Between WEIGHT_AMOUNT1 and WEIGHT_AMOUNT2
			setRelays(LOW,HIGH,HIGH);
		} else if ( WEIGHT_AMOUNT2 < fCurrentWeight ) {
			// Greater than WEIGHT_AMOUNT2

			// Keep
			// HACK: I put a mini-loop here to allow e stop to pause mixing.
			for ( int i = MIX_TIME; i > 0; i-- ) {
				while ( iEStopStatus ) {
					setRelays(LOW,LOW,LOW);
				}

				setRelays(LOW,HIGH,LOW);

				delay(1000);
			}

			// Done.
			iProcessStatus = 1;
		}
	}
#else
	fCurrentWeight = getWeight();

	if ( !iProcessStatus ) {
		while ( fCurrentWeight < WEIGHT_AMOUNT1 ) {
			if ( iEStopStatus )
				setRelays(LOW,LOW,LOW);
			else
				setRelays(HIGH,LOW,LOW);
		}

		while ( WEIGHT_AMOUNT1 < fCurrentWeight < WEIGHT_AMOUNT2 ) {
			if ( iEStopStatus )
				setRelays(LOW,LOW,LOW);
			else
				setRelays(LOW,HIGH,HIGH);
		}

		while ( WEIGHT_AMOUNT2 < fCurrentWeight ) {
			for ( int i = MIX_TIME; i > 0; i++ ) {
				if ( iEStopStatus )
					setRelays(LOW,LOW,LOW);
					i--;
				else
					setRelays(LOW,HIGH,LOW);
			}
			iProcessStatus = 1;
		}
	}
#endif
}

// Function to read the current weight reading
float getWeight ( void ) {
	char cWeightString[8];

	// NOTE: Why is the array size 8 when we read only 7 chars?
	// The last element is 0 so atof() knows when to stop.

	// Tell the scale to send the weight
	scaleSerial.print('b');

	// Read in the weight
	for ( int i = 0; i > 7; i++ )
		cWeightString[i] = scaleSerial.read();

	cWeightString[7] = 0;

	// Convert and return number.
	return atof(cWeightString);
}

// Conventient wrapper function to set all three relays on one line.
void setRelays ( int iRelay1, int iRelay2, int iRelay3 ) {
	digitalWrite(RELAY1_PIN,iRelay1);
	digitalWrite(RELAY2_PIN,iRelay2);
	digitalWrite(RELAY3_PIN,iRelay3);
}

// Function to emergency stop/start the machine.
void eStop ( void ) {
	iEStopStatus = !iEStopStatus;
	digitalWrite(ESTOP_LED_PIN,(iEStopStatus?HIGH:LOW));
}

// Sets the process state variable.
void startProcess ( void ) {
	iProcessStatus = 0;
}

but it appears I need a new approach to reading the output from serial.

I agree.

#include <SoftwareSerial.h>

SoftwareSerial is obsolete. Use NewSoftSerial, instead.

	pinMode(SS_RX_PIN,INPUT);
	digitalWrite(SS_RX_PIN,LOW);
	pinMode(SS_TX_PIN,OUTPUT);
	digitalWrite(SS_TX_PIN,LOW);

What’s with this? You told SoftwareSerial that it controlled these pins? Why are you now messing with them?

	// Tell the scale to send the weight
	scaleSerial.print('b');

	for ( int i = 0; i > 7; i++ )
		cWeightString[i] = scaleSerial.read();

	cWeightString[7] = 0;

Tell the scale to send the weight as a 7 byte string, and expect a response nanoseconds later?

Serial data transmission is sssslllloooowwww, especially at 9600 baud. You need to switch to NewSoftSerial, which has an available() method that tells how much data there is to read. Do nothing until there are 7 bytes to read. Then, read and store them.

Or, use a while loop to read each value that terminates when the value is not -1 (which is what SoftwareSerial::read() returns when there is no data.

By the way, the middle part of the for loop defines the while condition for execution. As written, your loop says “start with i equal to 0. While i is greater than 7, do this, then increment i by 1”. I doubt that that is what you really want.

Well the newest version of newsoftserial actually just replaces that serial file (it is how you can set rx/tx lines different then 0,1). In the code I tried to make work, I did indeed just use version 10 so I replaced all that with what you might be more use to seeing which is softserial. I also tried to delete that pin reading crap but that didnt solve anything. I am happy I am at least on the right track to making this code work for me.

I am about 4days into C++ now with various other projects going on around me that I have some part in. Perhaps you can guide me a bit more on a solution to reading this data. I suppose i < 7 , but am I needing to rewrite this with some form of buffer and serial available check? What should the first part of that loop be? Pointing me at some articles or forum posts would be great. I am currently reading one you participated in relating to reading GPS data in.

edit: also by setting my scale to a “scoreboard” output format all I have spitting out now is just a few blank spaces and a simple number. The only time it shows different is if you have a overload “OL.” So this seems easy enough, I just can’t wrap my mind around properly reading the string, parsing it, and using it as a number in greater than or less than statements.

The first thing that you need to accomplish is to successfully get all the serial data from the scale. What you do with the data is immaterial. Just print it to start with.

void loop()
{
   scaleSerial.print('b');
   while(scaleSerial.available() == 0)
   {
      // Do nothing while waiting
   }
   while(scaleSerial.available() > 0)
   {
      int inByte = scaleSerial.read();
      Serial.print("I got: ");
      Serial.print(inByte, DEC);
      Serial.print(" = ");
      Serial.println(inByte);
   }

   delay(1000);
}

Replace your loop() with this loop(). Show the output that you get.

When you are reliably getting output, then we can figure out what the ending character(s) are, so we know when to stop waiting/reading.

When we know when the end of packet arrives, we can figure out how to store the data (what size array, etc.) received, and print it all at once. We can also figure out how to parse the data, to make a number that can be used.

One step at a time.

I got: 32 = 32
I got: 32 = 32
I got: 32 = 32
I got: 32 = 32
I got: 32 = 32
I got: 50 = 50
I got: 13 = 13
I got: 10 = 10

Ok, I am reading with full eyes... or something.

Also, sending the scale 'b' to print or send the signal sort of interrupts normally viewing the scale as it the scale then reads out OUTPUT over and over again. This scale does have a continuous output mode, but I am not sure if it is any more challenging to make use of that data transmission.

Also if it helps, I am using a scale in the office so I dont have to go out to the shop every time and try to test using the scales that are always in use. Because of this I can't really make it output interesting numbers, only 0 and 2lbs. (always overload when I tried to setup some strain gauges to the input, oh well)

also the 50=50 line is obvious the value, as I change it from 0 to 2pounds (by changing from gross to net weights which are slightly off on this test scale), it goes from 50=50 to 48=48. I just don't know what will print out if it sees an input of more then 1 character for the value, I assume more number lines.

edit: So I took out the print line and set the scale to continuous output and it reads it just fine but it does seem to print faster even though it is delaying 1sec probably because it is never NOT doing anything which means it is skipping that first while line and isnt running the send 'b' code.

That looks like good news. The Serial.println statement should have looked like:

Serial.println((char)inByte);

So, what it means is that the scale returns 8 bytes per read. There are 6 bytes containing a number (" 2" in your example), a carriage return (13) and a line feed (10).

Now, try:

char buffer[10];
byte index;
bool ended = true;

void loop()
{
   if(ended)
   {
      scaleSerial.print('b');
      ended = false;
      index = 0;
   }

   while(scaleSerial.available() > 0)
   {
      int inByte = scaleSerial.read();
      if(inByte == '\r' || inByte == '\n')
      {
         ended = true;
      }
      else if(index < 10) // Is there room?
      {
         buffer[index++] = inByte;
         buffer[index] = '\0';
      }
   }

   if(ended)
   {
      Serial.print("Scale returned: >");
      Serial.print(buffer);
      Serial.println("<");

      int weight = atoi(buffer);
      Serial.print("weight: ");
      Serial.print(weight, DEC);

      ended = false;      
   }

   delay(1000);
}

So, when I first loaded it it worked, but a bit of jibberish arose because I assume it wasnt all println.
I also had the scale on continuous mode and saw the print ‘b’ in the code so I turned off the continuous output and then nothing happened… I cannot get it to run again like it was and I have no idea why.

It did run for a second, but now it wont. I have no clue why it won’t do it and I have changed it all back to how it was when it first ran. When it was running it was outputting the correct weight which was great, hmmm seems like I am close to grasping the idea but this error is messing with my head.

Edit:Ok, disregard the above. Somehow we changed the baud on the scale.

weight: 2Scale returned: >   2<
weight: 2Scale returned: >   2     2<
weight: 2Scale returned: >   2     2<
weight: 2Scale returned: >     2<
weight: 2Scale returned: > 2<
weight: 2Scale returned: > 2     2<
weight: 2Scale returned: > 2     2<
weight: 2Scale returned: >   2<
weight: 2Scale returned: >   2     2<
weight: 2Scale returned: >     2<
weight: 2Scale returned: > 2<
weight: 2Scale returned: > 2<
weight: 2Scale returned: > 2     2<
weight: 2Scale returned: >   2<
weight: 2Scale returned: >   2     2<
weight: 2Scale returned: >   2     2<
weight: 2Scale returned: >     2<
weight: 2Scale returned: > 2<
weight: 2Scale returned: > 2     2<
weight: 2Scale returned: >   2<
weight: 2Scale returned: >   2<
weight: 2Scale returned: >   2     2<
weight: 2Scale returned: >     2<

So this seems right on track, and using “weight” as our if statement should produce what we want. When the scale reads OL or overload it just ignores it and keeps reading the same number, but I am not sure how to adjust that to pause the programming.

Change:

      Serial.print(weight, DEC);

to:

      Serial.println(weight, DEC);

You can compare the data in buffer to "OL", before converting the value to a weight.

I am not sure how to, in code, write a clause that says if OL is detected to halt or pause. I think with the code sample you gave me I can easily plug it into my current code to get the operations I want. I just need to figure out if the start/pause button and emergency stop (attachinterrupt) are properly working because they behaved weirdly before, but perhaps that was jut because we had weird data input going on.

C++ seems like more fun the more I understand it.

I'll plug her in and give a simple LED test and report my results and code.

You have a string in buffer. There is a string function, strcmp(), that compares strings. The key is to get the contents of buffer consistent, and then compare buffer to the right string (is it"OL " or "OL" or " OL"?).

#define SS_RX_PIN 4

// SoftwareSerial TX line
#define SS_TX_PIN 5

// Relay 1 pin number
#define RELAY1_PIN 6

// Relay 2 pin number
#define RELAY2_PIN 7

// Relay 3 pin number
#define RELAY3_PIN 8

// E Stop LED indicator pin
#define ESTOP_LED_PIN 9

// Serial speed to/from scale
// NOTE: MUST match scale baud rate
#define SCALE_SERIAL_RATE 9600

// First weight threshold
#define WEIGHT_AMOUNT1 1263

// Second weight threshold
#define WEIGHT_AMOUNT2 2494

// Time to stay at mix stage in seconds
#define MIX_TIME 60

// --- INCLUDES ---
#include <NewSoftSerial.h>

// --- GLOBAL VARIABLES ---
// Emergency Stop status

// Process completion; when 1, adding/mixing is done.
int iProcessStatus = 1;

int startButton = 2;
int val = 0;


// --- CLASS INSTANCES ---
NewSoftSerial scaleSerial(4,5);

// --- FUNCTION PROTOTYPES ---

void setup() {
	// Setup the pins.
	// NOTE: These two lines are for the emergency stop button.


	
	pinMode(START_BUTTON_PIN,INPUT);
	digitalWrite(START_BUTTON_PIN,LOW);
	pinMode(RELAY1_PIN,OUTPUT);
	digitalWrite(RELAY1_PIN,LOW);
	pinMode(RELAY2_PIN,OUTPUT);
	digitalWrite(RELAY2_PIN,LOW);
	pinMode(RELAY3_PIN,OUTPUT);
	digitalWrite(RELAY3_PIN,LOW);
        pinMode(startButton, INPUT);
	//pinMode(ESTOP_LED_PIN,OUTPUT);
	//digitalWrite(ESTOP_LED_PIN,LOW);

	
	Serial.begin(57600);
        Serial.println("Goodnight moon!");
        scaleSerial.begin(9600);
        
}


char buffer[10];
byte index;
bool ended = true;

void loop() {
	

//#ifndef MSTYLE_ALT

	 if(ended)
   {
      scaleSerial.print('b');
      ended = false;
      index = 0;
   }

   while(scaleSerial.available() > 0)
   {
      int inByte = scaleSerial.read();
      if(inByte == '\r' || inByte == '\n')
      {
         ended = true;
      }
      else if(index < 10) // Is there room?
      {
         buffer[index++] = inByte;
         buffer[index] = '\0';
      }
   }

   if(ended)
   {
      Serial.print("Scale returned: >");
      Serial.print(buffer);
      Serial.println("<");

      int weight = atoi(buffer);
      Serial.print("weight: ");
      Serial.println(weight, DEC);

      ended = false;      
   }

   delay(100);
	
val = digitalRead(startButton);
if (val == LOW){		

 

int weight = atoi(buffer);
		if ( weight < 1 ) {
			// Less than WEIGHT_AMOUNT1
			setRelays(HIGH,LOW,LOW);
		} else if ( 1 < weight < 3 ) {
			// Between WEIGHT_AMOUNT1 and WEIGHT_AMOUNT2
			setRelays(LOW,HIGH,HIGH);
		} else if ( 4 < weight) {
			// Greater than WEIGHT_AMOUNT2

			// Keep
			// HACK: I put a mini-loop here to allow e stop to pause mixing.
			for ( int i = MIX_TIME; i > 0; i-- ) {
				

				setRelays(LOW,HIGH,LOW);

				delay(1000);
			}

			// Done.
			iProcessStatus = 1;
		}
	

}}



// Function to read the current weight reading


// Conventient wrapper function to set all three relays on one line.
void setRelays ( int iRelay1, int iRelay2, int iRelay3 ) {
	digitalWrite(RELAY1_PIN,iRelay1);
	digitalWrite(RELAY2_PIN,iRelay2);
	digitalWrite(RELAY3_PIN,iRelay3);
}

// Function to emergency stop/start the machine.


// Sets the process state variable.
void startProcess ( void ) {
	iProcessStatus = 0;

So this is what I was working with, but I clearly am nor grasping the basics here. So I set the scale to continuous mode to keep spitting numbers out, and it does indeed read it and spit them back to me. The problem is I havent set the function that runs on the button (which is the relay control) to properly work. I intend for a person just to have to press the button once and for that operation to run, but it cant because it cannot see the updated scale info and just ends the process and starts over again. What am I missing to make this a proper operation?

Also getting OL to read consistently seems off as most of the time the buffer looks like this

Scale returned: > 2<
weight: 2
Scale returned: > 2     2<
weight: 2
Scale returned: >   2<
weight: 2
Scale returned: >   2     2<
weight: 2
Scale returned: >     2<
weight: 2
Scale returned: > 2<
weight: 2
Scale returned: > 2     2<
weight: 2
Scale returned: >   2<
weight: 2
Scale returned: >   2     2<
weight: 2
Scale returned: >     2<
weight: 2
Scale returned: > 2<
weight: 2
Scale returned: > 2     2<
weight: 2
Scale returned: >   2<
weight: 2

Just imagine replacing the 2 with OL, and that is just how sporadic it is, I assume the continuous output is a bit fast… I am really not sure.

There is a possibility that you are seeing the serial port buffer overflow. You can see if this is a possibility by printing the value returned by scaleSerial.available(). If that number consistently is small (less than 10) no overflow is occurring. If that number climbs quickly and runs around 64 or so, there is a problem.

I think my problem is with the way the code is trying to read the serial information. I can only get valuable data that updates if I have the scale on continuous output, I believe I got the buffer set to work properly, but not sure if this will work. Any other suggestions on integrating this code with a simple pushbutton that you only have to push once and it runs through the whole process correctly with hitting that button again to pause, and then a simple interrupt I think I can figure out to act as an emergency shutoff?

thank you so much for your help thusfar, and for the delay in getting back to you. I had my brothers wedding over the weekend. I will test that buffer check for you today.

// scalething.pde

// --- NOTES ---
// The various relay enables/disables set an explicit state for all three
// to prevent transient bugs. Check to make sure they're turning on/off
// at the appropriate times.

// When should the scale tare the weight?

// --- DEFINES ---

// Management style
// When SET, style 1 is used, otherwise style 2
// follow the #ifdef tags in the code to see what the difference is.
// Uncomment the next line to use style 2
//#define MSTYLE_ALT

// Pin number that the START button is on
// NOTE: Must be 2 or 3
#define START_BUTTON_PIN 3

// Pin number fo Emergency Stop button
// NOTE: Must be 2 or 3
#define ESTOP_BUTTON_PIN 3

// SoftwareSerial RX line
#define SS_RX_PIN 4

// SoftwareSerial TX line
#define SS_TX_PIN 5

// Relay 1 pin number
#define RELAY1_PIN 6

// Relay 2 pin number
#define RELAY2_PIN 7

// Relay 3 pin number
#define RELAY3_PIN 8

// E Stop LED indicator pin
#define ESTOP_LED_PIN 9

// Serial speed to/from scale
// NOTE: MUST match scale baud rate
#define SCALE_SERIAL_RATE 9600

// First weight threshold
#define WEIGHT_AMOUNT1 1263

// Second weight threshold
#define WEIGHT_AMOUNT2 2494

// Time to stay at mix stage in seconds
#define MIX_TIME 60

// --- INCLUDES ---
#include <NewSoftSerial.h>

// --- GLOBAL VARIABLES ---
// Emergency Stop status

// Process completion; when 1, adding/mixing is done.
int iProcessStatus = 1;

int startButton = 2;
int val = 0;


// --- CLASS INSTANCES ---
NewSoftSerial scaleSerial(4,5);

// --- FUNCTION PROTOTYPES ---

void setup() {
	// Setup the pins.
	// NOTE: These two lines are for the emergency stop button.


	
	pinMode(START_BUTTON_PIN,INPUT);
	digitalWrite(START_BUTTON_PIN,LOW);
	pinMode(RELAY1_PIN,OUTPUT);
	digitalWrite(RELAY1_PIN,LOW);
	pinMode(RELAY2_PIN,OUTPUT);
	digitalWrite(RELAY2_PIN,LOW);
	pinMode(RELAY3_PIN,OUTPUT);
	digitalWrite(RELAY3_PIN,LOW);
        pinMode(startButton, INPUT);
	//pinMode(ESTOP_LED_PIN,OUTPUT);
	//digitalWrite(ESTOP_LED_PIN,LOW);

	
	Serial.begin(57600);
        Serial.println("Goodnight moon!");
        scaleSerial.begin(9600);
        
}


char buffer[6];
byte index;
bool ended = true;

void loop() {
	

//#ifndef MSTYLE_ALT

	 if(ended)
   {
      scaleSerial.print('b');
      ended = false;
      index = 0;
   }

   while(scaleSerial.available() > 0)
   {
      int inByte = scaleSerial.read();
      if(inByte == '\r' || inByte == '\n')
      {
         ended = true;
      }
      else if(index < 6) // Is there room?
      {
         buffer[index++] = inByte;
         buffer[index] = '\0';
      }
   }

   if(ended)
   {
      Serial.print("Scale returned: >");
      Serial.print(buffer);
      Serial.println("<");

      int weight = atoi(buffer);
      Serial.print("weight: ");
      Serial.println(weight, DEC);

      ended = false;      
   }

   delay(100);
	
val = digitalRead(startButton);
if (val == LOW){		

 

int weight = atoi(buffer);
		if ( weight < 200 ) {
			// Less than WEIGHT_AMOUNT1
			setRelays(HIGH,LOW,LOW);
		} else if ( 200 < weight < 400 ) {
			// Between WEIGHT_AMOUNT1 and WEIGHT_AMOUNT2
			setRelays(LOW,HIGH,HIGH);
		} else if ( 400 < weight) {
			// Greater than WEIGHT_AMOUNT2

			// Keep
			// HACK: I put a mini-loop here to allow e stop to pause mixing.
			for ( int i = MIX_TIME; i > 0; i-- ) {
				

				setRelays(LOW,HIGH,LOW);

				delay(1000);
			}

			// Done.
			iProcessStatus = 1;
		}
	

}}



// Function to read the current weight reading


// Conventient wrapper function to set all three relays on one line.
void setRelays ( int iRelay1, int iRelay2, int iRelay3 ) {
	digitalWrite(RELAY1_PIN,iRelay1);
	digitalWrite(RELAY2_PIN,iRelay2);
	digitalWrite(RELAY3_PIN,iRelay3);
}

// Function to emergency stop/start the machine.


// Sets the process state variable.
void startProcess ( void ) {
	iProcessStatus = 0;
}

So here is the code again with what I am working with for the moment. I think my if/else statements are just not working, or the processing of the weight is off. I currently have to hold the button down to get it to change functions but I can’t get to the third phase of the if else statement. It will go from relay1 on to relay 2 and 3 and sometimes flicker on relay 1 with 2+3 off for a second. Makes little sense to me other then the fact that the data processing is taking precedence and I need the button to run more of a process then a loop so that you press it once and it runs until completed with the data decoding going on in the background.

I am just getting lost down the rabbit hole.