Stepper Shield Lemonade Stand

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
User avatar
AlaskaJeff
 
Posts: 37
Joined: Sat Jan 11, 2014 1:29 am

Re: Stepper Shield Lemonade Stand

Post by AlaskaJeff »

lemonbotfirstday.jpg
lemonbotfirstday.jpg (88.39 KiB) Viewed 1102 times
The Eagle has landed. The debut at Kasiloff River, Alaska, was a smash, with six customers

User avatar
adafruit_support_bill
 
Posts: 88136
Joined: Sat Feb 07, 2009 10:11 am

Re: Stepper Shield Lemonade Stand

Post by adafruit_support_bill »

Awesome! And solar powered too!

Alaska is a long way to go for ordinary lemonade. But it might just be worth the drive for laser treated.

User avatar
egutting
 
Posts: 297
Joined: Wed Nov 14, 2012 12:57 am

Re: Stepper Shield Lemonade Stand

Post by egutting »

This is so awesome!!

User avatar
AlaskaJeff
 
Posts: 37
Joined: Sat Jan 11, 2014 1:29 am

Re: Stepper Shield Lemonade Stand

Post by AlaskaJeff »

The Man eventually kicked us out of our spot at the Kasilof river boat launch. Our initial post-marketing analysis reveals the following:

1. You can't trust the Man if you're running a small business.

2. The electrodes that detect when the cup is full are very twitchy. Analog things are like a very hot girlfriend with borderline personality- you really want to make it work, but the instability gets old after a while. We believe that after a dunk in the lemonade, the electrolytes on the electrodes change the conductivity. If they have time to dry, it make them less sensitive. If they are wet, they are too sensitive. We can change the electrodes with each sale, but that is tedious. We tried the TMP 36, but its too slow to react. We will try a plain thermistor. The ultimate fall-back is to fill the cup with a timer. As long as the ice in consistent, this works, and still satisfies the unknowing masses, but its not satisfying to us. We will try once again to go it on a digital pin with a pull-up. Any ideas are appreciated, but not expected.

3. We got rid of our "Basic Laser Treatment." We only do"plain" lemonade, and "deluxe" laser treatment, because that is what our customers tell us they want. We have converted the "basic" protocol into laser treatment for bottled water so we can expand into the low carb market.

User avatar
adafruit_support_bill
 
Posts: 88136
Joined: Sat Feb 07, 2009 10:11 am

Re: Stepper Shield Lemonade Stand

Post by adafruit_support_bill »

I've used ultrasonic sensors in my Arduwino to detect fluid levels in wine glasses with good results. The Maxbotix sensors we carry here have a close-range limit of about 6". If you can find a Ping sensor, they go as close as a few centimeters.

User avatar
AlaskaJeff
 
Posts: 37
Joined: Sat Jan 11, 2014 1:29 am

Re: Stepper Shield Lemonade Stand

Post by AlaskaJeff »

Your idea is great. I actually have a Ping Sensor and have positioned it on the sensor arm. It functions well when I put in on an independent arduino with just the snesing loop. It detects a fluid level at 2cm, which is great. Unfortunately, when I put the same code into the lemonade program where I have previously put the electrode or the TMP 36 (they worked, just not as accurately as required) it doesn't fire the filling solonoid valve. Also it doesn't serial print the range.
  
  if (plain) //This runs plain lemonade without laser treatment. What loser wants that? Lasers are the WAY.
  {

    // turns the red "underway" light on
    digitalWrite(rightLight,HIGH); // turns on the right switchlight- this is the white adafruit MOM switch
  
  myStepper2->step(2025, BACKWARD, DOUBLE);//move conveyor to the fill position
  myStepper1->step(55, FORWARD, MICROSTEP);//put in the fill sensor
   
delay(500 );
      int uS = sonar.ping();
      Serial.print("Ping: ");
      Serial.print(uS / US_ROUNDTRIP_CM);
      Serial.println("cm");
  
  
  while (uS / US_ROUNDTRIP_CM > 3);
  {
    
    delay(50);
      int uS = sonar.ping();
      Serial.print("Ping: ");
      Serial.print(uS / US_ROUNDTRIP_CM);
      Serial.println("cm");
    digitalWrite(fillRelay,LOW);
    
  }
  digitalWrite(fillRelay,HIGH);//closes the fill valve
  
  myStepper1->step(55, BACKWARD, MICROSTEP);// moves the sensor out of the lemonade
  
  delay(500);
  
  myStepper2->step(2000 , FORWARD, DOUBLE);// moves drink back to the start
   //resets the ready green light
  // stops the red 'underway' light
  digitalWrite(rightLight,LOW);// turns the right light off
    
  }
  
Another issue is that the Stepper the moves the sensor module locks into position, even when the program is in the 'resting' phase (where waits for the 3 Bool paths). This only occurs after the protocol has been run once.

User avatar
adafruit_support_bill
 
Posts: 88136
Joined: Sat Feb 07, 2009 10:11 am

Re: Stepper Shield Lemonade Stand

Post by adafruit_support_bill »

Hard to say. Often when microcontroller programs start acting wacky after an incremental change memory problems are to blame. http://learn.adafruit.com/memories-of-an-arduino

If you post the whole code we can take a look.

When posting code, use the </> button instead of the quote button. That makes it easier for us to cut & paste into an editor. All that pretty HTML color coding confuses the heck out of the compiler.

User avatar
AlaskaJeff
 
Posts: 37
Joined: Sat Jan 11, 2014 1:29 am

Re: Stepper Shield Lemonade Stand

Post by AlaskaJeff »

Ok. Here is the entire code: I think I need to run a loop that pings every 50microseconds, that keep the fill solonoid open, and then escapes when the distance <= 2 cm, closing the valve. The previous analog sensors didn't need to keep pinging.

Code: Select all

/*
This is a test sketch for the Adafruit assembled Motor Shield for Arduino v2 It won't work with v1.x motor shields! Only for the v2's with built in PWM control
For use with the Adafruit Motor Shield v2
----> http://www.adafruit.com/products/1438
*/
  #include <Wire.h>
  #include <Adafruit_MotorShield.h>
  #include "utility/Adafruit_PWMServoDriver.h"
  #include <NewPing.h>
 
  
    
    
Adafruit_MotorShield AFMStop(0x60);// Default address- no jmpers.
Adafruit_MotorShield AFMSbot(0x61); // Rightmost jumper closed Adafruit_MotorShield AFMStop(0x60); 
Adafruit_StepperMotor *myStepper1 = AFMStop.getStepper(200,1);
Adafruit_StepperMotor *myStepper2 = AFMStop.getStepper(200,2);
Adafruit_StepperMotor *myStepper3 = AFMSbot.getStepper(200,1);
Adafruit_StepperMotor *myStepper4 = AFMSbot.getStepper(200,2);

#define TRIGGER_PIN 12
#define ECHO_PIN 11
#define MAX_DISTANCE 200
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
int basicSwitch = 4;
int plainSwitch = 3;
int deluxeSwitch = 5;
int fillSensor = 0;
int fillRelay = 7;
int blueLaser = 8;
int greenLaser = 9;
int rightLight = 10;
int middleLight = 1;
int leftLight = 2;
int redLaser= 13;
int delayPeriod = 1000;

  void setup ()
  {

  AFMSbot.begin(); // Start the bottom shield
  AFMStop.begin(); // Start the top shield

  Serial.begin(115200); // 

  myStepper1->setSpeed(30); //sensor speed
  myStepper2->setSpeed(100); //conveyor speed
  myStepper3->setSpeed(200); //laser horizontal
  myStepper4->setSpeed(50); //laser vertical speed
    Serial.begin(115200); // set up Serial library at 115200 for the ping ;
   
  pinMode(basicSwitch,INPUT_PULLUP); //select basic lemonade
  pinMode(plainSwitch,INPUT_PULLUP); //select the basic laser
  pinMode(deluxeSwitch,INPUT_PULLUP); //select deluxe laser
  //pinMode(fillSensor,INPUT_PULLUP)// the fill sensor has been changed from digital 6 to analog 0
  pinMode(fillRelay,OUTPUT);//the valve filling the cup- relay #1
  pinMode(blueLaser,OUTPUT);//the blue laser relay- relay #2
  pinMode(greenLaser,OUTPUT);//the green laser- relay #3
  pinMode(redLaser,OUTPUT);//the red laser- relay #4
  pinMode(rightLight,OUTPUT); //the right switch light
  pinMode(middleLight, OUTPUT);//the middle switch light
  pinMode(leftLight,OUTPUT);//the left switch light
  }
  
  //relay #1 is fillRelay, relay #2 is greenLaser, relay #3 is blueLaser, relay# 4 is redLaser. 
  
void loop()

