Nucleo-transfer
Dependencies: ADS1015 MPU6050 PixelArray PixelArray-Nucleo mbed WS2813
Fork of Nucleo-transfer by
Diff: Sensorplate/main.cpp
- Revision:
- 66:88c910cd4d9e
- Parent:
- 60:2f7e82c6f916
- Child:
- 67:1b300aa30923
--- a/Sensorplate/main.cpp Tue Apr 17 16:11:20 2018 +0000 +++ b/Sensorplate/main.cpp Fri May 25 09:02:28 2018 +0000 @@ -32,16 +32,21 @@ #include "PixelArray.h" #include "WS2812.h" -#define WS2812_BUF 3 -#define NUM_COLORS 5 +#define ALARMBUF 16 +#define NUM_COLORS 8 +#define YELLOW_TRANSITION 12 +#define RED_TRANSITION 15 #define NUM_LEDS_PER_COLOR 3 #define NUMBER_LED_FRONT (3) #define ONE_COLOR +#define TAIL_LENGTH 6 +#define COMET_TAIL_END_INTENSITY 90 +#define FADE_STEPS 20 -InterruptIn button_lock(PC_1); // Input on intterupt base decleration. +InterruptIn button_lock(PC_0); // Input on intterupt base decleration. InterruptIn button_reposition(PC_3); InterruptIn button_mute(PC_2); -InterruptIn button_new_patient(PC_0); +InterruptIn button_new_patient(PC_1); DigitalIn intensity_code(PA_12); DigitalIn colour_code_1(PA_11); @@ -54,9 +59,9 @@ DigitalOut LED_on_dev_board4(LED4); DigitalOut speaker1(PC_12); // relatie aangeven! //neopixel::PixelArray indicator_LEDs(PA_7); -PixelArray px(WS2812_BUF); -//WS2812 ws(PA_7, WS2812_BUF, 3, 9, 9, 6); -WS2812 ws(PA_7, WS2812_BUF, 3, 9, 9, 6); +PixelArray px(ALARMBUF); +//WS2812 ws(PA_7, ALARMBUF, 3, 9, 9, 6); +WS2812 ws(PA_7, ALARMBUF, 3, 12, 8, 12); PwmOut lock_feedback_LED(PB_13); //(PB_1); // Declaration of pulse with modulation outputs. PwmOut mute_feedback_LED(PB_14); //(PB_15); @@ -68,7 +73,9 @@ Timer delay_between_button_pressed; // Timer for time between two buttons (to prevent pressing buttons simultaneously). Timer speaker_timer; // Timer for speaker activation. Timer piezo_electric_sample_timer; // Timer for equally time-spaced samples. -Timer Knight_Rider_Timer; +Timer comet_timer; +Timer reposition_button_hold_timer; +Timer new_patient_button_hold_timer; /* The code underneath this commentbox has some fixed parameters for serial/ADC reading: -> The address for the angle_device_reference_belt is set to 0x68 in the file MPU6050_belt (rule number: 19); @@ -82,14 +89,14 @@ Adafruit_ADS1115 piezo_resistive_adc1(&i2c_sensorplate_adc, 0x48); // i2c pins, i2c address. Adafruit_ADS1115 piezo_resistive_adc2(&i2c_sensorplate_adc, 0x49); // i2c pins, i2c address. Adafruit_ADS1115 piezo_electric_adc(&i2c_sensorplate_adc, 0x4B); // i2c pins, i2c address. -Serial usb_serial(SERIAL_TX, SERIAL_RX); // tx, rx -Serial pi_serial(PC_10, PC_11); // tx, rx +RawSerial usb_serial(SERIAL_TX, SERIAL_RX); // tx, rx +RawSerial pi_serial(PC_10, PC_11); // tx, rx Ticker total_readout_cycle; // Polling cycle. // End of commentbox related to the serial configuration/ADC reading components. int boot_delay_ms = 500; int total_readout_cycle_time_us = 100000; // Cycle time in us. -int total_knight_rider_cycle_time_ms = 1000; +int total_comet_cycle_time_ms = 750/16; int i2c__frequency = 400000; // I2C Frequency. int baud_rate = 115200; // Baud rate. short piezo_resistive_array[8] = {0,0,0,0,0,0,0,0}; // 8 PR sensors 1 time per cycle. @@ -99,7 +106,7 @@ float gyroscope_sensorplate[3]; // Raw gyroscope data. float accelerometer_reference_belt[3]; // Raw accelerometer data from belt. float gyroscope_reference_belt[3]; // Raw gyroscope data from belt. -int colourbuf[NUM_COLORS] = {0xff0000,0x00ff00,0x0000ff,0xffa500,0xffffff}; // hex codes for the different colours +int colourbuf[NUM_COLORS] = {0xff0000,0x00ff00,0x0000ff,0xffa500,0x555555,0x800080,0x000000,0x8B4513}; // hex codes for the different colours char LED_colour = 'w'; // Variable to set LED colour (standard set to green, untill PI sends other character). Other possible colours: red ('r') & yellow ('y'). bool lock_state = false, lock_flag = 0, mute_state = 0, alarm = 0, calibration_flag = 0, intensity_select = 1; // Boolean variables for logging states. bool mute_flag = 0, new_patient_flag = 0, reposition_flag = 0, new_patient_lock_flag = 0, reposition_lock_flag = 0, mute_lock_flag; // Flag variables. @@ -114,9 +121,20 @@ int speaker_active_ms = 750; // Time to iterate speaker on and off when alarm occurs. int alarm_voltage = 2400; // Needed voltage for alarm expressed as a digital 15 bit value (= 20% of max battery voltage). int LED_red_intensity = 0, LED_blue_intensity = 0, LED_green_intensity = 0; // Variables to set LED intensity. +int LED_colour_wheel_percentage=0; +int ring_colour_old,mixer=0; +int colour_wheel_filler = 5; +bool colour_wheel_drain_reposition = false; +bool colour_wheel_drain_new_patient = false; +bool circle_filling_reposition = false; +bool circle_filling_new_patient = false; +int circle_filled_reposition = 0; +int circle_filled_new_patient = 0; +int comet=0; +int tail,tail_step; //short batteryvoltage_current = 0, batteryvoltage_last = 0, powervoltage_current, powervoltage_last; // Variables to manage batteryvoltage. Maybe change current to other? //const int digital_value_ADC_powervoltage_unplugged = 15000; // Digital value to set the indicating LEDs to wall blue (should be set off later). const in hoofdletters -int intensity_day = 20, intensity_night = 5; // Intensity settings for LED's to wall. +int intensity_day = 80, intensity_night = 50; // Intensity settings for LED's to wall. double intensity = 0.0, control_LED_intensity = 0.0; // Variable between 0 and 1 to set the intensity of the LED's above the buttons. Intensity change to smart name! int colour_code = 0b00; bool pi_active = false; @@ -153,40 +171,7 @@ void serial_read() // Function for serial read for select LED intensity and colour. { - colour_code = (colour_code_1 << 1 | colour_code_0); - if(colour_code != 0b00 && pi_active == false) { - pi_active = true; - } - if(pi_active) { - intensity_select = intensity_code; - switch(colour_code) { - case 0b11 : - LED_colour = 'y'; - break; - case 0b10 : - LED_colour = 'b'; - break; - case 0b01 : - LED_colour = 'g'; - break; - case 0b00 : - LED_colour = 'r'; - break; - default : - LED_colour = 'w'; - break; - } - } - - if (test_mode == 1) { // If statement for test purposal. -// usb_serial.printf("Intensity_select = %d en LED_colour = %d\n", intensity_select, LED_colour); - } - - if (test_mode == 0) { - //usb_serial.printf("Message: %s\n", message); - usb_serial.printf("Intensity_select = %d en LED_colour = %d\n", intensity_select, LED_colour); - - } + LED_colour_wheel_percentage = pi_serial.getc(); } void serial_log() // Function for serial logging. See link to table with code declarations above in code. @@ -378,6 +363,180 @@ } +int minimum(int a,int b) +{ + if(a>b)return b; + else return a; +} + +int colour_fade(int colour_old,int colour_new,int colour_mix) +{ + int old_r=(colour_old&0xff0000)>>16; + int old_g=(colour_old&0x00ff00)>> 8; + int old_b=(colour_old&0x0000ff)>> 0; + int new_r=(colour_new&0xff0000)>>16; + int new_g=(colour_new&0x00ff00)>> 8; + int new_b=(colour_new&0x0000ff)>> 0; + int mix = (100*colour_mix)/FADE_STEPS; + int mix_r=((new_r-old_r)*mix/100)+old_r; + int mix_g=((new_g-old_g)*mix/100)+old_g; + int mix_b=((new_b-old_b)*mix/100)+old_b; + return ((mix_r<<16)|(mix_g<<8)|(mix_b)); + +} + + + +void colour_wheel(int percentage_in) +{ + px.SetAllI(int(intensity*2.55)); + if(percentage_in>100)percentage_in=100; + int ring_colour = colourbuf[2]; + px.SetAll(colourbuf[6]); + int leds_on =(percentage_in*16)/100; + float led_partly = ((percentage_in*16)%100); + if(leds_on==YELLOW_TRANSITION) { + if(mixer>20)mixer=20; + ring_colour = colour_fade(colourbuf[2],colourbuf[3],mixer); + mixer++; + } + if(leds_on>YELLOW_TRANSITION&&leds_on<RED_TRANSITION&&ring_colour_old==colourbuf[3]) { + ring_colour=colourbuf[3]; + mixer=0; + } + if(leds_on==RED_TRANSITION) { + if(mixer>20)mixer=20; + usb_serial.printf("mixer:%d\n",mixer); + ring_colour = colour_fade(colourbuf[3],colourbuf[0],mixer); + mixer++; + } + if(leds_on>RED_TRANSITION&&ring_colour_old==colourbuf[0]) { + ring_colour = colourbuf[0]; + mixer=0; + } + usb_serial.printf("on:%d,part:%f\n",leds_on,led_partly); + for(int j = 0; j<=(leds_on); j++)px.Set(((16-j)%16),ring_colour); + px.SetAllI(int(intensity*2.55)); + if((16-leds_on-1)>0) { + px.Set(((16-leds_on-1)%16),ring_colour); + px.SetI(((16-leds_on-1)%16),int(0.01*led_partly*intensity*2.55)); + } + usb_serial.printf("percentage in %d,%d\n",percentage_in,leds_on); + + if(reposition_button_hold_timer.read_ms()) { + usb_serial.printf("filling circle\n"); + circle_filling_reposition = true; + colour_wheel_filler = reposition_button_hold_timer.read_ms()/250; + if(colour_wheel_filler>=8) { + colour_wheel_filler=8; + circle_filled_reposition = 15; + circle_filling_reposition = false; + colour_wheel_drain_reposition = false; + reposition_flag = 1; + } + px.SetAll(colourbuf[6]); + for(int k =0; k<=colour_wheel_filler; k++) { + px.Set(k,colourbuf[5]); + px.Set(16-k,colourbuf[5]); + } + px.SetAllI(int(intensity*2.55)); + } + + if(new_patient_button_hold_timer.read_ms()) { + usb_serial.printf("filling circle\n"); + circle_filling_new_patient = true; + colour_wheel_filler = new_patient_button_hold_timer.read_ms()/250; + if(colour_wheel_filler>=8) { + colour_wheel_filler=8; + circle_filled_new_patient = 10; + circle_filling_new_patient = false; + colour_wheel_drain_new_patient = false; + new_patient_flag = 1; + } + px.SetAll(colourbuf[6]); + for(int k =0; k<=colour_wheel_filler; k++) { + px.Set((k+8)%16,colourbuf[5]); + px.Set((16-k+8)%16,colourbuf[5]); + } + px.SetAllI(int(intensity*2.55)); + } + + if(!reposition_button_hold_timer.read_ms()&&circle_filling_reposition&&!colour_wheel_drain_reposition) { + usb_serial.printf("Short hold\n"); + px.SetAll(colourbuf[6]); + for(int k =0; k<=colour_wheel_filler; k++) { + px.Set(k,colourbuf[5]); + px.Set(16-k,colourbuf[5]); + } + px.SetAllI(int(intensity*2.55)); + colour_wheel_filler++; + if(colour_wheel_filler>=5) { + colour_wheel_drain_reposition=true; + circle_filling_reposition=false; + } + } + + if(!new_patient_button_hold_timer.read_ms()&&circle_filling_new_patient&&!colour_wheel_drain_new_patient) { + usb_serial.printf("Short hold\n"); + px.SetAll(colourbuf[6]); + for(int k =0; k<=colour_wheel_filler; k++) { + px.Set((k+8)%16,colourbuf[5]); + px.Set((16-k+8)%16,colourbuf[5]); + } + px.SetAllI(int(intensity*2.55)); + colour_wheel_filler++; + if(colour_wheel_filler>=5) { + colour_wheel_drain_new_patient=true; + circle_filling_new_patient=false; + } + } + + if(colour_wheel_drain_reposition) { + usb_serial.printf("drain\n"); + px.SetAll(colourbuf[6]); + for(int k =0; k<=colour_wheel_filler; k++) { + px.Set(k,colourbuf[5]); + px.Set(16-k,colourbuf[5]); + } + px.SetAllI(int(intensity*2.55)); + colour_wheel_filler--; + if(!colour_wheel_filler)colour_wheel_drain_reposition=false; + } + + if(colour_wheel_drain_new_patient) { + usb_serial.printf("drain\n"); + px.SetAll(colourbuf[6]); + for(int k =0; k<=colour_wheel_filler; k++) { + px.Set((k+8)%16,colourbuf[5]); + px.Set((16-k+8)%16,colourbuf[5]); + } + px.SetAllI(int(intensity*2.55)); + colour_wheel_filler--; + if(!colour_wheel_filler)colour_wheel_drain_new_patient=false; + } + + if(circle_filled_reposition) { + usb_serial.printf("circle_filled_repo\n"); + px.SetAll(colourbuf[6]); + for(int k =0; k<=circle_filled_reposition; k++) { + px.Set((16-k)%16,colourbuf[5]); + } + px.Set((16-circle_filled_reposition)%16,colourbuf[4]); + px.SetAllI(int(intensity*2.55)); + circle_filled_reposition--; + } + + if(circle_filled_new_patient) { + usb_serial.printf("circle_filled_new_patient\n"); + px.SetAll(colourbuf[5]); + px.SetAllI(int(intensity*2.55*(7-(circle_filled_new_patient%5))/7)); + circle_filled_new_patient--; + } + + ws.write_offsets(px.getBuf(),0,0,0); + ring_colour_old=ring_colour; +} + void colour_select_indicating_LED_wall(char nLED_colour) // Function to select the colour for LED's to wall (values comes from algorithm). { set_intensity_LEDs(); // Call function set_intensity_LEDs to set the intensity for LED's to wall and above buttons. @@ -455,9 +614,11 @@ LED_on_dev_board1 = !LED_on_dev_board1; } - if (lock_state == 1) reposition_lock_flag = 1; + if (lock_state == 1||button_new_patient.read()==0) reposition_lock_flag = 1; else { - reposition_flag = 1; + reposition_button_hold_timer.reset(); + reposition_button_hold_timer.start(); + reposition_feedback_LED = control_LED_intensity; pi_serial.printf("&05\n"); if(test_mode == 1) usb_serial.printf("&05\n"); @@ -475,7 +636,8 @@ if(test_mode == 1) usb_serial.printf("&50\n"); } - + reposition_button_hold_timer.stop(); + reposition_button_hold_timer.reset(); reposition_feedback_LED = 0; } //TODO rename to calibration @@ -552,11 +714,14 @@ delay_between_button_pressed.reset(); delay_between_button_pressed.start(); - if (lock_state == 1) new_patient_lock_flag = 1; + if (lock_state == 1||button_reposition.read()==0) new_patient_lock_flag = 1; else { + new_patient_button_hold_timer.reset(); + new_patient_button_hold_timer.start(); + new_patient_feedback_LED = control_LED_intensity; pi_serial.printf("&06\n"); - new_patient_flag = 1; + //new_patient_flag = 1; if(test_mode == 1) { usb_serial.printf("&06\n"); @@ -575,6 +740,9 @@ usb_serial.printf("New patient released.\n"); } + new_patient_button_hold_timer.stop(); + new_patient_button_hold_timer.reset(); + if (new_patient_feedback_LED != 0) { pi_serial.printf("&60\n"); @@ -610,6 +778,12 @@ button_calibration_hold_timer.reset(); } + if (button_reposition == 1) { + reposition_button_hold_timer.stop(); + reposition_button_hold_timer.reset(); + } + + if ((button_calibration_hold_timer.read_ms() > calibrationtime_ms) && calibration_flag == 0 && button_mute == 0 && lock_state == 0) { // If statement for calibration algorithm. calibration_flag = 1; calibration_flash = 11; @@ -620,19 +794,19 @@ pi_serial.printf(">33\n"); } - - if (delay_between_button_pressed.read_ms() > delay_lock_interface) { // If buttons are not pressed for 3 minutes, set lock active. - lock_state = 1; - LED_on_dev_board2 = 1; - lock_feedback_LED = 0; - if (!auto_lock_led_logged) { - pi_serial.printf("&80\n"); - if(test_mode == 1) usb_serial.printf("&80\n"); - auto_lock_led_logged = 1; - } - } else { - auto_lock_led_logged = 0; - } + /* + if (delay_between_button_pressed.read_ms() > delay_lock_interface) { // If buttons are not pressed for 3 minutes, set lock active. + lock_state = 1; + LED_on_dev_board2 = 1; + lock_feedback_LED = 0; + if (!auto_lock_led_logged) { + pi_serial.printf("&80\n"); + if(test_mode == 1) usb_serial.printf("&80\n"); + auto_lock_led_logged = 1; + } + } else { + auto_lock_led_logged = 0; + }*/ } void set_userinterface_LED() // Control functions for LED above buttons (added because of failures). @@ -677,10 +851,12 @@ int main() // Main function. inline function "Momo Init" bijvoorbeeld { - serial_read(); - ws.useII(WS2812::GLOBAL); // use global intensity scaling + pi_serial.attach(serial_read,Serial::RxIrq); + ws.useII(WS2812::PER_PIXEL); + ws.setII(255); + px.SetAll(colourbuf[4]); // use global intensity scaling set_intensity_LEDs(); // Initialize intensity for user interface LED's and LED's shines to wall. - colour_select_indicating_LED_wall(LED_colour); + ws.write_offsets(px.getBuf(),0,0,0); speaker1 = 1; wait_ms(boot_delay_ms); // Wait to boot sensorplate first. @@ -711,38 +887,50 @@ __disable_irq(); while(!pi_active) { - Knight_Rider_Timer.reset(); - Knight_Rider_Timer.start(); - reposition_feedback_LED = control_LED_intensity; - new_patient_feedback_LED = 0; - while(Knight_Rider_Timer.read_ms()<(1*(total_knight_rider_cycle_time_ms/8))) {} - new_patient_feedback_LED = control_LED_intensity; - while(Knight_Rider_Timer.read_ms()<(2*(total_knight_rider_cycle_time_ms/8))) {} - mute_feedback_LED = control_LED_intensity; - reposition_feedback_LED = 0; - while(Knight_Rider_Timer.read_ms()<(3*(total_knight_rider_cycle_time_ms/8))) {} - lock_feedback_LED = control_LED_intensity; - new_patient_feedback_LED = 0; - while(Knight_Rider_Timer.read_ms()<(4*(total_knight_rider_cycle_time_ms/8))) {} - mute_feedback_LED = 0; - while(Knight_Rider_Timer.read_ms()<(5*(total_knight_rider_cycle_time_ms/8))) {} - mute_feedback_LED = control_LED_intensity; - while(Knight_Rider_Timer.read_ms()<(6*(total_knight_rider_cycle_time_ms/8))) {} - new_patient_feedback_LED = control_LED_intensity; - lock_feedback_LED = 0; - while(Knight_Rider_Timer.read_ms()<(7*(total_knight_rider_cycle_time_ms/8))) {} - reposition_feedback_LED = control_LED_intensity; - mute_feedback_LED = 0; + comet_timer.reset(); + comet_timer.start(); + ws.useII(WS2812::PER_PIXEL); + ws.setII(255); + tail_step = (255-COMET_TAIL_END_INTENSITY)/TAIL_LENGTH; + comet++; + px.SetAll(colourbuf[6]); + px.Set(comet%ALARMBUF,colourbuf[4]); + px.SetI(comet%ALARMBUF,255); + for(int i=1; i<=TAIL_LENGTH; i++) { + tail=(comet-i); + if(tail<0)tail=0; + px.Set(tail%ALARMBUF,colourbuf[4]); + px.SetI(tail%ALARMBUF,(255-(tail_step*i))); + } + colour_code = (colour_code_1 << 1 | colour_code_0); + if(colour_code != 0b00 && pi_active == false && (comet%ALARMBUF)==(ALARMBUF-1)) { + pi_active = true; + } + ws.write_offsets(px.getBuf(),0,0,0); + while(comet_timer.read_ms()<total_comet_cycle_time_ms) {} + } + for(int i=ALARMBUF-1; i>=0; i--) { + comet_timer.reset(); + comet_timer.start(); + for(int j=1; j<=TAIL_LENGTH; j++) { + tail=(i-j); + if(tail>=0) { + px.Set(tail,colourbuf[4]); + px.SetI(tail,(int(255-(tail_step*j)))); + } + } + px.Set(i,colourbuf[4]); + px.SetI(i,255); + while(comet_timer.read_ms()<total_comet_cycle_time_ms) {} + ws.write_offsets(px.getBuf(),0,0,0); + } - serial_read(); - colour_select_indicating_LED_wall(LED_colour); - while(Knight_Rider_Timer.read_ms()<(8*(total_knight_rider_cycle_time_ms/8))) {} - - } __enable_irq(); + wait(1); delay_between_button_pressed.reset(); // Delaytimer reset en start. delay_between_button_pressed.start(); +// ws.useII(WS2812::GLOBAL); reposition_feedback_LED = 0; new_patient_feedback_LED = 0; mute_feedback_LED = 0; @@ -826,7 +1014,7 @@ // usb_serial.printf("Loop time after timer_functions: %d ms\n",piezo_electric_sample_timer.read_ms()); } - colour_select_indicating_LED_wall(LED_colour); // Function to select colour. + colour_wheel(LED_colour_wheel_percentage); // Function to select colour. set_userinterface_LED(); // Set LED's of user interface (LED's above buttons). if (test_mode == 1) { // If statement for test purposal. @@ -846,7 +1034,7 @@ if (test_mode == 0) { // If statements for test purposal (untill * mark). // usb_serial.printf("Loop time pre serial: %d ms\n",piezo_electric_sample_timer.read_ms()); } - serial_read(); // Call function for reading information from PI by serial connection. + //serial_read(); // Call function for reading information from PI by serial connection. serial_log(); // Call function for logging information to PI by serial connection. if (test_mode == 0) { // If statements for test purposal (untill * mark).