ss
Dependencies: WS2812 PixelArray Adafruit_GFX
Diff: main.cpp
- Revision:
- 0:27e31cadeb36
- Child:
- 2:a3f7435f9475
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sat Jun 15 13:09:31 2019 +0000 @@ -0,0 +1,606 @@ +#include "mbed.h" +#include "IRreflection.h" +#include "ReceiverIR.h" +#include "PCF8574.h" +#include "hcsr04.h" +#include "Adafruit_SSD1306.h" +#include "WS2812.h" +#include "PixelArray.h" + +#define WS2812_BUF 77 //number of LEDs in the array +#define NUM_COLORS 6 //number of colors to store in the array +#define NUM_STEPS 8 //number of steps between colors + +Timer total; +Timer Etime; +Timer Otime; +Timer AngleTimer; + +//WS2812 neopixel================ +PixelArray px(WS2812_BUF); +WS2812 ws(D7, WS2812_BUF, 6,17,9,14); //nucleo-f411re +Thread neothread; + +// temperary========================= +RawSerial pc(USBTX, USBRX, 115200); +//ultrasonic sensor===================== +int limit = 5; +HCSR04 sensor(D3, D2,pc,0,limit); +int turn = 0; +int Ultra_distance = 0; + +//PCF8574============================ +PCF8574 io(I2C_SDA,I2C_SCL,0x40); +//IR_Reflection : declaration======== +TRSensors TR(D11,D12,D13,D10); + +static int sensor_for_end[NUMSENSORS]; +static int sensor_val[NUMSENSORS]; +static int calMin[NUMSENSORS]; +static int calMax[NUMSENSORS]; +//================================== +//==============Motor=============== +PwmOut PWMA(D6); //PB_10,D6 +PwmOut PWMB(D5); + +DigitalOut AIN1(A1); +DigitalOut AIN2(A0); +DigitalOut BIN1(A2); +DigitalOut BIN2(A3); + +#define MIDDLE 2000 +int R_PWM; +int L_PWM; +int weight; int P_weight; +int P_temp; int Fix_temp; +int print_c; +int den; +static int on_line[1]; +typedef enum{LEFT = 0, RIGHT} DIRE; +DIRE direction; +DIRE Over_direction; +DIRE P_direction; +DIRE Obs_direction; +//================================== +//IR_Remote : declaration=========== +ReceiverIR ir_rx(D4); + +RemoteIR::Format format; +uint8_t IR_buf[32]; +uint32_t IR_buf_sum; +int bitcount; +//==========flag=================== + +typedef enum{NOK = 0, YOK}flag; +// Nessary change to enum!!! +flag flag_cal_Min; +flag flag_cal_Max; +flag flag_start; +flag flag_over; +flag flag_out; +flag flag_IR; +flag flag_end; +flag flag_angle; +flag flag_obstacle; +flag flag_distance; +flag flag_neo; +//============================== +void Initialization(void); +void Motor_init(void); +void Motor_Stop(void); +void Calibration(void); +void Driving(void); +void Actuator(void); +void Distance_check(void); +void Obstacle_check(void); +void Actuator_Obstacle(int dir); +int End_check(int *sensor_values); +int color_set(uint8_t red,uint8_t green, uint8_t blue); +int interpolate(int startValue, int endValue, int stepNumber, int lastStepNumber); +void NeopixelOn(void); + +//===========================OLED +class I2CPreInit : public I2C +{ +public: + I2CPreInit(PinName sda, PinName scl) : I2C(sda, scl) + { + frequency(400000); + start(); + }; +}; + +I2C i2c(D14, D15); +Adafruit_SSD1306_I2c oled(i2c, D9, 0x78, 64, 128); + +int main(){ + neothread.start(&NeopixelOn); + oled.clearDisplay(); + oled.printf("Welcome to Alphabot\r\n\r\n"); + oled.display(); + + Initialization(); + + Driving(); + + if(flag_end){ + oled.clearDisplay(); + int duration = total.read(); + oled.printf("Congratulation!! \r\n"); + oled.printf("Time is %.3f", total.read()); + oled.display(); + flag_neo = YOK; + } + + +} +//==================================================== +//==================initialization==================== +//==================================================== +void Initialization(){ + + //추후 다른 변수 초기화 전부 이곳에!!! + + flag_over = NOK; + flag_IR = NOK; + flag_distance = NOK; + + TR.calibrate_init(calMin,calMax); + + Motor_init(); + + Calibration(); + +} + +void Motor_Stop(){ + pc.printf("===============================Motor Stop!\r\n"); + AIN1 = 0; + AIN2 = 0; + BIN1 = 0; + BIN2 = 0; + PWMB.pulsewidth_us(0); + PWMA.pulsewidth_us(0); +} + +void Motor_init(){ + AIN1 = 0; + AIN2 = 1; + BIN1 = 0; + BIN2 = 1; + PWMB.period_us(500); + PWMA.period_us(500); + + den = 0; + R_PWM = 0; + L_PWM = 0; + weight= 0; + print_c = 0; + + +} +void Calibration(){ + + while(flag_cal_Max == NOK){ + + if ((ir_rx.getState() == ReceiverIR::Received)&&(ir_rx.getData(&format, IR_buf, sizeof(IR_buf) * 8)!=0)) { + for(int i =0 ; i<4; i ++){ + IR_buf_sum |=(IR_buf[i]<<8*(3-i)); + } + pc.printf("%X\r\n",IR_buf_sum); + if(IR_buf_sum == 0x00FF0CF3){ + io.write(0x7F); + TR.calibrate(sensor_val, calMin, calMax); + wait(0.5); + io.write(0xFF); + for(int i = 0; i<5; i++){ + pc.printf("Min_sensor_value[%d] = %d\r\n",i+1,calMin[i]); + pc.printf("Max_sensor_value[%d] = %d\r\n",i+1,calMax[i]); + } + pc.printf("================================\r\n"); + + flag_cal_Max = YOK; + } + IR_buf_sum = 0; + } + } + + while(flag_cal_Min == NOK){ + + if ((ir_rx.getState() == ReceiverIR::Received)&&(ir_rx.getData(&format, IR_buf, sizeof(IR_buf) * 8)!=0)) { + for(int i =0 ; i<4; i ++){ + IR_buf_sum |=(IR_buf[i]<<8*(3-i)); + } + pc.printf("%X\r\n",IR_buf_sum); + if(IR_buf_sum == 0x00FF18E7){ + io.write(0xBF); + TR.calibrate(sensor_val, calMin, calMax); + wait(0.5); + io.write(0xFF); +for(int i = 0; i<5; i++){ +pc.printf("Min_sensor_value[%d] = %d\r\n",i+1,calMin[i]); +pc.printf("Max_sensor_value[%d] = %d\r\n",i+1,calMax[i]); +} +pc.printf("================================\r\n"); + flag_cal_Min = YOK; + } + IR_buf_sum = 0; + } + } + + + +//=================start=============================== + while(flag_start == NOK){ + + if ((ir_rx.getState() == ReceiverIR::Received)&&(ir_rx.getData(&format, IR_buf, sizeof(IR_buf) * 8)!=0)) { + for(int i =0 ; i<4; i ++){ + IR_buf_sum |=(IR_buf[i]<<8*(3-i)); + } + + pc.printf("%X\r\n",IR_buf_sum); + if(IR_buf_sum == 0x00FF5EA1){ + pc.printf("===============start!===============\r\n"); + flag_start = YOK; + } + IR_buf_sum = 0; + } + } +//================================================================ +} + + + + + + + + +//Using logic control================================================================= +void Driving(){ + + + total.start(); + + Etime.start(); + while(!flag_end){ + Etime.reset(); + + + // Obstacle_check(); + + if(flag_distance == NOK){ + Actuator(); + } + + + Distance_check(); + + + do{ + }while(Etime.read()<0.00300001); + } + +} + + +int End_check(int *sensor_values){ + int avg = 0; + int sum = 0; + + for(int i = 0; i < NUMSENSORS; i++){ + sum += sensor_values[i]; + } + avg = sum / NUMSENSORS; + //pc.printf("\tavg function: %d\r\n",avg); + return avg; +} + + + +void Actuator(){ + + den = 30; + + //int temp = TR.readLine(sensor_val, calMin, calMax,on_line,1) - MIDDLE; + int temp = TR.readLine(sensor_val, calMin, calMax,on_line,1); + //pc.printf("new temp: %d\r\n",temp); + + TR.readCalibrated(sensor_for_end, calMin, calMax); + int avg = End_check(sensor_for_end); + + if(avg <= 100){ + pc.printf("avg:%d\r\n",avg); + Motor_Stop(); + flag_end = YOK; + total.stop(); + } + + temp = temp - MIDDLE; + + if(temp>=0) direction = LEFT; + else direction = RIGHT; + + + weight = abs(temp)/den; + + if((print_c%500) == 0){ + pc.printf("flag_out = %d\r\n", flag_out); + pc.printf("temp = %d\r\n", temp); + pc.printf("online = %d\r\n", on_line[0]); + } + + R_PWM = 140; + L_PWM = 140; + + + + //if(weight > (2000/den)*2/3) weight = (2000/den)*3/4; + + if(weight >= (2000/den)*3/4){ + if(direction == LEFT){ + PWMA.pulsewidth_us(L_PWM+0.0*weight); + PWMB.pulsewidth_us(R_PWM-2.1*weight); + } + else{ + PWMA.pulsewidth_us(L_PWM-2.1*weight); + PWMB.pulsewidth_us(R_PWM+0.0*weight); + } + }else{ + + if(direction == LEFT){ + PWMA.pulsewidth_us(L_PWM+0.0*weight); + PWMB.pulsewidth_us(R_PWM-1.4*weight); + } + else{ + PWMA.pulsewidth_us(L_PWM-1.4*weight); + PWMB.pulsewidth_us(R_PWM+0.0*weight); + } + } + + + if(weight >= (2000/den)*2/3 && flag_over == NOK) + { + flag_over = YOK; + P_direction = direction; + P_weight = weight; + } + + if((flag_over == YOK) && (abs(weight)<= (2000/den)*1/5)&&on_line[0]==1) + { + if(P_weight >=(2000/den)*2/3 && P_weight<=(2000/den)*4/5){ + if(P_direction == LEFT){ + PWMA.pulsewidth_us(L_PWM-P_weight); + PWMB.pulsewidth_us(R_PWM); + } + else{ + PWMA.pulsewidth_us(L_PWM); + PWMB.pulsewidth_us(R_PWM-P_weight); + } + } + if(P_weight>=(2000/den)*4/5){ + if(P_direction == LEFT){ + PWMA.pulsewidth_us(L_PWM-1.0*P_weight); + PWMB.pulsewidth_us(R_PWM+1.0*P_weight); + } + else{ + PWMA.pulsewidth_us(L_PWM+1.0*P_weight); + PWMB.pulsewidth_us(R_PWM-1.0*P_weight); + } + } + // pc.printf("I'm Here\r\n"); + + wait(0.12); + flag_over = NOK; + } + + P_temp = temp; + print_c++; +} + + +void Distance_check(){ + + if(flag_distance == NOK){ + sensor.distance(); + Ultra_distance = sensor.returndistance(); + //pc.printf("distance = %d\r\n",flag_distance); + if((Ultra_distance >= 16 && Ultra_distance <= 19)) flag_distance = YOK; + } + + if(flag_distance == YOK){ + while(1){ + // pc.printf("distance check. turn left!!\r\n"); + PWMB.pulsewidth_us(100); + PWMA.pulsewidth_us(100); + AIN1.write(1); + AIN2.write(0); + BIN1.write(0); + BIN2.write(1); + //pc.printf("ABS == ") + if((abs(TR.readLine(sensor_val, calMin, calMax,on_line,1) - MIDDLE)<=400 && on_line[0] == 1)){ + Motor_init(); + flag_distance = NOK; + PWMB.pulsewidth_us(0); + PWMA.pulsewidth_us(0); + break; + } + } + } +} + +void Obstacle_check(){ + + //io.write 체크 + //flag_IR 변경 YOK + // pc.printf("flag_out = %x\r\n", io.read()); + if(io.read() == 0x7F){ //왼쪽읽음 + flag_IR = YOK; + flag_obstacle = YOK; + Obs_direction = LEFT; + } + else if(io.read() == 0xbF) //오른쪽 읽음 + { + flag_IR = YOK; + flag_obstacle = YOK; + Obs_direction = RIGHT; + } + + if(flag_IR){ + Otime.start(); + //flag_IR = NOK; + // pc.printf("\tActuator Obstacel start\r\n"); + + while(flag_obstacle == YOK){ + //while(io.read() != 0xFF){ + + Actuator_Obstacle(Obs_direction); + pc.printf("obstacle!\r\n"); + //pc.printf("\t\tActuator Obstacel start\r\n"); + + } + Otime.stop(); + Otime.reset(); + flag_IR = NOK; + } + + + + +} + +void Actuator_Obstacle(int dir){ + + R_PWM = 100; + L_PWM = 100; + +if(Otime.read() <= 0.5){ + + if(dir == 0){ + PWMA.pulsewidth_us(L_PWM-20); + PWMB.pulsewidth_us(R_PWM-100); + } + else if(dir == 1 ){ + PWMA.pulsewidth_us(L_PWM-100); + PWMB.pulsewidth_us(R_PWM-40); + } + +}else if(Otime.read() <= 1.0){ + + if(dir == 0){ + PWMA.pulsewidth_us(L_PWM+5); + PWMB.pulsewidth_us(R_PWM); + } + else if(dir == 1 ){ + PWMA.pulsewidth_us(L_PWM+5); + PWMB.pulsewidth_us(R_PWM); + } + +}else if(Otime.read() <= 2.0){ + + if(dir == 0){ + PWMA.pulsewidth_us(L_PWM-100); + PWMB.pulsewidth_us(R_PWM-40); + } + else if(dir == 1 ){ + PWMA.pulsewidth_us(L_PWM-20); + PWMB.pulsewidth_us(R_PWM-100); + } + +}else{ + + if((abs(TR.readLine(sensor_val, calMin, calMax,on_line,1) - MIDDLE)<=400 && on_line[0] == 1)) flag_obstacle = NOK; + + PWMA.pulsewidth_us(L_PWM); + PWMB.pulsewidth_us(R_PWM); + + } + +} + + +int color_set(uint8_t red,uint8_t green, uint8_t blue) +{ + return ((red<<16) + (green<<8) + blue); +} + +// 0 <= stepNumber <= lastStepNumber +int interpolate(int startValue, int endValue, int stepNumber, int lastStepNumber) +{ + return (endValue - startValue) * stepNumber / lastStepNumber + startValue; +} + +void NeopixelOn(){ + int colorIdx = 0; + int colorTo = 0; + int colorFrom = 0; + + uint8_t ir = 0; + uint8_t ig = 0; + uint8_t ib = 0; + + ws.useII(WS2812::PER_PIXEL); // use per-pixel intensity scaling + + // set up the colours we want to draw with + int colorbuf[NUM_COLORS] = {0x2f0000,0x2f2f00,0x002f00,0x002f2f,0x00002f,0x2f002f}; + + // Now the buffer is written, write it to the led array. + while (flag_neo) + { + //get starting RGB components for interpolation + std::size_t c1 = colorbuf[colorFrom]; + std::size_t r1 = (c1 & 0xff0000) >> 16; + std::size_t g1 = (c1 & 0x00ff00) >> 8; + std::size_t b1 = (c1 & 0x0000ff); + + //get ending RGB components for interpolation + std::size_t c2 = colorbuf[colorTo]; + std::size_t r2 = (c2 & 0xff0000) >> 16; + std::size_t g2 = (c2 & 0x00ff00) >> 8; + std::size_t b2 = (c2 & 0x0000ff); + + for (int i = 0; i <= NUM_STEPS; i++) + { + ir = interpolate(r1, r2, i, NUM_STEPS); + ig = interpolate(g1, g2, i, NUM_STEPS); + ib = interpolate(b1, b2, i, NUM_STEPS); + + //write the color value for each pixel + px.SetAll(color_set(ir,ig,ib)); + + //write the II value for each pixel + px.SetAllI(32); + + for (int i = WS2812_BUF; i >= 0; i--) + { + ws.write(px.getBuf()); + } + } + + colorFrom = colorIdx; + colorIdx++; + + if (colorIdx >= NUM_COLORS) + { + colorIdx = 0; + } + + colorTo = colorIdx; + } +} + + +/* +else if(Otime.read() <= 2.0){ + + if(dir == 0){ + PWMA.pulsewidth_us(L_PWM+5); + PWMB.pulsewidth_us(R_PWM); + } + else if(dir == 1 ){ + PWMA.pulsewidth_us(L_PWM+5); + PWMB.pulsewidth_us(R_PWM); + } + +} +*/ \ No newline at end of file