#include #include #include #include // --- 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(ledsA, NUM_LEDS_A); FastLED.addLeds(ledsB, NUM_LEDS_B); FastLED.addLeds(ledsC, NUM_LEDS_C); FastLED.addLeds(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(); }