310 lines
6.6 KiB
C++
Executable File
310 lines
6.6 KiB
C++
Executable File
#include <Wire.h>
|
|
#include <LiquidCrystal_I2C.h>
|
|
#include <LcdBarGraphX.h>
|
|
#include <FastLED.h>
|
|
|
|
|
|
// --- LEDS ---
|
|
#define LED_TYPE WS2811
|
|
#define COLOR_ORDER RGB
|
|
#define MASTER_BRIGHTNESS 200
|
|
|
|
#define DATA_PIN_A 11 // update pin numbers for data lines as needed
|
|
#define DATA_PIN_B 10
|
|
#define DATA_PIN_C 8
|
|
#define DATA_PIN_D 9
|
|
|
|
#define NUM_LEDS_A 22 // adjust number of pixels as needed
|
|
#define NUM_LEDS_B 12
|
|
#define NUM_LEDS_C 12
|
|
#define NUM_LEDS_D 22
|
|
|
|
CRGB ledsA[NUM_LEDS_A];
|
|
CRGB ledsB[NUM_LEDS_B];
|
|
CRGB ledsC[NUM_LEDS_C];
|
|
CRGB ledsD[NUM_LEDS_D];
|
|
|
|
static uint8_t hueA=123;
|
|
|
|
|
|
|
|
// --- Robot Functionality ---
|
|
|
|
// Initialize LCD
|
|
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
|
|
|
|
LcdBarGraphX bar(&lcd, 20, 0, 3); // -- Second line at column 0
|
|
|
|
// Define ports
|
|
int poti_port=A0;
|
|
int poti_value=0;
|
|
int amount=0;
|
|
int poti_last_value;
|
|
int poti_read;
|
|
int poti_new_value;
|
|
|
|
int button_port=12;
|
|
int button_pressed=0;
|
|
|
|
int relay_port=13;
|
|
bool relay_status=false;
|
|
|
|
bool pump_running=false;
|
|
char state='i';
|
|
|
|
int led_bottle = 1;
|
|
int led_pump = 2;
|
|
int led_glass= 3;
|
|
|
|
unsigned long previousMillis=0;
|
|
unsigned long currentMillis=0;
|
|
|
|
// 500ml/min mean 120ms per ml
|
|
int ms_per_ml=132;
|
|
int ml_pumped=0;
|
|
|
|
void setup()
|
|
{
|
|
|
|
// --- Robot Functionality ---
|
|
|
|
pinMode(button_port, INPUT);
|
|
pinMode(relay_port, OUTPUT);
|
|
|
|
//Initialize lcd
|
|
lcd.begin(20,4);
|
|
|
|
// Standard Set text
|
|
lcd.setCursor ( 0, 0 );
|
|
lcd.print(" * * Cockstar * * ");
|
|
lcd.setCursor ( 0, 1 );
|
|
lcd.print("Starting... ");
|
|
|
|
Serial.begin(9600);
|
|
|
|
// --- LEDS ---
|
|
delay(2500); //power up delay
|
|
FastLED.addLeds<LED_TYPE, DATA_PIN_A, COLOR_ORDER>(ledsA, NUM_LEDS_A);
|
|
FastLED.addLeds<LED_TYPE, DATA_PIN_B, COLOR_ORDER>(ledsB, NUM_LEDS_B);
|
|
FastLED.addLeds<LED_TYPE, DATA_PIN_C, COLOR_ORDER>(ledsC, NUM_LEDS_C);
|
|
FastLED.addLeds<LED_TYPE, DATA_PIN_D, COLOR_ORDER>(ledsD, NUM_LEDS_D);
|
|
FastLED.setBrightness(MASTER_BRIGHTNESS);
|
|
FastLED.clear();
|
|
|
|
}
|
|
|
|
void loop()
|
|
{
|
|
// --- Robot Functionality ---
|
|
|
|
// Read status of poti
|
|
poti_read =analogRead(A0);
|
|
//
|
|
poti_new_value=map(poti_read,0,1023,0,101);
|
|
if(poti_value != poti_new_value && poti_last_value != poti_new_value) {
|
|
poti_last_value=poti_value;
|
|
poti_value=poti_new_value;
|
|
}
|
|
|
|
|
|
// Read status of button
|
|
int button_pressed=digitalRead(button_port);
|
|
Serial.println(button_pressed);
|
|
|
|
// Reset title
|
|
lcd.setCursor ( 0, 0 );
|
|
lcd.print(" * * Cockstar * * ");
|
|
|
|
// States:
|
|
// i: idle
|
|
// w: waiting
|
|
// r: Running
|
|
// f: Finished
|
|
|
|
// lcd.print(" ");
|
|
|
|
switch(state){
|
|
case 'i':
|
|
// Idle
|
|
lcd.setCursor ( 0, 1 );
|
|
lcd.print("Ready. Place glass. ");
|
|
pump_running=false;
|
|
previousMillis=millis();
|
|
|
|
// Print bar graph only if pump running
|
|
if(poti_value>0){
|
|
bar.drawValue(ml_pumped,poti_value);
|
|
} else {
|
|
lcd.print(" ");
|
|
}
|
|
|
|
if(button_pressed){
|
|
state='w';
|
|
}
|
|
break;
|
|
|
|
case 'w':
|
|
// Waiting until glass is finally placed
|
|
lcd.setCursor ( 0, 1 );
|
|
lcd.print("Wait... ");
|
|
lcd.print(" ");
|
|
|
|
if(!button_pressed){
|
|
state='i';
|
|
}
|
|
|
|
// wait 500ms
|
|
if(millis()-previousMillis>500) {
|
|
state='r';
|
|
previousMillis=millis();
|
|
}
|
|
break;
|
|
|
|
case 'r':
|
|
// Pump is running
|
|
pump_running=true;
|
|
|
|
if(!button_pressed){
|
|
state='i';
|
|
}
|
|
|
|
// Run pump only when poti at least 1ml
|
|
if(poti_value > 0){
|
|
|
|
// If poti is over 100ml, run forever
|
|
if(poti_value > 100) {
|
|
lcd.setCursor ( 0, 1 );
|
|
lcd.print("Pump running. ");
|
|
} else {
|
|
|
|
// Else, normal mode limited by poti_value
|
|
lcd.setCursor ( 0, 1 );
|
|
lcd.print("Filling glass. ");
|
|
|
|
ml_pumped=int((millis()-previousMillis)/ms_per_ml);
|
|
|
|
if(ml_pumped >= poti_value) {
|
|
pump_running=false;
|
|
state='f';
|
|
previousMillis=millis();
|
|
}
|
|
|
|
lcd.setCursor ( 0, 3 );
|
|
|
|
// Print bar graph only if pump running
|
|
if(poti_value>0){
|
|
bar.drawValue(ml_pumped,poti_value);
|
|
} else {
|
|
lcd.print(" ");
|
|
}
|
|
}
|
|
} else {
|
|
lcd.setCursor ( 0, 1 );
|
|
lcd.print("Pump deactivated. ");
|
|
pump_running=false;
|
|
|
|
}
|
|
break;
|
|
|
|
case 'f':
|
|
// Glass filled
|
|
lcd.setCursor ( 0, 1 );
|
|
lcd.print("Ready, remove glass.");
|
|
|
|
if(!button_pressed){
|
|
state='i';
|
|
}
|
|
break;
|
|
}
|
|
|
|
// Update pump status
|
|
if(pump_running) {
|
|
digitalWrite(relay_port, 1);
|
|
} else {
|
|
digitalWrite(relay_port, 0);
|
|
}
|
|
|
|
// Update fluid amount
|
|
//lcd.setCursor ( 0, 2 );
|
|
//lcd.print(" ");
|
|
lcd.setCursor ( 0, 2 );
|
|
|
|
if(poti_value==0) {
|
|
lcd.print("Amount: None ");
|
|
} else {
|
|
if(poti_value>100) {
|
|
lcd.print("Amount: Infinite ");
|
|
} else {
|
|
lcd.print(String("Amount: ") + poti_value + "ml ");
|
|
}
|
|
}
|
|
|
|
|
|
// --- LEDS ---
|
|
EVERY_N_MILLISECONDS(50) {
|
|
//static uint8_t hueA;
|
|
fill_solid(ledsA, NUM_LEDS_A, CHSV(hueA, 255, 255));
|
|
hueA++;
|
|
}
|
|
|
|
|
|
|
|
//------code for the second strip, ledsB here------
|
|
// Putting the ledsB pattern inside this EVERY_N section allows
|
|
// the speed for just this strip to be individually adjusted.
|
|
// This will run every 500 milliseconds.
|
|
// Use ledsB in this section, such as ledsB[i], and NUM_LEDS_B
|
|
// with for loops so it uses the correct length of strip B.
|
|
// For example:
|
|
|
|
// EVERY_N_MILLISECONDS(20) {
|
|
|
|
// }
|
|
|
|
|
|
|
|
//------code for ledsC pattern------
|
|
// This strip can run a similar or different pattern, and have
|
|
// it's own timing. This will run every 35 milliseconds.
|
|
// Use ledsC[i] and NUM_LEDS_C in this section.
|
|
|
|
EVERY_N_MILLISECONDS(20) {
|
|
static uint8_t hueC;
|
|
static uint8_t brightnessC;
|
|
static uint8_t countC;
|
|
//fill_solid(ledsC, NUM_LEDS_B, CHSV(hueB, 255, 255));
|
|
//hueB++;
|
|
|
|
if(state=='f'){
|
|
fill_solid(ledsC, NUM_LEDS_C, CHSV(255, 0, brightnessC));
|
|
countC++;
|
|
if(countC==10){
|
|
countC=0;
|
|
if(brightnessC<10){
|
|
brightnessC=255;
|
|
} else {
|
|
brightnessC=0;
|
|
}
|
|
}
|
|
} else {
|
|
fill_solid(ledsC, NUM_LEDS_C, CHSV(hueC, 255, 255));
|
|
}
|
|
hueC++;
|
|
}
|
|
|
|
|
|
|
|
//------code for ledsLogo pattern------
|
|
// This strip can also do it's own individual thing.
|
|
// Use ledsD and NUM_LEDS_D in this section.
|
|
|
|
EVERY_N_MILLISECONDS(20) {
|
|
fill_rainbow( ledsD, NUM_LEDS_D, millis()/5, 12);
|
|
}
|
|
|
|
|
|
// Update the display for all strips.
|
|
FastLED.show();
|
|
|
|
}
|