Created
March 22, 2020 17:57
-
-
Save owencsmith/b41b4b29896b4a2116259c67de1d760f to your computer and use it in GitHub Desktop.
Arduino sketch for the cleaning subsystem.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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