{
  
  bool plain = digitalRead(plainSwitch) == LOW; // the right switch for plain lemonade
  
  bool basic = digitalRead(basicSwitch) == LOW; // the middle switch for basic laser treatment
  
  bool deluxe = digitalRead(deluxeSwitch) == LOW; // the right switch for deluxe laser treatment
  
   
  digitalWrite(fillRelay,HIGH); //keeps the fill relay OFF
  digitalWrite(blueLaser,HIGH); //keeps the blue laser relay OFF- this is LOW=ON relay
  digitalWrite(greenLaser,HIGH); //keeps the green laser relay OFF-this is LOW=ON relay
  digitalWrite(redLaser,HIGH); //keeps the red laser relay OFF-this is LOW=ON relay 
   
  
  
  
  
  if (plain)  //This runs plain lemonade without laser treatment. What loser wants that? Lasers are the WAY.
  {

    // turns the red "underway" light on
    digitalWrite(rightLight,HIGH); // turns on the right switchlight- this is the white adafruit MOM switch
  
  myStepper2->step(2025, BACKWARD, DOUBLE);//move conveyor to the fill position
  myStepper1->step(55, FORWARD, MICROSTEP);//put in the fill sensor
   
delay(500 );
      int uS = sonar.ping();
      Serial.print("Ping: ");
      Serial.print(uS / US_ROUNDTRIP_CM);
      Serial.println("cm");
  
  
  while (uS / US_ROUNDTRIP_CM > 3);
  {
    
    delay(50);
      int uS = sonar.ping();
      Serial.print("Ping: ");
      Serial.print(uS / US_ROUNDTRIP_CM);
      Serial.println("cm");
    digitalWrite(fillRelay,LOW);
    
  }
  digitalWrite(fillRelay,HIGH);//closes the fill valve
  
  myStepper1->step(55, BACKWARD, MICROSTEP);// moves the sensor out of the lemonade
  
  delay(500);
  
  myStepper2->step(2000 , FORWARD, DOUBLE);// moves drink back to the start
  
  
  digitalWrite(rightLight,LOW);// turns the right light off
    
  }
  
  else if ( basic) //this runs boittled water
  {
    
    
    digitalWrite(middleLight,HIGH); // turns on the middle switchlight- this is the blue adafruit MOM switch
  myStepper3->step(170,FORWARD,MICROSTEP);//rotate the laser horizontal over the track
  myStepper2->step(100, BACKWARD, DOUBLE);//move conveyor to shot position #1
 
  
  myStepper4->step(90,FORWARD,SINGLE);// aim Laser to position 1
  digitalWrite(blueLaser,LOW);
  delay(1000);
  digitalWrite(blueLaser,HIGH);
  myStepper2->step(200,BACKWARD,DOUBLE);//move the cup to shot #2
  myStepper4->step(2,BACKWARD,SINGLE);//re-aim the laser
  digitalWrite(greenLaser,LOW);
  delay(500);
  digitalWrite(greenLaser,HIGH);
  digitalWrite(blueLaser,LOW);
  delay(500);
  digitalWrite(blueLaser,HIGH);
  myStepper2->step(200,BACKWARD,DOUBLE); //move cup to potion 3
  myStepper4->step(3,BACKWARD,SINGLE);//aim position 3
  digitalWrite(greenLaser,LOW);
  delay(500);
  digitalWrite(greenLaser,HIGH);
  digitalWrite(blueLaser,LOW);
  delay(500);
  digitalWrite(blueLaser,HIGH);
  myStepper3->step(170,BACKWARD,MICROSTEP);// halfway back for final shot
  myStepper2->step(925,BACKWARD,DOUBLE);//moves conveyor to final 
  
  digitalWrite(greenLaser,LOW);
  delay(500);
  digitalWrite(greenLaser,HIGH);
  digitalWrite(blueLaser,LOW);
  delay(300);
  digitalWrite(blueLaser,HIGH);
  
  
  myStepper4->step(85,BACKWARD,SINGLE);//back to start
  myStepper2->step(1425,FORWARD,DOUBLE);//back to the beginning of conveyor
     
     digitalWrite(middleLight,LOW);
  
  }
  
  else if ( deluxe  )
  {
    
    digitalWrite(leftLight,HIGH); // turns on the leeft switchlight- this is the white adafruit MOM switch
  myStepper3->step(190,FORWARD,MICROSTEP);//rotate the laser horizontal over the track
  myStepper2->step(1100, BACKWARD, DOUBLE);//move conveyor to halfway
  myStepper4->step(50,FORWARD,SINGLE);//aim the laserto halfway point
  digitalWrite(greenLaser,LOW);//midway 'treatment" of the empty cup
  delay(500);
  digitalWrite(greenLaser,HIGH);
  digitalWrite(blueLaser,LOW);
  delay(1000);
  digitalWrite(blueLaser,HIGH);
  myStepper4->step(50,BACKWARD,SINGLE);
  myStepper2->step(900,BACKWARD,DOUBLE);//finish moving conveyor to the fill station
  
  myStepper1->step(55, FORWARD, MICROSTEP);//put in the fill sensor
  
  delay(50);
      int uS = sonar.ping();
      Serial.print("Ping: ");
      Serial.print(uS / US_ROUNDTRIP_CM);
      Serial.println("cm");
  
  
  while (uS / US_ROUNDTRIP_CM > 3);
  {
    
    delay(50);
      int uS = sonar.ping();
      Serial.print("Ping: ");
      Serial.print(uS / US_ROUNDTRIP_CM);
      Serial.println("cm");
    digitalWrite(fillRelay,LOW);
    
  }
  digitalWrite(fillRelay,HIGH);//closes the fill valve
  digitalWrite(redLaser,HIGH);//turns the red laser off
  
  myStepper1->step(55,BACKWARD,MICROSTEP);//remove fill sensor
 
  myStepper2->step(500,FORWARD,DOUBLE);//move conveyor quarter way back back.
  myStepper4->step(22,FORWARD,SINGLE);//aim laser cannon to quarter way home
  digitalWrite(greenLaser, LOW);
  delay(delayPeriod);
  digitalWrite(greenLaser,HIGH);
  delay(delayPeriod);
  digitalWrite(blueLaser,LOW);
  delay(delayPeriod);
  digitalWrite(blueLaser,HIGH);
  delay(delayPeriod);
  digitalWrite(greenLaser,LOW);
  delay(500);
  digitalWrite(greenLaser,HIGH);
  delay(500);
  
  myStepper2->step(500,FORWARD,DOUBLE);//move halfway back
  myStepper4->step(40,FORWARD,SINGLE);//aim cannon to halfway back
  digitalWrite(greenLaser, LOW);
  delay(delayPeriod);
  digitalWrite(greenLaser,HIGH);
  delay(delayPeriod);
  digitalWrite(blueLaser,LOW);
  delay(delayPeriod);
  digitalWrite(blueLaser,HIGH);
  
  myStepper4->step(62,BACKWARD,SINGLE);

  myStepper2->step(1000,FORWARD,DOUBLE); //return cup to the beginning
  myStepper3->step(190,BACKWARD,MICROSTEP);
 
     
     digitalWrite(leftLight,LOW);
  
  }
  
}
Last edited by adafruit_support_bill on Wed Jun 11, 2014 1:14 pm, edited 3 times in total.
Reason: please use the </> button when submitting code. press </>, then paste your code between the [code] [/code] tags.

