Conveyor belt simulation

Hiya. (please delete if not allowed)

so I have an assignment to virtually
a) control a conveyor belt (simulated by a 9v motor)
b) count the items passing (use me hand/phone ect)
c) have a push button for "mode 1" or "mode 2"
d) mode1 stops motor after 3 items have passed
e) mode 2 stops motor after 6 items have passed

(so I thought it would be nice to use the lcd to display the number of items that have passed, -unnecessary for brief)

I have an Ultrasound sensor, HC-SR04, a 16/2 lcd, a push button and a 9V motor circuit, using a mosfet, all wired up (very tight fit!)

My problem(s) are many and varied, but for the purpose of this conversation.... I have a patchwork of code (bits taken from different prog's ive made in past and stuff i found online) and I am struggling to get it to all work together.
I have the system actually counting items, (which i thought would be the hardest part) but i cant seem to get the push button to do anything (even print its state to the monitor)

could somebody please give a look at my code (ill put up a pic of wiring too but I dunno if that will be of any help) and suggest where Im wrong and maybe what i could do to finish this little project?

Please and thank you (for reading this far and any help you can give!)




#include <LiquidCrystal.h>
LiquidCrystal lcd(1, 2, 4, 5, 6, 7);
#define trigPin 9
#define echoPin 10
#define motorPin 3
#define buttonPin 13

int counter = 0;
int currentState = 0;
int previousState = 0;
int motorSpeed = 0;

void setup() {
lcd.begin(16, 2);  
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(motorPin, OUTPUT);// initialize the motor pin as an output:
 
Serial.begin (9600);
lcd.print("items=");  
}
void loop() {
  int buttonState = 0; 

   // initialize the LED pin as an output:
  pinMode(motorPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT_PULLUP);
Serial.print(buttonState);

 long duration, distance;
 digitalWrite(trigPin, LOW); 
 delayMicroseconds(2); 
 digitalWrite(trigPin, HIGH);
 delayMicroseconds(10); 
 digitalWrite(trigPin, LOW);

 duration = pulseIn(echoPin, HIGH);
 distance = (duration/2) / 29.1;

 if (distance <= 30){
 currentState = 1;
 }
 else {
 currentState = 0;
 }
 delay(100);
 if(currentState != previousState){
if(currentState == 1){
counter = counter + 1;
lcd.print(counter);
    }
 }
for (motorSpeed = 0 ; motorSpeed <= 255; motorSpeed += 10) 
  {
    analogWrite(motorPin, motorSpeed);
    delay(30);
  }
  for (motorSpeed = 255 ; motorSpeed >= 0; motorSpeed -= 10) 
  {
    analogWrite(motorPin, motorSpeed);
    delay(30);
  }
}

I don't see where you are reading the button pin. You initialize buttonState to 0 but never do anything with it.

There is no reason for the following 2 lines to be in the loop() function. Put them in setup().

  // initialize the LED pin as an output:
  pinMode(motorPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT_PULLUP);

Should the pushbutton just toggle between mode 1 and mode 2?

yeah, pressed is 2 i assume?

I don't know. Is the pushbutton a momentary or latching switch?

why is buttonState defined inside loop()? it's value will not be persistent, it will be reset to zero each iteration of loop().

why is pinMode() being called in loop() instead of once in setup()?

why is there a 100msec delay? doesn't the code need to be constantly monitoring distance?

as Todd asked, where is buttonPin being read?

why is the motor speed being ramps up or down instead of simply started or stopped?

where is there a check for counter == 3 or 6?

where is there an event to start the process:

  • resetting the count to zero
  • starting the conveyor
  • counting items and
  • stopping after the selected number of items have been counted

where is the specified # items: 3 or 6 being set

momentary im assuming, its one of the ones that came with the starter kit
TS66H-3-Tact-Switch

ok, "I dont know" and "thats what the internet said" are the answers to most of those questions dude.... Im not great at coding (in case you hadnt guessed!)
gimme a min to google each question, try to update the code and ill get back to you

Best to wire that switch diagonally across in order to ensure that you pick up switched legs.
Diagonal Button Wiring

1 Like

I know its wrong.... error messages....
^
sketch_conveyor4:32:43: error: lvalue required as left operand of assignment
analogWrite(motorPin = 1 && counter <= 6);//turning on motor untill count =6
^
exit status 1
lvalue required as left operand of assignment

but am i going in right direction?

#include <LiquidCrystal.h>
LiquidCrystal lcd(1, 2, 4, 5, 6, 7);
#define trigPin 9
#define echoPin 10
#define motorPin 3
#define buttonPin 13

int counter = 0;
int currentState = 0;
int previousState = 0;
int motorSpeed = 0;
int buttonState = 0; 

void setup() {
lcd.begin(16, 2);  
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(motorPin, OUTPUT);// initialize the motor pin as an output:
pinMode(buttonPin, INPUT_PULLUP); // initialize the pushbutton pin as an input:
 
Serial.begin (9600);
lcd.print("items=");  
}
void loop() {
 
  if (digitalRead(buttonPin) == 0)
{
   analogWrite(motorPin = 1 && counter <= 3);//turning on motor untill count =3    
}
else
{
   analogWrite(motorPin = 1 && counter <= 6);//turning on motor untill count =6
}

 long duration, distance;
 digitalWrite(trigPin, LOW); 
 delayMicroseconds(2); 
 digitalWrite(trigPin, HIGH);
 delayMicroseconds(10); 
 digitalWrite(trigPin, LOW);

 duration = pulseIn(echoPin, HIGH);
 distance = (duration/2) / 29.1;
 if (distance <= 30){
 currentState = 1;
 }
 else {
 currentState = 0;
 }
 delay(100);
 if(currentState != previousState){
if(currentState == 1){
counter = counter + 1;
lcd.print(counter);
    }
 }
for (motorSpeed = 0 ; motorSpeed <= 255; motorSpeed += 255) 
  {
    analogWrite(motorPin, motorSpeed);
    delay(30);
  }
  for (motorSpeed = 255 ; motorSpeed >= 0; motorSpeed -= 255) 
  {
    analogWrite(motorPin, motorSpeed);
    delay(30);
  }
}

cheers dude, have done that now thanks

Did you just make up your own syntax for analogWrite?

  if (digitalRead(buttonPin) == 0)
  {
    analogWrite(motorPin = 1 && counter <= 3);//turning on motor untill count =3
  }
  else
  {
    analogWrite(motorPin = 1 && counter <= 6);//turning on motor untill count =6
  }

What is the 100ms delay for?

I have a question about the requirements. Once the required number of items has passed and you stop the motor (d or e) what next? Should the Arduino do nothing until it is reset or set the number to 0 and do it all over again? In setup() just program the pins, determine the mode (you can base that on whether the button is pressed after reset), and start the motor. All loop() has to do is count the objects (you already have that working), and when the count reaches 3 or 6 (based on mode) stop the motor.

yes, basicly, I look it up online and try to make it do what i need it to

Basically the motor runs from the start. When the switch button is not pressed (off) the sensor stops the motor every 3 objects.
When the switch button is pressed and held the motor stops every 6 objects instead.

So yeah it does nothing afterwards, youve reached your goal... stopping after 3/6 objects

analogWrite() takes 2 arguments, the pin and value, and results in a compiler error. the result of the arguments is 0/1.

the button needs to be held down for the one case to take effect.

better analogWrite codeing?

#include <LiquidCrystal.h>
LiquidCrystal lcd(1, 2, 4, 5, 6, 7);
#define trigPin 9
#define echoPin 10
#define motorPin 3
#define buttonPin 13

int counter = 0;
int currentState = 0;
int previousState = 0;
int motorSpeed = 0;
int buttonState = 0; 

void setup() {
lcd.begin(16, 2);  
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(motorPin, OUTPUT);// initialize the motor pin as an output:
pinMode(buttonPin, INPUT_PULLUP); // initialize the pushbutton pin as an input:
 
Serial.begin (9600);
lcd.print("items=");  
}
void loop() {
  
     if (digitalRead(buttonPin) == 0 && counter <= 3)
{
   analogWrite(motorPin, 255);//turning on motor untill count =3    
}
  if (digitalRead(buttonPin) == 1 && counter <= 6)
{
   analogWrite(motorPin, 255);//turning on motor untill count =6  
}

 long duration, distance;
 digitalWrite(trigPin, LOW); 
 delayMicroseconds(2); 
 digitalWrite(trigPin, HIGH);
 delayMicroseconds(10); 
 digitalWrite(trigPin, LOW);

 duration = pulseIn(echoPin, HIGH);
 distance = (duration/2) / 29.1;
 if (distance <= 30){
 currentState = 1;
 }
 else {
 currentState = 0;
 }
 delay(100);
 if(currentState != previousState){
if(currentState == 1){
counter = counter + 1;
lcd.print(counter);
    }
 }
for (motorSpeed = 0 ; motorSpeed <= 255; motorSpeed += 255) 
  {
    analogWrite(motorPin, motorSpeed);
    delay(30);
  }
  for (motorSpeed = 255 ; motorSpeed >= 0; motorSpeed -= 255) 
  {
    analogWrite(motorPin, motorSpeed);
    delay(30);
  }
}

so with this code the motor is on and when button is pressed it goes from on to pulseing when counter reaches 6 (step forward! yeah)
(just stays on when button is not pressed, doesnt matter what counter is)

if i change the motor control part to this...

  if (digitalRead(buttonPin) == 0 && counter <= 3)
{
   analogWrite(motorPin, 255);//turning on motor untill count =3    
}
  if (digitalRead(buttonPin) == 1 && counter <= 6)
{
   analogWrite(motorPin, 255);//turning on motor untill count =6  
}

i just get weird letters, symbols and numbers on screen, looks like some unfinished form of hex counting or something?

the code controls the motor in 2 different locations

void loop() {
    if (digitalRead(buttonPin) == 0 && counter <= 3)
    {
        analogWrite(motorPin, 255);//turning on motor untill count =3
    }
    if (digitalRead(buttonPin) == 1 && counter <= 6)
    {
        analogWrite(motorPin, 255);//turning on motor untill count =6
    }
    for (motorSpeed = 0 ; motorSpeed <= 255; motorSpeed += 255)
    {
        analogWrite(motorPin, motorSpeed);
        delay(30);
    }
    for (motorSpeed = 255 ; motorSpeed >= 0; motorSpeed -= 255)
    {
        analogWrite(motorPin, motorSpeed);
        delay(30);
    }

why is there a 2nd

thank you!
the patchwork of code is getting there....

#include <LiquidCrystal.h>
LiquidCrystal lcd(1, 2, 4, 5, 6, 7);
#define trigPin 9
#define echoPin 10
#define motorPin 3
#define buttonPin 13

int counter = 0;
int currentState = 0;
int previousState = 0;
int motorSpeed = 0;
int buttonState = 0; 

void setup() {
lcd.begin(16, 2);  
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(motorPin, OUTPUT);// initialize the motor pin as an output:
pinMode(buttonPin, INPUT_PULLUP); // initialize the pushbutton pin as an input:
 
Serial.begin (9600);
lcd.print("items=");  
}
void loop() {
  
     if (digitalRead(buttonPin) == 0 && counter <= 3)
{
   analogWrite(motorPin, 255);//turning on motor untill count =3    
}
  if (digitalRead(buttonPin) == 1 && counter <= 6)
{
   analogWrite(motorPin, 255);//turning on motor untill count =6  
}
else
{
  analogWrite(motorPin, 0);
}

 long duration, distance;
 digitalWrite(trigPin, LOW); 
 delayMicroseconds(2); 
 digitalWrite(trigPin, HIGH);
 delayMicroseconds(10); 
 digitalWrite(trigPin, LOW);
 duration = pulseIn(echoPin, HIGH);
 distance = (duration/2) / 29.1;
 if (distance <= 30){
 currentState = 1;
 }
 else {
 currentState = 0;
 }
 delay(100);
 if(currentState != previousState){
if(currentState == 1){
counter = counter + 1;
lcd.print(counter);
    }
 }

}

now the motor is on untill counter reaches 6 then turns off, no pulsing or anything! big step forward! so now i have to sort out the button part :exploding_head:

something along these lines?? deleting/changing the parts i dont need (already there) and changing variable names (currentState) ect????

// constants won't change. They're used here to set pin numbers:
const int BUTTON_PIN = 7; // the number of the pushbutton pin

// Variables will change:
int lastState = HIGH; // the previous state from the input pin
int currentState;    // the current reading from the input pin

void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  // initialize the pushbutton pin as an pull-up input
  // the pull-up input pin will be HIGH when the switch is open and LOW when the switch is closed.
  pinMode(BUTTON_PIN, INPUT_PULLUP);
}

void loop() {
  // read the state of the switch/button:
  currentState = digitalRead(BUTTON_PIN);

  if(lastState == LOW && currentState == HIGH)
    Serial.println("The state changed from LOW to HIGH");

  // save the last state
  lastState = currentState;
}

consider


#define Button  A1
#define LED     10

enum { Off = HIGH, On = LOW };

void
setup ()
{
    Serial.begin (9600);

    pinMode (Button, INPUT_PULLUP);

    digitalWrite (LED, Off);
    pinMode (LED,    OUTPUT);
}

void
loop ()
{
    static byte butState = Off;
           byte but      = digitalRead (Button);

    if (butState != but)  {
        butState = but;
        delay (10);     // debounce

        if (On == but)  {
            digitalWrite (LED, ! digitalRead (LED));

            const char *s = digitalRead (LED) ? "Off" : "On";
            Serial.println (s);
        }
    }
}

but it's not obvious how you use a button to start the process and then select 3/6. a single press could start and a 2nd press before reaching 3 could bump the target count to 6.

should a 3rd press stop?