Thank you so much for writing this out in detail! It makes it much easier for a non-programmer such as myself to understand!
Before you posted this, I managed to get a fully working program, but it requires < > (I took it from Example #5 from the tutorial link posted earlier) and unfortunately I have to use letters like a, b, c, etc for the command switch case type. Like so:
<a 4 6>
a = case
4 = motor
6 = until 6 clicks
Here is my code that I hacked together from snippets online. I'm sure there's better ways of writing it, so feel free to point out how I can improve it!
I will definitely look in more detail how you did it and incorporate it since your program is able to do it without < > and mix letters with numbers like M600 whereas I was only able to use letters like 'a'
/*************************************************************************
Name: AutoFeeders.ino
Created: 3/25/2019
Author: Shai
Description: Pick and place Auto Feeder controller
**************************************************************************/
/*******************************************************
* INCLUDES
********************************************************/
#include "pins.h"
/*******************************************************
* DEFINES
********************************************************/
// Variables will change:
int encoderCounter = 0; // counter for the number of button presses
int buttonState = 0; // current state of the button
int lastButtonState = 0; // previous state of the button
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars]; // temporary array for use when parsing
// variables to hold the parsed data
char command[numChars] = {0};
int feederNumber = 0;
int feederDistance = 0;
// float floatFromPC = 0.0;
boolean newData = false;
/*******************************************************
* SETUP
********************************************************/
//String inData;
void setup()
{
Serial.begin(SERIAL_BAUD);
// initialize the button pin as a input:
pinMode(buttonPin, INPUT);
// initialize the motor PWM pin as an output:
pinMode(mosfetPin1, OUTPUT);
pinMode(mosfetPin2, OUTPUT);
// initialize serial communication:
Serial.begin(SERIAL_BAUD);
//Set Mosfet off to begin with for safety
digitalWrite(mosfetPin1, LOW);
digitalWrite(mosfetPin2, LOW);
/*
pinMode(speedPin, OUTPUT);
setSpeedMotor(speedPin,100);
*/
Serial.println("Ready! Type <command feederNumber feederDistance>");
}
/*******************************************************
* ENCODER COUNTER
********************************************************/
void loop()
{
recvWithStartEndMarkers();
if (newData == true) {
strcpy(tempChars, receivedChars);
// this temporary copy is necessary to protect the original data
// because strtok() used in parseData() replaces the commas with \0
parseData();
showParsedData();
newData = false;
}
// read the pushbutton input pin:
buttonState = digitalRead(buttonPin);
// compare the buttonState to its previous state
if (buttonState != lastButtonState) {
// if the state has changed, increment the counter
if (buttonState == HIGH) {
// if the current state is HIGH then the button went from off to on:
encoderCounter++;
Serial.println("Encoder pad detected");
Serial.print("Detection number: ");
Serial.println(encoderCounter);
} else {
// if the current state is LOW then the button went from on to off:
Serial.println("Encoder pad disengaged");
}
// Delay a little bit to avoid bouncing
delay(50);
// save the current state as the last state, for next time through the loop
lastButtonState = buttonState;
}
// If encoderCounter reaches over 4, shut off ALL mosfets
if (encoderCounter >feederDistance) {
digitalWrite(mosfetPin1, LOW);
}
if (encoderCounter >feederDistance) {
digitalWrite(mosfetPin2, LOW);
}
}
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (Serial.available() > 0 && newData == false) {
rc = Serial.read();
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
}
//============
void parseData() { // split the data into its parts
char * strtokIndx; // this is used by strtok() as an index
strtokIndx = strtok(tempChars," "); // get the first part - the string
strcpy(command, strtokIndx); // copy it to command
strtokIndx = strtok(NULL, " "); // this continues where the previous call left off
feederNumber = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, " "); // this continues where the previous call left off
feederDistance = atoi(strtokIndx); // convert this part to an integer
//strtokIndx = strtok(NULL, " ");
//floatFromPC = atof(strtokIndx); // convert this part to a float
switch(tolower(command[0])) { //do switch on first char
case 'a': {
encoderCounter = 0; // Reset encoderCounter
if(feederNumber == mosfetPin1){
digitalWrite(mosfetPin1, HIGH);
}
else if(feederNumber == mosfetPin2){
digitalWrite(mosfetPin2, HIGH);
}
Serial.println("Feeder %feederNumber turned on");
}
break;
}
}
//============
void showParsedData() {
Serial.print("Command: ");
Serial.println(command);
Serial.print("Feeder Number: ");
Serial.println(feederNumber);
Serial.print("Feeder Distance: ");
Serial.println(feederDistance);
}
and attached is my pins file (note that a lot of stuff defined there isn't used yet, but gives you a glimpse into what I am planning to do as I build on this program. Code was over character limit to paste here.
pins.h (1.88 KB)