User avatar
adafruit_support_bill
 
Posts: 88136
Joined: Sat Feb 07, 2009 10:11 am

Re: Stepper Shield Lemonade Stand

Post by adafruit_support_bill »

The problem is you have 2 variables called uS. One is defined outside the loop and is the one you test in the loop conditional expression.

The other one is defined inside the loop. it is local to the loop and is created and destroyed on each iteration of the loop.

Code: Select all

while (uS / US_ROUNDTRIP_CM > 3);
  {
    
    delay(50);
      int uS = sonar.ping();     <<<-------------------- This line re-defines a local copy of uS.  
      Serial.print("Ping: ");
      Serial.print(uS / US_ROUNDTRIP_CM);
      Serial.println("cm");
    digitalWrite(fillRelay,LOW);
    
  }
Removing the 'int' eliminates the dual definition. Now your original uS variable should be updated by the loop.

Code: Select all

while (uS / US_ROUNDTRIP_CM > 3);
  {
    
    delay(50);
      uS = sonar.ping();
      Serial.print("Ping: ");
      Serial.print(uS / US_ROUNDTRIP_CM);
      Serial.println("cm");
    digitalWrite(fillRelay,LOW);
    
  }

User avatar
AlaskaJeff
 
Posts: 37
Joined: Sat Jan 11, 2014 1:29 am

Re: Stepper Shield Lemonade Stand

Post by AlaskaJeff »

pingsensor.jpg
pingsensor.jpg (38.65 KiB) Viewed 880 times
This works. You rule. This photo shows it partly backed off from the fill position.

User avatar
AlaskaJeff
 
Posts: 37
Joined: Sat Jan 11, 2014 1:29 am

Re: Stepper Shield Lemonade Stand

Post by AlaskaJeff »

newspaper.jpg
newspaper.jpg (65.55 KiB) Viewed 843 times
interview.jpg
interview.jpg (74.25 KiB) Viewed 843 times
Alaska Lemonade Day was a triumph. The devise served >120 laser-treated lemonades without technical problems. The media went wild.

Now onto a weather station and fish detector.

Thanks again to this Adafruit for all the help.

User avatar
adafruit_support_bill
 
Posts: 88136
Joined: Sat Feb 07, 2009 10:11 am

Re: Stepper Shield Lemonade Stand

Post by adafruit_support_bill »

Great work! Looking forward to seeing your next projects.

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”