Hackster is hosting Hackster Holidays, Ep. 7: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Friday!Stream Hackster Holidays, Ep. 7 on Friday!
Shahariar
Published © CC BY-SA

Fluid Ejection Controller

A device for controlled ejection of fluid by volume (medicine/ chemical / fuel) or drop by drop for different applications.

IntermediateFull instructions provided8 hours1,839
Fluid Ejection Controller

Things used in this project

Hardware components

BBC micro:bit board
BBC micro:bit board
×1
28YBJ-48 4 Phase Stepper Motor + UNL2003 Driver
×1
SparkFun Breadboard Holder Plastic Base
×1
75 types plastic Gear, Pully, Linear Drive set
×1
Photo-Interruper
×1
3ml Syringe
×1
Resistor 1k ohm
Resistor 1k ohm
×3
Resistor 2.21k ohm
Resistor 2.21k ohm
×1
3 mm LED: Red
3 mm LED: Red
×1
3 mm LED: Green
3 mm LED: Green
×1
5 mm LED: Yellow
5 mm LED: Yellow
×1
Male Header 40 Position 1 Row (0.1")
Male Header 40 Position 1 Row (0.1")
×1
Male/Female Jumper Wires
Male/Female Jumper Wires
×1
Capacitor 47 µF
Capacitor 47 µF
×1
Ceramic Disc Capacitor, 0.1 µF
Ceramic Disc Capacitor, 0.1 µF
×1

Software apps and online services

GNAT Community
AdaCore GNAT Community

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Hot glue gun (generic)
Hot glue gun (generic)
Drill / Driver, Cordless
Drill / Driver, Cordless

Story

Read more

Schematics

Sch

Code

main.adb

ADA
Injection Timer
------------------------ edge connector pin mapping ------------------------------
----------------------------------------------------------------------------------
-- See here : https://makecode.microbit.org/device/pins --------------------------

--  pin(code)      pin (edge connector pads)      hardware connected
--   2         --  large via p2                   -- UNL2003 Ch1
--   13        --  small pad p13                  -- UNL2003 Ch2
--   15        --  small pad p15                  -- UNL2003 CH3
--   14        --  small pad p14                  -- UNL2003 CH4
--   0         --  large via p0                   -- photo interrupt
--   1         --  large via p1                   -- 20 K pot
--   7         --  small pad p7                   -- RED LED
--   10        --  small pad p10                  -- GREEN LED 
--   8         --  small pad p8                   -- YELLOW LED
----------------------------------------------------------------------------------
------------------------- end of comment section ---------------------------------

-- packages/drivers

with MicroBit.IOs;     use MicroBit.IOs;     -- includes microbit GPIO
with MicroBit.Time;                          -- includes microbit time
with MicroBit.Buttons; use MicroBit.Buttons; -- includes ubit button


-- following part for variable declearation
procedure Main is


   Phase_1 : constant MicroBit.IOs.Pin_Id := 2;
   Phase_2 : constant MicroBit.IOs.Pin_Id := 13;
   Phase_3 : constant MicroBit.IOs.Pin_Id := 15;
   Phase_4 : constant MicroBit.IOs.Pin_Id := 14;
   RED_LED :constant MicroBit.IOs.Pin_Id := 7;
   YELLOW_LED :constant MicroBit.IOs.Pin_Id := 8;
   GREEN_LED : constant MicroBit.IOs.Pin_Id := 10;

   POT_ADC_Val : MicroBit.IOs.Analog_Value;  -- 20k pot on pin 1
   POS_ADC_Val : MicroBit.IOs.Analog_Value;  -- photo interrupt on pin 0
   ADC_Temp : MicroBit.IOs.Analog_Value ;    -- ADC type temp variable
   Position_Counter : Integer :=0;



   -- following part for initialization (one time run code)
begin
-- de-energize all the coils of stepper motor
   MicroBit.IOs.Set (Phase_1, False);
   MicroBit.IOs.Set (Phase_2, False);
   MicroBit.IOs.Set (Phase_3, False);
   MicroBit.IOs.Set (Phase_4, False);
   MicroBit.Time.Delay_Ms (100);

   ADC_Temp := 950;
   POT_ADC_Val := MicroBit.IOs.Analog(1);
   POS_ADC_Val := MicroBit.IOs.Analog(0);
  -- loop until button A is pressed
   while MicroBit.Buttons.State (Button_A) /= Pressed loop

      for I in 0 .. (POT_ADC_Val/20) loop
         MicroBit.IOs.Set (RED_LED, True);
         MicroBit.Time.Delay_Ms (250);
         MicroBit.IOs.Set (RED_LED, False);
         MicroBit.Time.Delay_Ms (250);
       

      end loop;

      MicroBit.IOs.Set (GREEN_LED, True);
      MicroBit.Time.Delay_Ms (100);
      MicroBit.IOs.Set (GREEN_LED, False);
      MicroBit.Time.Delay_Ms (150);

      POT_ADC_Val := MicroBit.IOs.Analog(1);
      POS_ADC_Val := MicroBit.IOs.Analog(0);

   end loop;



   --  next part infinite loop (main loop run code)
   loop
      while Position_Counter <7  loop
         POT_ADC_Val := MicroBit.IOs.Analog(1); -- read pot for timing delay
         --MicroBit.Time.Delay_Ms (2000);
         -- blink indication to user
         for I in 0 .. (POT_ADC_Val/20) loop
            MicroBit.IOs.Set (GREEN_LED, True);
            MicroBit.Time.Delay_Ms (500);
            MicroBit.IOs.Set (GREEN_LED, False);
            MicroBit.Time.Delay_Ms (500);
         end loop;
         -- push shaft by energizing 4 coil phases one at a time
         for Y in 0 ..11 loop -- 12 loops make 0.1 ml volume displacement
            MicroBit.IOs.Set (Phase_1, False);
            MicroBit.IOs.Set (Phase_2, False);
            MicroBit.IOs.Set (Phase_3, False);
            MicroBit.IOs.Set (Phase_4, True);
            MicroBit.Time.Delay_Ms (9);
            MicroBit.IOs.Set (Phase_1, False);
            MicroBit.IOs.Set (Phase_2, False);
            MicroBit.IOs.Set (Phase_3, True);
            MicroBit.IOs.Set (Phase_4, False);
            MicroBit.Time.Delay_Ms (9);
            MicroBit.IOs.Set (Phase_1, False);
            MicroBit.IOs.Set (Phase_2, True);
            MicroBit.IOs.Set (Phase_3, False);
            MicroBit.IOs.Set (Phase_4, False);
            MicroBit.Time.Delay_Ms (9);
            MicroBit.IOs.Set (Phase_1, True);
            MicroBit.IOs.Set (Phase_2, False);
            MicroBit.IOs.Set (Phase_3, False);
            MicroBit.IOs.Set (Phase_4, False);
            MicroBit.Time.Delay_Ms (9);
         end loop;
         -- count holes in shaft with photo interrupt
         if POS_ADC_Val< ADC_Temp then
            MicroBit.IOs.Set (YELLOW_LED,True);
            Position_Counter := Position_Counter+1;
         else
            MicroBit.IOs.Set (YELLOW_LED,False);
         end if;
      end loop;
      while Position_Counter >0  loop

         -- MicroBit.Time.Delay_Ms (2000);
         for I in 0 .. (POT_ADC_Val/20) loop
            MicroBit.IOs.Set (RED_LED, True);
            MicroBit.Time.Delay_Ms (500);
            MicroBit.IOs.Set (RED_LED, False);
            MicroBit.Time.Delay_Ms (500);
         end loop;
         -- pull shaft by energizing 4 coil phases  in reverse order
         for X in 0 ..11 loop  -- 0.1 ml volume transfer
            MicroBit.IOs.Set (Phase_1, True);
            MicroBit.IOs.Set (Phase_2, False);
            MicroBit.IOs.Set (Phase_3, False);
            MicroBit.IOs.Set (Phase_4, False);
            MicroBit.Time.Delay_Ms (9);
            MicroBit.IOs.Set (Phase_1, False);
            MicroBit.IOs.Set (Phase_2, True);
            MicroBit.IOs.Set (Phase_3, False);
            MicroBit.IOs.Set (Phase_4, False);
            MicroBit.Time.Delay_Ms (9);
            MicroBit.IOs.Set (Phase_1, False);
            MicroBit.IOs.Set (Phase_2, False);
            MicroBit.IOs.Set (Phase_3, True);
            MicroBit.IOs.Set (Phase_4, False);
            MicroBit.Time.Delay_Ms (9);
            MicroBit.IOs.Set (Phase_1, False);
            MicroBit.IOs.Set (Phase_2, False);
            MicroBit.IOs.Set (Phase_3, False);
            MicroBit.IOs.Set (Phase_4, True);
            MicroBit.Time.Delay_Ms (9);
           

         end loop;
         -- count holes in shaft with photo interrupt
         if POS_ADC_Val< ADC_Temp then
            MicroBit.IOs.Set (YELLOW_LED,True);
            Position_Counter := Position_Counter-1;
         else
            MicroBit.IOs.Set (YELLOW_LED,False);
         end if;
      end loop;
         
         while True loop
         null; -- stop operation
         end loop;

   end loop;
end Main;

-- I have written this code based on examples/drivers from the following link:
-- https://github.com/AdaCore/Ada_Drivers_Library/tree/master/boards/MicroBit
-- by Fabien-Chouteau's work on behalf of ADA driver library on github        

-- DISCLAIMER: License agreement as per contest rules  --

main.adb

ADA
Electronic Dropper
------------------------ edge connector pin mapping ------------------------------
----------------------------------------------------------------------------------
-- See here : https://makecode.microbit.org/device/pins --------------------------

--  pin(code)      pin (edge connector pads)      hardware connected
--   2         --  large via p2                   -- UNL2003 Ch1
--   13        --  small pad p13                  -- UNL2003 Ch2
--   15        --  small pad p15                  -- UNL2003 CH3
--   14        --  small pad p14                  -- UNL2003 CH4
--   0         --  large via p0                   -- photo interrupt
--   1         --  large via p1                   -- 20 K pot
--   7         --  small pad p7                   -- RED LED
--   10        --  small pad p10                  -- GREEN LED 
--   8         --  small pad p8                   -- YELLOW LED
----------------------------------------------------------------------------------
------------------------- end of comment section ---------------------------------

-- packages/drivers

with MicroBit.IOs;     use MicroBit.IOs;     -- includes microbit GPIO
with MicroBit.Time;                          -- includes microbit time
with MicroBit.Buttons; use MicroBit.Buttons; -- includes ubit button



procedure Main is

  -- assigning gpio and adc pins
   Phase_1 : constant MicroBit.IOs.Pin_Id := 2;
   Phase_2 : constant MicroBit.IOs.Pin_Id := 13;
   Phase_3 : constant MicroBit.IOs.Pin_Id := 15;
   Phase_4 : constant MicroBit.IOs.Pin_Id := 14;
   RED_LED :constant MicroBit.IOs.Pin_Id := 7;
   YELLOW_LED :constant MicroBit.IOs.Pin_Id := 8;
   GREEN_LED : constant MicroBit.IOs.Pin_Id := 10;

   -- following part for variable declearation
   POT_ADC_Val : MicroBit.IOs.Analog_Value;  -- 20k pot on pin 1
   POS_ADC_Val : MicroBit.IOs.Analog_Value;  -- photo interrupt on pin 0
   ADC_Temp : MicroBit.IOs.Analog_Value ;    -- ADC type temp variable
   Position_Counter : Integer :=0;



   -- following part for initialization (one time run code)
begin
   -- de-energize all the coils of stepper motor 
   MicroBit.IOs.Set (Phase_1, False);
   MicroBit.IOs.Set (Phase_2, False);
   MicroBit.IOs.Set (Phase_3, False);
   MicroBit.IOs.Set (Phase_4, False);
   MicroBit.Time.Delay_Ms (100);

   ADC_Temp := 950;
   POT_ADC_Val := MicroBit.IOs.Analog(1);
   POS_ADC_Val := MicroBit.IOs.Analog(0);
   -- loop until button A is pressed
   while MicroBit.Buttons.State (Button_A) /= Pressed loop
      -- blink led depending on pot value
      for I in 0 .. (POT_ADC_Val/20) loop
         MicroBit.IOs.Set (RED_LED, True);
         MicroBit.Time.Delay_Ms (250);
         MicroBit.IOs.Set (RED_LED, False);
         MicroBit.Time.Delay_Ms (250);


      end loop;

      MicroBit.IOs.Set (GREEN_LED, True);
      MicroBit.Time.Delay_Ms (100);
      MicroBit.IOs.Set (GREEN_LED, False);
      MicroBit.Time.Delay_Ms (150);

      POT_ADC_Val := MicroBit.IOs.Analog(1);
      POS_ADC_Val := MicroBit.IOs.Analog(0);

   end loop;



   
   loop
      -- loop until B is not pressed
      while MicroBit.Buttons.State (Button_B) /= Pressed   loop
         -- read pot for taking user input to adjust displacement length
         POT_ADC_Val := MicroBit.IOs.Analog(1); 
         --MicroBit.Time.Delay_Ms (2000);

          -- led blink for indication (debugging)
            MicroBit.IOs.Set (RED_LED, True);
            MicroBit.Time.Delay_Ms (500);
            MicroBit.IOs.Set (RED_LED, False);
            MicroBit.Time.Delay_Ms (500);
        
         -- push shaft by powering 4 phases/coils one at a time
         -- 12 loops make 0.1 ml volume displacement
         for Y in 0 ..(POT_ADC_Val/50) loop 
            MicroBit.IOs.Set (Phase_1, False);
            MicroBit.IOs.Set (Phase_2, False);
            MicroBit.IOs.Set (Phase_3, False);
            MicroBit.IOs.Set (Phase_4, True);
            MicroBit.Time.Delay_Ms (9);
            MicroBit.IOs.Set (Phase_1, False);
            MicroBit.IOs.Set (Phase_2, False);
            MicroBit.IOs.Set (Phase_3, True);
            MicroBit.IOs.Set (Phase_4, False);
            MicroBit.Time.Delay_Ms (9);
            MicroBit.IOs.Set (Phase_1, False);
            MicroBit.IOs.Set (Phase_2, True);
            MicroBit.IOs.Set (Phase_3, False);
            MicroBit.IOs.Set (Phase_4, False);
            MicroBit.Time.Delay_Ms (9);
            MicroBit.IOs.Set (Phase_1, True);
            MicroBit.IOs.Set (Phase_2, False);
            MicroBit.IOs.Set (Phase_3, False);
            MicroBit.IOs.Set (Phase_4, False);
            MicroBit.Time.Delay_Ms (9);
         end loop;
         -- count holes in shaft with photo interrupt
         if POS_ADC_Val< ADC_Temp then
         -- indication led blink for user
            MicroBit.IOs.Set (YELLOW_LED,True);
            Position_Counter := Position_Counter+1;
         else
            MicroBit.IOs.Set (YELLOW_LED,False);
         end if;
      end loop;
      -- loop while B button is pressed and hold
      while  MicroBit.Buttons.State (Button_B) = Pressed   loop

         -- MicroBit.Time.Delay_Ms (2000);
         -- read pot for taking user input to adjust displacement length
         POT_ADC_Val := MicroBit.IOs.Analog(1); 
        
            MicroBit.IOs.Set (RED_LED, True);
            MicroBit.Time.Delay_Ms (250);
            MicroBit.IOs.Set (RED_LED, False);
            MicroBit.Time.Delay_Ms (250);
        
         --  pull shaft by powering 4 phases/coils in reverse order
         for X in 0 ..(POT_ADC_Val/50) loop  
            MicroBit.IOs.Set (Phase_1, True);
            MicroBit.IOs.Set (Phase_2, False);
            MicroBit.IOs.Set (Phase_3, False);
            MicroBit.IOs.Set (Phase_4, False);
            MicroBit.Time.Delay_Ms (9);
            MicroBit.IOs.Set (Phase_1, False);
            MicroBit.IOs.Set (Phase_2, True);
            MicroBit.IOs.Set (Phase_3, False);
            MicroBit.IOs.Set (Phase_4, False);
            MicroBit.Time.Delay_Ms (9);
            MicroBit.IOs.Set (Phase_1, False);
            MicroBit.IOs.Set (Phase_2, False);
            MicroBit.IOs.Set (Phase_3, True);
            MicroBit.IOs.Set (Phase_4, False);
            MicroBit.Time.Delay_Ms (9);
            MicroBit.IOs.Set (Phase_1, False);
            MicroBit.IOs.Set (Phase_2, False);
            MicroBit.IOs.Set (Phase_3, False);
            MicroBit.IOs.Set (Phase_4, True);
            MicroBit.Time.Delay_Ms (9);


         end loop;
         -- count holes in shaft with photo interrupt
         if POS_ADC_Val< ADC_Temp then
            MicroBit.IOs.Set (YELLOW_LED,True);
            Position_Counter := Position_Counter+1;
         else
            MicroBit.IOs.Set (YELLOW_LED,False);
         end if;
      end loop;
      -- when B button is released, halt device operation 
      while True loop
         null; -- stop operation, reset device to restart
         end loop;

   end loop;
end Main;

-- I have written this code based on examples/drivers from the following link:
-- https://github.com/AdaCore/Ada_Drivers_Library/tree/master/boards/MicroBit
-- by Fabien-Chouteau's work on behalf of ADA driver library on github        

-- DISCLAIMER: License agreement as per contest rules  --

Credits

Shahariar
74 projects • 266 followers
"What Kills a 'Great life' is a 'Good Life', which is Living a Life Inside While Loop"
Thanks to Fabien Chouteau.

Comments