You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
309 lines
6.6 KiB
309 lines
6.6 KiB
#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(); |
|
|
|
}
|
|
|