Skip to content

Instantly share code, notes, and snippets.

@owencsmith
Created March 22, 2020 17:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save owencsmith/b41b4b29896b4a2116259c67de1d760f to your computer and use it in GitHub Desktop.
Save owencsmith/b41b4b29896b4a2116259c67de1d760f to your computer and use it in GitHub Desktop.
Arduino sketch for the cleaning subsystem.
/*
* Arduino Sketch to Control Cleaning System:
* Stepper Motor
* Water Solenoid
* Air Solenoid
*/
#include <SPI.h>
#include <HighPowerStepperDriver.h>
#include <Wire.h>
#include <TimerOne.h>
#define SLAVE_ADDRESS 0x08
//I2C
const uint8_t DirPin = 2;
const uint8_t StepPin = 3;
//SPI
const uint8_t CSPin = 4;
//Solenoids
const uint8_t AirPin = 5;
const uint8_t SanitizePin = 7;
// This period is the length of the delay between steps, which controls the
// stepper motor's speed. You can increase the delay to make the stepper motor
// go slower. If you decrease the delay, the stepper motor will go faster, but
// there is a limit to how fast it can go before it starts missing steps.
const uint16_t StepPeriodUs = 2000;
//The number of steps to advance the stepper enough to move the cups to the next stage of the cleaning process
const uint16_t advanceQuadrant = 1000;
HighPowerStepperDriver sd;
boolean cupInQuadrant[4] = {0,0,0,0};
volatile bool receiveFlag = false;
int receiveBuffer[9];
volatile bool endWashCycle = true;
bool washing = false;
void setup() {
//Setup for motor driver
SPI.begin();
sd.setChipSelectPin(CSPin);
// Drive the STEP and DIR pins low initially.
pinMode(StepPin, OUTPUT);
digitalWrite(StepPin, LOW);
pinMode(DirPin, OUTPUT);
digitalWrite(DirPin, LOW);
//Drive the Solenoid pins low initially.
pinMode(SanitizePin, OUTPUT);
digitalWrite(SanitizePin, LOW);
pinMode(AirPin, OUTPUT);
digitalWrite(AirPin, LOW);
// Give the driver some time to power up.
delay(1000);
// Reset the driver to its default settings and clear latched status
// conditions.
sd.resetSettings();
sd.clearStatus();
// Select auto mixed decay. TI's DRV8711 documentation recommends this mode
// for most applications, and we find that it usually works well.
sd.setDecayMode(HPSDDecayMode::AutoMixed);
// Set the current limit. You should change the number here to an appropriate
// value for your particular system.
sd.setCurrentMilliamps36v4(1000);
// Set the number of microsteps that correspond to one full step.
sd.setStepMode(HPSDStepMode::MicroStep32);
// Enable the motor outputs.
sd.enableDriver();
// Set the default stepping direction
sd.setDirection(0);
//Setup for I2C
Serial.begin(9600); // start serial for output
Wire.begin(SLAVE_ADDRESS);
Wire.onReceive(receiveData);
Wire.onRequest(sendData);
Serial.println("I2C Ready!");
//Setup Timer uses length of wash cycle
Timer1.initialize(300000000);
Timer1.attachInterrupt(setVariableToEndWash);
}
void loop() {
delay(100);
if(receiveFlag){
runOnReceivedData();
noInterrupts();
receiveFlag = false;
interrupts();
}
if(endWashCycle){
endWash();
noInterrupts();
endWashCycle = false;
interrupts();
}
}
/**
* The function that runs when an I2C message is received. Turns on a flag that is polled by the main loop().
* @params: bytecount the number of bytes in the message (unused right now but required as function linked to I2C receive)
*/
void receiveData(int byteCount){
while(Wire.available()){
Wire.read();
}
receiveFlag = true;
}
/**
* #Unused - The function that sends data on the I2C bus.
*/
void sendData(){
if (receiveBuffer[0] == 99){
//writeData(keepCount());
}
else{
Serial.println("No function for this address");
}
}
/**
* If a cup place I2C message is received the loop calls this. If the system is not running a wash cycle, advances the quadrant,
* updates the inner cup position model, and starts the wash cycle.
*/
void runOnReceivedData(){
if(!washing){
advanceOneStage();
advanceCupPositionModel(false);
startWashCycle();
}
}
/**
* Sets the
*/
void openSanitizeSolenoid(){
digitalWrite(SanitizePin, HIGH);
}
void openAirSolenoid(){
void closeSanitizeSolenoid(){
digitalWrite(SanitizePin, LOW);
}
void closeAirSolenoid(){
digitalWrite(AirPin, LOW);
}
void advanceOneStage(){
for(unsigned int x = 0; x < advanceQuadrant; x++)
{
sd.step();
delayMicroseconds(StepPeriodUs);
}
}
void advanceCupPositionModel(boolean firstPosition){
for(int i=1; i<4; i++){
cupInQuadrant[i] = cupInQuadrant[i-1];
}
cupInQuadrant[0] = firstPosition;
}
void startWashCycle(){
if(cupInQuadrant[1]){
openSanitizeSolenoid();
}
if(cupInQuadrant[2]){
openSanitizeSolenoid();
}
if(cupInQuadrant[3]){
openAirSolenoid();
}
Timer1.start();
washing = true;
}
void setVariableToEndWash(){
endWashCycle = true;
}
void endWash(){
closeSanitizeSolenoid();
closeAirSolenoid();
Timer1.stop();
washing = false;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment