Advertisement
Guest User

Untitled

a guest
Nov 15th, 2019
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.20 KB | None | 0 0
  1. /*
  2. * bkoSegway.c
  3. *
  4. * Created: 20/09/2019 10:21:46
  5. * Author : goldi
  6. */
  7.  
  8. /* Lesezeichen
  9. *
  10. * INT VEC - S.44
  11. *
  12. * ADC MUX - S.214
  13. *
  14. * PIN Definitionen
  15. *
  16. * A-Register
  17. *
  18. * PA0 - UBATT Abfragen der Betteriespannung
  19. *
  20. * PA1 - MASSE
  21. *
  22. * PA2 - ADXL-Y Achsial-Beschleunigung Y-Achse
  23. *
  24. * PA3 - ADXL-X Achsial-Beschleunigung X-Achse
  25. *
  26. * PA4 - GYRO-X Neigung X-Achse
  27. *
  28. * PA5 - GYRO-Y Neigung Y-Achse
  29. *
  30. * PA6 - POT Lenkungs Poti
  31. *
  32. * PA7 - FOOTDETECT Prüft ob Nutzer auf dem Segway steht
  33. *
  34. * B-Register
  35. *
  36. * PB0 - N/A
  37. *
  38. * PB1 - N/A
  39. *
  40. * PB2 - LED3 Rot
  41. *
  42. * PB3 - LED2 Gelb
  43. *
  44. * PB4 - LED1 Grün
  45. *
  46. * PB5 - MOSI SPI
  47. *
  48. * PB6 - MISO SPI
  49. *
  50. * PB7 - SCK SPI
  51. *
  52. * C-Register
  53. *
  54. * PC0 - N/A
  55. *
  56. * PC1 - N/A
  57. *
  58. * PC2 - N/A
  59. *
  60. * PC3 - N/A
  61. *
  62. * PC4 - N/A
  63. *
  64. * PC5 - N/A
  65. *
  66. * PC6 - N/A
  67. *
  68. * PC7 - N/A
  69. *
  70. * D-Register
  71. *
  72. * PD0 - N/A
  73. *
  74. * PD1 - N/A
  75. *
  76. * PD2 - CURFLAG OVERCURRENT FLAG - SOFORT AUSSCHALTEN
  77. *
  78. * PD3 - N/A
  79. *
  80. * PD4 - PWM-L
  81. *
  82. * PD5 - PWM-R
  83. *
  84. * PD6 - CW/CCW-A Clock/Counterclockwise Rotation Selector A
  85. *
  86. * PD7 - CW/CCW-B Clock/Counterclockwise Rotation Selector B
  87. *
  88. * Sonstige
  89. *
  90. * !RES - Reset Pin
  91. *
  92. * AREF - AREF Analoge Referenzspannung
  93. *
  94. * GND - Ground An Masse
  95. *
  96. * VCC - Spannung 5V
  97. *
  98. * AVCC - Spannung 5V Analog Parallelversorgung
  99. */
  100.  
  101. //
  102. // PRE REQ
  103. //
  104. #ifndef F_CPU
  105. #define F_CPU 16000000UL
  106. #endif
  107.  
  108. // Konstanten
  109. // REG A
  110. #define UBATT DDA0
  111. #define ADXL_Y DDA2
  112. #define ADXL_X DDA3
  113. #define GYRO_X DDA4
  114. #define GYRO_Y DDA5
  115. #define POT DDA6
  116. #define FOOTDETECT DDA7
  117. // REG B
  118. #define LED_3 DDB4
  119. #define LED_2 DDB3
  120. #define LED_1 DDB2
  121. // REG D
  122. #define CURRFLAG DDD2
  123. #define PWM_L DDD4
  124. #define PWM_R DDD5
  125. #define CW_CCW_A DDD6
  126. #define CW_CCW_B DDD7
  127. // OTHER
  128. #define PWM_AL OCR1AL
  129. #define PWM_BL OCR1BL
  130. #define CW_CCW_A DDD6
  131. #define CW_CCW_B DDD7
  132.  
  133.  
  134. //
  135. // GLOBAL VAR
  136. //
  137. volatile char buzzer = 0;
  138. volatile long adcSelect = 0;
  139. volatile long adcADXL = 0;
  140. volatile long adcGYRO = 0;
  141. volatile int adcBattery = 0;
  142. volatile int adcSwitch = 0;
  143. volatile int adcPOT = 0;
  144. volatile int adcRocker = 0;
  145. volatile long total_ADXL_GYRO = 0;
  146. volatile long avg_GYRO = 0;
  147. volatile long avg_ADXL = 0;
  148. volatile long avg_BATT = 0;
  149. volatile int driveA = 0;
  150. volatile int driveB = 0;
  151. volatile int RAW_driveA = 0;
  152. volatile int RAW_driveB = 0;
  153. volatile long driveSum = 0;
  154. volatile long buff0 = 0;
  155. volatile long buff1 = 0;
  156. volatile long buff2 = 0;
  157. volatile long buff3 = 0;
  158. volatile long angle = 0;
  159. volatile int Tcount = 0;
  160. volatile long speed = 0;
  161. volatile long steer = 0;
  162. volatile long correction = 0;
  163. volatile long angle_rate = 0;
  164. volatile long balance = 0;
  165. volatile char mode = 0;
  166. volatile char bCount = 0;
  167. volatile long timeout = 0;
  168. volatile char delta = 0;
  169. volatile long rockerSQ = 0;
  170. volatile int zero_Rocker = 0;
  171. volatile int zero_ADXL = 0;
  172. volatile int zero_GYRO = 0;
  173. volatile int Lcount = 0;
  174. volatile int currLimit = 100;
  175. volatile char errNr = 0;
  176. volatile int off_ADXL = 0;
  177.  
  178. #define ADC_INPUT_FIRST 0
  179. #define ADC_INPUT_LAST 6
  180. #define ADC_VREF_TYPE 0x40
  181. #define DRIVE_LIMIT 20000
  182. #define TOTAL_LOOP 500
  183. #define TOTAL_LOOP_10 50
  184. #define _standby 0
  185. #define _run 1
  186. #define _warmup 2
  187. #define _down 3
  188. #define SAFE_SPEED 5000
  189. #define SAFE_SPEED_N -5000
  190. #define SW_DOWN 50
  191. #define CRITICAL 80
  192. #define MAX_PWM 180
  193. #define MAX_PWM_N -180
  194. #define BATT_DEAD 487000
  195. #define BATT_OK 505000
  196.  
  197.  
  198. //
  199. // PREDEF
  200. //
  201. void get_speedLimit();
  202. long get_ADC(int adcSel);
  203. void algo();
  204. void process();
  205. void set_pwm();
  206. void get_tiltAngle();
  207.  
  208.  
  209. //
  210. // LIB
  211. //
  212. #include <avr/io.h>
  213. #include <avr/interrupt.h>
  214. #include <util/delay.h>
  215.  
  216. //
  217. // ISR
  218. //
  219. ISR(ADC_vect){
  220. cli();
  221. adcSelect = ADC;
  222. sei();
  223. }
  224.  
  225. ISR(TIMER0_OVF_vect){
  226. cli();
  227. get_tiltAngle();
  228. get_speedLimit();
  229. algo();
  230. process();
  231. set_pwm();
  232. TCNT0 = 100;
  233. sei();
  234. }
  235.  
  236. //
  237. // FUNC
  238. //
  239. void get_tiltAngle(){
  240. adcGYRO = get_ADC(5);
  241. adcGYRO = 1024 - adcGYRO;
  242.  
  243. adcADXL = get_ADC(3);
  244. adcBattery = get_ADC(0);
  245. adcRocker = get_ADC(6);
  246. adcSwitch = get_ADC(7);
  247.  
  248. buff0 = total_ADXL_GYRO / TOTAL_LOOP;
  249. total_ADXL_GYRO = total_ADXL_GYRO - buff0;
  250.  
  251. buff0 = adcADXL - zero_ADXL;
  252. buff0 = buff0 + off_ADXL;
  253.  
  254. total_ADXL_GYRO = total_ADXL_GYRO + buff0;
  255.  
  256. buff1 = avg_GYRO / TOTAL_LOOP;
  257. avg_GYRO = avg_GYRO - buff1;
  258.  
  259. avg_GYRO = avg_GYRO + adcGYRO;
  260. buff1 = avg_GYRO / TOTAL_LOOP_10;
  261.  
  262. buff0 = adcGYRO * 10;
  263. buff1 = buff1 - buff0;
  264. buff1 = buff1 * 35;
  265. buff1 = buff1 / 100;
  266. angle_rate = buff1;
  267.  
  268. total_ADXL_GYRO = total_ADXL_GYRO + angle_rate;
  269. angle = total_ADXL_GYRO / TOTAL_LOOP_10;
  270.  
  271. buff1 = avg_BATT / TOTAL_LOOP;
  272. avg_BATT = avg_BATT - buff1;
  273. avg_BATT = avg_BATT + adcBattery;
  274.  
  275. Lcount++;
  276. }
  277.  
  278. void get_speedLimit(){
  279. buff1 = 0;
  280. if(driveSum > 0){
  281. buff1 = driveSum - DRIVE_LIMIT;
  282. }
  283.  
  284. buff1 = buff1 / 70;
  285. off_ADXL = 0;
  286.  
  287. if(buff1 > 13){
  288. buff1 = 13;
  289. }
  290. if(buff1 < 0){
  291. buff1 = 0;
  292. }
  293.  
  294. if(buff1 > 0){
  295. off_ADXL = buff1;
  296. buzzer = 2;
  297. }
  298.  
  299. if(buzzer == 0){
  300. if(avg_BATT > BATT_OK){
  301. PORTB |= (1 << LED_1);
  302. PORTB &= ~((1 << LED_2) | (1 << LED_3));
  303. }
  304. if(avg_BATT < BATT_OK){
  305. PORTB |= (1 << LED_2);
  306. PORTB &= ~((1 << LED_1) | (1 << LED_3));
  307. }
  308. if(avg_BATT < BATT_DEAD){
  309. PORTB |= (1 << LED_3);
  310. PORTB &= ~((1 << LED_1) | (1 << LED_2));
  311. }
  312. }
  313. }
  314.  
  315. long get_ADC(int adcSel){
  316. ADMUX &= ~0x1F;
  317. switch(adcSel){
  318. case(0): //Battery
  319. break;
  320. case(5): //GYRO
  321. ADMUX |= ((1 << MUX2) | (1 << MUX0));
  322. break;
  323. case(3): //ADXL
  324. ADMUX |= ((1 << MUX1) | (1 << MUX0));
  325. break;
  326. case(6): //Rocker
  327. ADMUX |= ((1 << MUX2) | (1 << MUX1));
  328. break;
  329. case(7): //Switch
  330. ADMUX |= ((1 << MUX2) | (1 << MUX1) | (1 << MUX0));
  331. break;
  332. }
  333. ADCSRA |= (1 << ADSC);
  334. _delay_us(30);
  335. return adcSelect;
  336. }
  337.  
  338. void algo(){
  339. buff0 = angle;
  340. buff0 = buff0 * 17;
  341. buff1 = angle_rate * 17;
  342.  
  343. balance = buff1 + buff0;
  344.  
  345. driveSum = driveSum + balance;
  346.  
  347. if(driveSum > 55000){
  348. driveSum = 55000;
  349. }
  350. if(driveSum < -55000){
  351. driveSum = -55000;
  352. }
  353.  
  354. buff0 = driveSum / 155;
  355. buff1 = balance / 165;
  356. speed = buff0 + buff1;
  357. }
  358.  
  359. void process(){
  360. Tcount++;
  361. if(Tcount > 10){
  362. if(buzzer == 1){
  363. PORTB |= ((1 << LED_1) | (1 << LED_2) | (1 << LED_3));
  364. }
  365. if(buzzer == 2){
  366. PORTB |= (1 << LED_3);
  367. }
  368. }
  369.  
  370. if(Tcount > 16){
  371. if(buzzer > 0){
  372. PORTB &= ~((1 << LED_1) | (1 << LED_2) | (1 << LED_3));
  373. bCount++;
  374. }
  375.  
  376. Tcount = 1;
  377.  
  378. if(bCount > 10){
  379. bCount = 0;
  380. buzzer = 0;
  381. }
  382. }
  383.  
  384. rockerSQ = zero_Rocker - adcRocker;
  385.  
  386. buff1 = driveSum / 20000;
  387. if(buff1 < 0){
  388. buff1 = buff1 * -1;
  389. }
  390.  
  391. if(buff1 < 1){buff1 = 1;}
  392.  
  393. rockerSQ = rockerSQ / buff1;
  394.  
  395. buff1 = driveSum / 2000;
  396. if(buff1 < 0){
  397. buff1 = buff1 * -1;
  398. }
  399.  
  400. if(buff2 > 22){
  401. buff1 = 22;
  402. }
  403.  
  404. buff1 = 27 - buff1;
  405. buff2 = buff1 * -1;
  406.  
  407. if(rockerSQ > buff1){
  408. rockerSQ = buff1;
  409. }
  410. if(rockerSQ < buff2){
  411. rockerSQ = buff2;
  412. }
  413.  
  414. steer = rockerSQ;
  415.  
  416. if((PIND & (1 << PD2)) == 0){
  417. currLimit = 125;
  418. }
  419. if((PIND & (1 << PD2)) == 1){
  420. if(currLimit < 30000){
  421. currLimit = currLimit + 1;
  422. }
  423. buzzer = 1;
  424. }
  425.  
  426. speed = speed * 125;
  427. speed = speed / currLimit;
  428.  
  429. RAW_driveA = speed - steer;
  430. RAW_driveB = speed + steer;
  431.  
  432. if(mode == _warmup){
  433. RAW_driveA = 0;
  434. RAW_driveB = 0;
  435. speed = 0;
  436. correction = 0;
  437. driveSum = 0;
  438. total_ADXL_GYRO = 0;
  439. angle = 0;
  440. if(adcSwitch > SW_DOWN){
  441. mode = _run;
  442. }
  443. }
  444.  
  445. if(mode == _run){
  446. if(adcSwitch > SW_DOWN){
  447. timeout = 0;
  448. }
  449.  
  450. if(adcSwitch < SW_DOWN){
  451. if(driveSum < 0){
  452. if(driveSum < SAFE_SPEED_N){
  453. buzzer = 1;
  454. timeout = timeout + 1;
  455. }
  456. }
  457.  
  458. if(driveSum > 0){
  459. if(driveSum > SAFE_SPEED){
  460. buzzer = 1;
  461. timeout = timeout + 1;
  462. }
  463. }
  464.  
  465. if(timeout > CRITICAL){
  466. mode = _down;
  467. }
  468. }
  469. }
  470.  
  471. if(mode == _down){
  472. for(buff1 = 1; buff1 <= 255; buff1++){
  473. if(RAW_driveA > 0){
  474. RAW_driveA = RAW_driveA - 1;
  475. }
  476. if(RAW_driveA < 0){
  477. RAW_driveA = RAW_driveA + 1;
  478. }
  479. if(RAW_driveB > 0){
  480. RAW_driveB = RAW_driveB - 1;
  481. }
  482. if(RAW_driveB > 0){
  483. RAW_driveB = RAW_driveB + 1;
  484. }
  485.  
  486. _delay_ms(2);
  487. set_pwm();
  488. }
  489. mode = _standby;
  490. }
  491. }
  492.  
  493. void set_pwm(){
  494. if(RAW_driveA > MAX_PWM){
  495. RAW_driveA = MAX_PWM;
  496. }
  497. if(RAW_driveA > MAX_PWM_N){
  498. RAW_driveA = MAX_PWM_N;
  499. }
  500.  
  501. if(RAW_driveA < 0){
  502. driveA = driveA * -1;
  503. PORTD |= (1 << CW_CCW_A);
  504. }
  505. if(RAW_driveA >= 0){
  506. driveA = RAW_driveA;
  507. PORTD &= ~(1 << CW_CCW_A);
  508. }
  509.  
  510. PWM_AL = 255 - driveA;
  511.  
  512. if(RAW_driveB > MAX_PWM){
  513. RAW_driveB = MAX_PWM;
  514. }
  515. if(RAW_driveB > MAX_PWM_N){
  516. RAW_driveB = MAX_PWM_N;
  517. }
  518.  
  519. if(RAW_driveA < 0){
  520. driveB = driveB * -1;
  521. PORTD |= (1 << CW_CCW_A);
  522. }
  523. if(RAW_driveA >= 0){
  524. driveB = RAW_driveB;
  525. PORTD &= ~(1 << CW_CCW_A);
  526. }
  527.  
  528. PWM_BL = driveB;
  529. }
  530.  
  531. void err_eval(){
  532. while (1){
  533. for (buff0 = 1; buff0 <= errNr; buff0++){
  534. PORTD |= (1 << LED_3);
  535. _delay_ms(150);
  536. PORTD &= ~(1 << LED_3);
  537. _delay_ms(150);
  538. }
  539. }
  540. }
  541.  
  542. void bootup(){
  543. for (char c = 0; c < 10; c++){
  544. PORTB |= ((1 << LED_3) | (1 << LED_2) | (1 << LED_1));
  545. _delay_ms(50);
  546. PORTB &= ~((1 << LED_3) | (1 << LED_2) | (1 << LED_1));
  547. _delay_ms(50);
  548. }
  549. }
  550.  
  551. void initTimer0(){
  552. TCNT0 = 100;
  553. TIMSK |= (1 << TOIE0);
  554. TCCR0 |= ((1 << CS02) | (1 << CS00) | (1 << ADPS0) | (1 << ADPS1) | (1 << ADPS2));
  555. }
  556.  
  557. void initTimer1(){
  558. TCCR1A |= ((1 << COM1A1) | (1 << COM1B1) | (1 << COM1B0) | (1 << WGM10));
  559. TCCR1B |= (1 << CS10);
  560. OCR1AL |= 0xff;
  561. }
  562.  
  563. void initADC(){
  564. ADMUX |= (1 << REFS0);
  565. ADCSRA |= (1 << ADEN) | (1 << ADIE);
  566. }
  567.  
  568. void init(){
  569. // DATA DIRECTION
  570. DDRA &= ~((1 << UBATT) | (1 << ADXL_Y)| (1 << ADXL_X) | (1 << GYRO_X) | (1 << GYRO_Y) | (1 << FOOTDETECT));
  571. DDRB |= ((1 << LED_3) | (1 << LED_2) | (1 << LED_1));
  572. DDRD &= ~(1 << CURRFLAG);
  573. DDRD |= ((1 << PWM_L) | (1 << PWM_R) | (1 << CW_CCW_A) | (1 << CW_CCW_B));
  574. // PIN STATE
  575. PORTB &= ~((1 << LED_3) | (1 << LED_2) | (1 << LED_1));
  576. DDRD &= ~((1 << PWM_L) | (1 << PWM_R) | (1 << CW_CCW_A) | (1 << CW_CCW_B));
  577. avg_BATT = BATT_OK * TOTAL_LOOP;
  578.  
  579. initADC();
  580. initTimer0();
  581. sei();
  582. }
  583.  
  584. //
  585. // MAIN
  586. //
  587. int main(void) {
  588. init();
  589. bootup();
  590. adcSwitch = 0;
  591. for (buff0 = 1; buff0 <= 10; buff0++){
  592. adcSwitch = adcSwitch + get_ADC(7);
  593. _delay_ms(1);
  594. }
  595. adcSwitch = adcSwitch / 10;
  596. _delay_ms(100);
  597. if(adcSwitch < 100){
  598. errNr = 4;
  599. err_eval();
  600. }
  601.  
  602.  
  603. adcRocker = 0;
  604. for(buff0 = 1; buff0 <= 10; buff0++){
  605. adcRocker = adcRocker + get_ADC(6);
  606. _delay_ms(1);
  607. }
  608. zero_Rocker = adcRocker / 10;
  609.  
  610. _delay_ms(100);
  611.  
  612.  
  613. adcGYRO = 0;
  614. for(buff0 = 1; buff0 <= 10; buff0++){
  615. buff1 = get_ADC(5);
  616. buff1 = 1024 - buff1;
  617. adcGYRO = adcGYRO + buff1;
  618. _delay_ms(5);
  619. }
  620. zero_GYRO = adcGYRO / 10;
  621. avg_GYRO = TOTAL_LOOP * zero_GYRO;
  622.  
  623.  
  624. adcADXL = 0;
  625. for(buff0 = 1; buff0 <= 10; buff0++){
  626. buff1 = get_ADC(3);
  627. adcADXL = adcADXL + buff1;
  628. _delay_ms(5);
  629. }
  630. zero_ADXL = adcADXL / 10;
  631.  
  632. if(zero_ADXL < 400){
  633. errNr = 3;
  634. err_eval();
  635. }
  636. if(zero_ADXL > 600){
  637. errNr = 3;
  638. err_eval();
  639. }
  640.  
  641. if(zero_ADXL < 350){
  642. errNr = 2;
  643. err_eval();
  644. }
  645. if(zero_ADXL > 750){
  646. errNr = 2;
  647. err_eval();
  648. }
  649. sei();
  650.  
  651. while (1) {
  652. }
  653. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement