LIS3DH and Motor Driver Code. Has the tilt to pour algorithm using case statements and a while(1) loop

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
tomo21
Date:
Wed Sep 03 15:29:28 2014 +0000
Commit message:
Updated with initial code.

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Sep 03 15:29:28 2014 +0000
@@ -0,0 +1,381 @@
+#include "mbed.h"
+ 
+#define LIS3DH_CTRL_REG1 (0x20) // CTRL_REG1 Sample Rate
+#define LIS3DH_CTRL_REG4 (0x23) // CTRL_REG4 Resolution
+#define LIS3DH_CFG_REG  (0x1F)  // ADC, Temp Sensor Register
+#define LIS3DH_ADDR     (0x30)  // LIS3DH address
+ 
+I2C i2c(I2C_SDA, I2C_SCL);
+ 
+//DigitalOut myled(LED1);
+ 
+Serial pc(SERIAL_TX, SERIAL_RX);
+ 
+//volatile char Accel[] = "+abc.d C";
+
+uint8_t z_val_l, z_val_h, x_val_l, x_val_h, y_val_l, y_val_h, out_3_l, out_3_h;
+int16_t z_val, x_val, y_val; 
+int16_t start, finish, out_3, celsius, fahrenheit;
+
+float p, p1, p2;
+
+float threshold = -25;
+int accel_count = 20;
+int accel_counter = 20;
+float Q = .2; //mL per ms
+float volume_initial = 750;
+float volume_poured = 750;
+float volume_current = 750;
+
+float motor_current_limit = .04;
+
+enum motor_state {start_pour, valve_closed, valve_open, closing_time};
+
+motor_state state = valve_closed;
+
+DigitalOut motor1(PA_10);
+DigitalOut motor2(PB_3);
+
+//NEED TO DETERMINE PINS
+/*
+DigitalOut LED_1(PA_1);
+DigitalOut LED_2(PA_2);
+DigitalOut LED_3(PA_3);
+DigitalOut LED_4(PA_4);
+DigitalOut LED_5(PA_5);
+*/
+AnalogIn motor_current(PA_0);
+
+Timer volume_timer;
+
+void stop_motor(){
+    motor1 = 1;
+    motor2 = 1;
+    wait_us(10);
+    motor1 = 0;
+    motor2 = 0; 
+}
+
+void open_valve(){
+    motor1 = 1;
+    motor2 = 0;    
+}
+
+void close_valve(){
+    motor1 = 0;
+    motor2 = 1;    
+}
+
+
+void read_accel()
+{
+    
+        char data_write[2];
+        char data_read[2];
+ 
+        // Configure the Accelerometer device LIS3DH:
+
+        data_write[0] = LIS3DH_CTRL_REG1;
+        data_write[1] = 0x77;   //400hz, Normal mode, Z Y X axis on
+        i2c.write(LIS3DH_ADDR, data_write, 2, 0);
+    
+        data_write[0] = LIS3DH_CTRL_REG4;
+        data_write[1] = 0x08;   //2g, high res
+        i2c.write(LIS3DH_ADDR, data_write, 2, 0); 
+    
+        data_write[0] = LIS3DH_CFG_REG;
+        data_write[1] = 0xC0;   //ADC on, temp sensor on
+        i2c.write(LIS3DH_ADDR, data_write, 2, 0); 
+        
+        // Read Acceleration Registers
+        
+        //X axis
+        data_write[0] = 0x28; //X axis Low Byte
+        i2c.write(LIS3DH_ADDR, data_write, 1, 1); // no stop (unsure)
+        i2c.read(LIS3DH_ADDR, data_read, 1, 0);
+        x_val_l = data_read[0];
+        
+        data_write[0] = 0x29; //X axis High Byte
+        i2c.write(LIS3DH_ADDR, data_write, 1, 1); // no stop (unsure)
+        i2c.read(LIS3DH_ADDR, data_read, 1, 0);
+        x_val_h = data_read[0];
+        
+        //convert from two separate bytes to one int
+        x_val = ((x_val_h) << 8) | x_val_l;
+        
+        float x = ((float)x_val * 0.061035f) / 1000.0f;
+        
+        //Y axis
+        data_write[0] = 0x2A; //X axis Low Byte
+        i2c.write(LIS3DH_ADDR, data_write, 1, 1); // no stop (unsure)
+        i2c.read(LIS3DH_ADDR, data_read, 1, 0);
+        y_val_l = data_read[0];
+        
+        data_write[0] = 0x2B; //X axis High Byte
+        i2c.write(LIS3DH_ADDR, data_write, 1, 1); // no stop (unsure)
+        i2c.read(LIS3DH_ADDR, data_read, 1, 0);
+        y_val_h = data_read[0];
+        
+        //convert from two separate bytes to one int
+        y_val = ((y_val_h) << 8) | y_val_l;
+        
+        float y = ((float)y_val * 0.061035f) / 1000.0f;
+        
+        //Z axis
+        data_write[0] = 0x2C; //X axis Low Byte
+        i2c.write(LIS3DH_ADDR, data_write, 1, 1); // no stop (unsure)
+        i2c.read(LIS3DH_ADDR, data_read, 1, 0);
+        z_val_l = data_read[0];
+        
+        data_write[0] = 0x2D; //X axis High Byte
+        i2c.write(LIS3DH_ADDR, data_write, 1, 1); // no stop (unsure)
+        i2c.read(LIS3DH_ADDR, data_read, 1, 0);
+        z_val_h = data_read[0];
+        
+        //convert from two separate bytes to one int
+        z_val = ((z_val_h) << 8) | z_val_l;
+        
+        float z = ((float)z_val * 0.061035f) / 1000.0f;
+        
+        //Calculate Pitch (angle from X axis, which is vertical in the bottle orientation)
+        // pitch is in radians (-pi/2 to pi/2)
+                
+        float yz_sq = sqrt(y*y + z*z);
+        float pitch = atan2(x, yz_sq);
+        float pitch_deg = pitch * 57.2957795;
+             
+        //display result
+        
+        pc.printf("X acceleration = %f\n", x);
+        pc.printf("Y acceleration = %f\n", y);
+        pc.printf("Z acceleration = %f\n", z);
+        pc.printf("\n");
+        pc.printf("Pitch = %f\n", pitch_deg);
+        
+        //filter pitch values
+        p2 = p1;
+        p1 = p;
+        p += -.2 * (p - pitch_deg); 
+}
+
+
+int tilt_up()
+{
+        if (p2 < p1 && p1 < p)
+        {
+            accel_count = 20;
+            return 1;
+        }
+        else
+        { return 0;}
+}
+
+int detect_current_spike()
+{
+    if(motor_current.read() >= motor_current_limit)
+        {
+            //the motor has finished opening or closing the valve
+            return 1;
+        }
+    else
+        {
+            //the motor is still opening or closing the valve
+            return 0;
+        }
+}
+    
+
+
+
+
+int detect_tilt()
+{
+ //detect tilt algorithm
+        
+        //if the pitch goes below the threshold for 20 samples
+        if (p < threshold)
+        {
+            accel_count --;
+        }
+        //reset the sample count if the bottle is tilting upright
+        else if (p2 < p1 && p1 < p)
+        {
+            accel_count = accel_counter;
+        }
+        else 
+        {
+            accel_count = accel_counter;
+        }
+        
+        //
+        if (accel_count <=0)
+        {
+            //we're tilted!
+            return 1;
+        }
+        else
+        { return 0;}    
+        
+        
+}
+
+
+/*void LED_track()
+{
+    if(volume_current <= 150)
+    {
+     LED_1 = 0;
+     LED_2 = 0;
+     LED_3 = 0;
+     LED_4 = 0;
+     LED_5 = 0;
+    }
+    if(volume_current > 150 && volume_current <= 300)
+    {
+     LED_1 = 0;
+     LED_2 = 0;
+     LED_3 = 0;
+     LED_4 = 0;
+     LED_5 = 1;
+    }
+    if(volume_current > 300 && volume_current <= 450)
+    { 
+     LED_1 = 0;
+     LED_2 = 0;
+     LED_3 = 0;
+     LED_4 = 1;
+     LED_5 = 1;
+    }
+    if(volume_current > 450 && volume_current <= 600)
+    { 
+     LED_1 = 0;
+     LED_2 = 0;
+     LED_3 = 1;
+     LED_4 = 1;
+     LED_5 = 1;
+    }
+    if(volume_current > 600 && volume_current <= 750)
+    { 
+     LED_1 = 0;
+     LED_2 = 1;
+     LED_3 = 1;
+     LED_4 = 1;
+     LED_5 = 1;
+    }
+    if(volume_current > 750)
+    { 
+     LED_1 = 1;
+     LED_2 = 1;
+     LED_3 = 1;
+     LED_4 = 1;
+     LED_5 = 1;
+    }     
+     
+}
+*/ 
+int main()
+{
+ 
+    
+    
+    /*    
+    if (status != 0) { // Error
+        while (1) {
+            myled = !myled;
+            wait(0.2);
+        }
+    }
+    */   
+ 
+    while (1) {
+        
+        //pc.printf("start");
+        read_accel();
+        //pc.printf("here");
+        switch (state){
+            case valve_closed:
+            {
+                pc.printf("State = valve closed\n");
+                stop_motor();
+                volume_timer.stop();
+                float t_poured = volume_timer.read();
+                volume_poured = Q*t_poured;
+                volume_current -= volume_poured;
+                //LED_track();
+            
+                if (detect_tilt() == 1)
+                {
+                     state = start_pour;
+                     p1 = 0;
+                     p2 = 0;
+                     break;               
+                }
+                else {break;}
+            }
+            
+            case start_pour:
+            {
+                open_valve();
+                pc.printf("Opening Valve!\n");
+                //miss the inital current spike
+                wait(.1);
+                float cur = motor_current.read();
+                pc.printf("Current = %f\n", cur);
+                
+                if (tilt_up() == 1){
+                state = closing_time;    
+                }   
+                else if(detect_current_spike() == 1)
+                {
+                    state = valve_open;
+                    break;
+                }
+                else {break;}
+                
+            }
+            
+            case closing_time:
+            {
+                    close_valve();
+                    pc.printf("Closing Valve!\n");
+                    //miss the initial current spike
+                    wait(.05);
+                    float cur = motor_current.read();
+                    pc.printf("Current = %f\n", cur);
+                if(detect_current_spike() == 1)
+                {
+                    state = valve_closed;
+                    break;
+                }    
+                else {break;}
+            }
+            
+            case valve_open:
+            {
+                pc.printf("Case: valve_open\n");
+                stop_motor();
+                volume_timer.start();
+            
+                if (tilt_up() == 1)
+                {
+                     state = closing_time;
+                     break;               
+                }
+                else {break;}  
+            }   
+            
+        
+        
+        
+            
+        }
+        
+        
+            
+        
+        wait(.1);
+        
+    }
+
+}
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Wed Sep 03 15:29:28 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/6213f644d804
\ No newline at end of file