├── .gitignore ├── Zeus_Car ├── ir_obstacle.cpp ├── ir_remote.cpp ├── hc165.h ├── ir_obstacle.h ├── hc165.cpp ├── ultrasonic.h ├── rgb.cpp ├── compass.h ├── grayscale.h ├── rgb.h ├── ultrasonic.cpp ├── car_control.h ├── ir_remote.h ├── test.h ├── qmc6310.h ├── qmc6310.cpp └── ai_camera.h ├── examples ├── 12_follow │ ├── ir_obstacle.cpp │ ├── hc165.h │ ├── ir_obstacle.h │ ├── hc165.cpp │ ├── ultrasonic.h │ ├── compass.h │ ├── ultrasonic.cpp │ ├── car_control.h │ ├── 12_follow.ino │ ├── qmc6310.h │ └── qmc6310.cpp ├── 11_obstacle_avoid │ ├── ir_obstacle.cpp │ ├── hc165.h │ ├── ir_obstacle.h │ ├── hc165.cpp │ ├── ultrasonic.h │ ├── compass.h │ ├── ultrasonic.cpp │ ├── car_control.h │ ├── 11_obstacle_avoid.ino │ ├── qmc6310.h │ └── qmc6310.cpp ├── 18_app_control_plus │ ├── ir_obstacle.cpp │ ├── hc165.h │ ├── ir_obstacle.h │ ├── rgb.h │ ├── hc165.cpp │ ├── rgb.cpp │ ├── ultrasonic.h │ ├── compass.h │ ├── grayscale.h │ ├── ultrasonic.cpp │ ├── car_control.h │ ├── common_definition.h │ ├── qmc6310.h │ ├── qmc6310.cpp │ └── ai_camera.h ├── 7_compass │ ├── ir_remote.cpp │ ├── rgb.h │ ├── rgb.cpp │ ├── compass.h │ ├── car_control.h │ ├── ir_remote.h │ ├── 7_compass.ino │ ├── qmc6310.h │ └── qmc6310.cpp ├── 6_car_light │ ├── ir_remote.cpp │ ├── ir_remote.h │ └── 6_car_light.ino ├── 5_remote_control │ ├── ir_remote.cpp │ ├── car_control.h │ ├── ir_remote.h │ ├── 5_remote_control.ino │ └── car_control.cpp ├── 8_move_field_centric │ ├── ir_remote.cpp │ ├── rgb.h │ ├── rgb.cpp │ ├── compass.h │ ├── car_control.h │ ├── ir_remote.h │ ├── qmc6310.h │ ├── qmc6310.cpp │ └── 8_move_field_centric.ino ├── 14_line_track │ ├── hc165.h │ ├── hc165.cpp │ ├── compass.h │ ├── grayscale.h │ ├── car_control.h │ ├── 14_line_track.ino │ ├── qmc6310.h │ └── qmc6310.cpp ├── 13_hc165_and_grayscale │ ├── hc165.h │ ├── hc165.cpp │ └── 13_hc165_and_grayscale.ino ├── 15_line_track_field_centric │ ├── hc165.h │ ├── hc165.cpp │ ├── compass.h │ ├── grayscale.h │ ├── car_control.h │ ├── 15_line_track_field_centric.ino │ ├── qmc6310.h │ └── qmc6310.cpp ├── 17_app_control │ ├── rgb.h │ ├── rgb.cpp │ ├── compass.h │ ├── car_control.h │ ├── qmc6310.h │ ├── qmc6310.cpp │ ├── 17_app_control.ino │ └── ai_camera.h ├── 9_hc165_and_ir_obstacle │ └── 9_hc165_and_ir_obstacle.ino ├── 16_ai_detection_from_app │ ├── 16_ai_detection_from_app.ino │ └── ai_camera.h ├── 10_ultrasonic │ └── 10_ultrasonic.ino ├── 2_omni_move │ └── 2_omni_move.ino ├── 1_basic_move │ └── 1_basic_move.ino ├── 3_rotate_and_move │ └── 3_rotate_and_move.ino └── 4_drift │ └── 4_drift.ino ├── test ├── qmc6310test │ ├── qmc6310.h │ ├── qmc6310.cpp │ └── qmc6310test.ino └── test.ino └── Readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | -------------------------------------------------------------------------------- /Zeus_Car/ir_obstacle.cpp: -------------------------------------------------------------------------------- 1 | #include "ir_obstacle.h" 2 | 3 | void irObstacleBegin() { 4 | hc165Begin(); 5 | } 6 | 7 | byte irObstacleRead() { 8 | return hc165Read(); 9 | } 10 | 11 | -------------------------------------------------------------------------------- /examples/12_follow/ir_obstacle.cpp: -------------------------------------------------------------------------------- 1 | #include "ir_obstacle.h" 2 | 3 | void irObstacleBegin() { 4 | hc165Begin(); 5 | } 6 | 7 | byte irObstacleRead() { 8 | return hc165Read(); 9 | } 10 | -------------------------------------------------------------------------------- /examples/11_obstacle_avoid/ir_obstacle.cpp: -------------------------------------------------------------------------------- 1 | #include "ir_obstacle.h" 2 | 3 | void irObstacleBegin() { 4 | hc165Begin(); 5 | } 6 | 7 | byte irObstacleRead() { 8 | return hc165Read(); 9 | } 10 | -------------------------------------------------------------------------------- /examples/18_app_control_plus/ir_obstacle.cpp: -------------------------------------------------------------------------------- 1 | #include "ir_obstacle.h" 2 | 3 | void irObstacleBegin() { 4 | hc165Begin(); 5 | } 6 | 7 | byte irObstacleRead() { 8 | return hc165Read(); 9 | } 10 | -------------------------------------------------------------------------------- /Zeus_Car/ir_remote.cpp: -------------------------------------------------------------------------------- 1 | #include "ir_remote.h" 2 | #include 3 | 4 | CNec IRLremote; 5 | 6 | void irBegin() { 7 | if (!IRLremote.begin(IR_RECEIVER_PIN)) 8 | Serial.println(F("You did not choose a valid pin.")); 9 | } 10 | 11 | uint8_t irRead() { 12 | long result = IR_KEY_ERROR; 13 | if (IRLremote.available()) { 14 | auto data = IRLremote.read(); 15 | result = data.command; 16 | } 17 | return result; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /examples/7_compass/ir_remote.cpp: -------------------------------------------------------------------------------- 1 | #include "ir_remote.h" 2 | #include 3 | 4 | CNec IRLremote; 5 | 6 | void irBegin() { 7 | if (!IRLremote.begin(IR_RECEIVER_PIN)) 8 | Serial.println(F("You did not choose a valid pin.")); 9 | } 10 | 11 | uint8_t irRead() { 12 | long result = IR_KEY_ERROR; 13 | if (IRLremote.available()) { 14 | auto data = IRLremote.read(); 15 | result = data.command; 16 | } 17 | return result; 18 | } 19 | -------------------------------------------------------------------------------- /examples/6_car_light/ir_remote.cpp: -------------------------------------------------------------------------------- 1 | #include "ir_remote.h" 2 | #include 3 | 4 | CNec IRLremote; 5 | 6 | void irBegin() { 7 | if (!IRLremote.begin(IR_RECEIVER_PIN)) 8 | Serial.println(F("You did not choose a valid pin.")); 9 | } 10 | 11 | uint8_t irRead() { 12 | long result = IR_KEY_ERROR; 13 | if (IRLremote.available()) { 14 | auto data = IRLremote.read(); 15 | result = data.command; 16 | } 17 | return result; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /Zeus_Car/hc165.h: -------------------------------------------------------------------------------- 1 | #ifndef __HC165_H__ 2 | #define __HC165_H__ 3 | #include 4 | 5 | /** 6 | * @name Define pins of the HC165 IO expansion chip 7 | */ 8 | #define PIN_74HC165_CP 8 9 | #define PIN_74HC165_PL 9 10 | #define PIN_74HC165_Q7 7 11 | 12 | /** HC165 init */ 13 | void hc165Begin(); 14 | 15 | /** 16 | * @brief return IO status of HC165 17 | * 18 | * @return uint16_t 19 | */ 20 | uint16_t hc165Read(); 21 | 22 | #endif // __HC165_H__ 23 | 24 | -------------------------------------------------------------------------------- /examples/5_remote_control/ir_remote.cpp: -------------------------------------------------------------------------------- 1 | #include "ir_remote.h" 2 | #include 3 | 4 | CNec IRLremote; 5 | 6 | void irBegin() { 7 | if (!IRLremote.begin(IR_RECEIVER_PIN)) 8 | Serial.println(F("You did not choose a valid pin.")); 9 | } 10 | 11 | uint8_t irRead() { 12 | long result = IR_KEY_ERROR; 13 | if (IRLremote.available()) { 14 | auto data = IRLremote.read(); 15 | result = data.command; 16 | } 17 | return result; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /examples/8_move_field_centric/ir_remote.cpp: -------------------------------------------------------------------------------- 1 | #include "ir_remote.h" 2 | #include 3 | 4 | CNec IRLremote; 5 | 6 | void irBegin() { 7 | if (!IRLremote.begin(IR_RECEIVER_PIN)) 8 | Serial.println(F("You did not choose a valid pin.")); 9 | } 10 | 11 | uint8_t irRead() { 12 | long result = IR_KEY_ERROR; 13 | if (IRLremote.available()) { 14 | auto data = IRLremote.read(); 15 | result = data.command; 16 | } 17 | return result; 18 | } 19 | -------------------------------------------------------------------------------- /examples/12_follow/hc165.h: -------------------------------------------------------------------------------- 1 | #ifndef __HC165_H__ 2 | #define __HC165_H__ 3 | #include 4 | 5 | /** 6 | * @name Define pins of the HC165 IO expansion chip 7 | */ 8 | #define PIN_74HC165_CP 8 9 | #define PIN_74HC165_PL 9 10 | #define PIN_74HC165_Q7 7 11 | 12 | /** HC165 init */ 13 | void hc165Begin(); 14 | 15 | /** 16 | * @brief return IO status of HC165 17 | * 18 | * @return uint16_t 19 | */ 20 | uint16_t hc165Read(); 21 | 22 | #endif // __HC165_H__ 23 | -------------------------------------------------------------------------------- /examples/14_line_track/hc165.h: -------------------------------------------------------------------------------- 1 | #ifndef __HC165_H__ 2 | #define __HC165_H__ 3 | #include 4 | 5 | /** 6 | * @name Define pins of the HC165 IO expansion chip 7 | */ 8 | #define PIN_74HC165_CP 8 9 | #define PIN_74HC165_PL 9 10 | #define PIN_74HC165_Q7 7 11 | 12 | /** HC165 init */ 13 | void hc165Begin(); 14 | 15 | /** 16 | * @brief return IO status of HC165 17 | * 18 | * @return uint16_t 19 | */ 20 | uint16_t hc165Read(); 21 | 22 | #endif // __HC165_H__ 23 | -------------------------------------------------------------------------------- /examples/11_obstacle_avoid/hc165.h: -------------------------------------------------------------------------------- 1 | #ifndef __HC165_H__ 2 | #define __HC165_H__ 3 | #include 4 | 5 | /** 6 | * @name Define pins of the HC165 IO expansion chip 7 | */ 8 | #define PIN_74HC165_CP 8 9 | #define PIN_74HC165_PL 9 10 | #define PIN_74HC165_Q7 7 11 | 12 | /** HC165 init */ 13 | void hc165Begin(); 14 | 15 | /** 16 | * @brief return IO status of HC165 17 | * 18 | * @return uint16_t 19 | */ 20 | uint16_t hc165Read(); 21 | 22 | #endif // __HC165_H__ 23 | -------------------------------------------------------------------------------- /examples/18_app_control_plus/hc165.h: -------------------------------------------------------------------------------- 1 | #ifndef __HC165_H__ 2 | #define __HC165_H__ 3 | #include 4 | 5 | /** 6 | * @name Define pins of the HC165 IO expansion chip 7 | */ 8 | #define PIN_74HC165_CP 8 9 | #define PIN_74HC165_PL 9 10 | #define PIN_74HC165_Q7 7 11 | 12 | /** HC165 init */ 13 | void hc165Begin(); 14 | 15 | /** 16 | * @brief return IO status of HC165 17 | * 18 | * @return uint16_t 19 | */ 20 | uint16_t hc165Read(); 21 | 22 | #endif // __HC165_H__ 23 | -------------------------------------------------------------------------------- /examples/13_hc165_and_grayscale/hc165.h: -------------------------------------------------------------------------------- 1 | #ifndef __HC165_H__ 2 | #define __HC165_H__ 3 | #include 4 | 5 | /** 6 | * @name Define pins of the HC165 IO expansion chip 7 | */ 8 | #define PIN_74HC165_CP 8 9 | #define PIN_74HC165_PL 9 10 | #define PIN_74HC165_Q7 7 11 | 12 | /** HC165 init */ 13 | void hc165Begin(); 14 | 15 | /** 16 | * @brief return IO status of HC165 17 | * 18 | * @return uint16_t 19 | */ 20 | uint16_t hc165Read(); 21 | 22 | #endif // __HC165_H__ 23 | -------------------------------------------------------------------------------- /examples/15_line_track_field_centric/hc165.h: -------------------------------------------------------------------------------- 1 | #ifndef __HC165_H__ 2 | #define __HC165_H__ 3 | #include 4 | 5 | /** 6 | * @name Define pins of the HC165 IO expansion chip 7 | */ 8 | #define PIN_74HC165_CP 8 9 | #define PIN_74HC165_PL 9 10 | #define PIN_74HC165_Q7 7 11 | 12 | /** HC165 init */ 13 | void hc165Begin(); 14 | 15 | /** 16 | * @brief return IO status of HC165 17 | * 18 | * @return uint16_t 19 | */ 20 | uint16_t hc165Read(); 21 | 22 | #endif // __HC165_H__ 23 | -------------------------------------------------------------------------------- /Zeus_Car/ir_obstacle.h: -------------------------------------------------------------------------------- 1 | #ifndef __IR_OBSTACLE_H__ 2 | #define __IR_OBSTACLE_H__ 3 | 4 | #include "hc165.h" 5 | 6 | /** 7 | * @brief init IR Obstacle Module 8 | * 9 | */ 10 | void irObstacleBegin(); 11 | 12 | /** 13 | * @brief Returns the IO level status of the infrared obstacle avoidance module 14 | * connected with HC165 IO expansion chip. 15 | * Actually it is the function hc165Read() 16 | * 17 | * @return byte 18 | */ 19 | byte irObstacleRead(); 20 | 21 | #endif // __IR_OBSTACLE_H__ 22 | 23 | -------------------------------------------------------------------------------- /examples/12_follow/ir_obstacle.h: -------------------------------------------------------------------------------- 1 | #ifndef __IR_OBSTACLE_H__ 2 | #define __IR_OBSTACLE_H__ 3 | 4 | #include "hc165.h" 5 | 6 | /** 7 | * @brief init IR Obstacle Module 8 | * 9 | */ 10 | void irObstacleBegin(); 11 | 12 | /** 13 | * @brief Returns the IO level status of the infrared obstacle avoidance module 14 | * connected with HC165 IO expansion chip. 15 | * Actually it is the function hc165Read() 16 | * 17 | * @return byte 18 | */ 19 | byte irObstacleRead(); 20 | 21 | #endif // __IR_OBSTACLE_H__ 22 | -------------------------------------------------------------------------------- /examples/11_obstacle_avoid/ir_obstacle.h: -------------------------------------------------------------------------------- 1 | #ifndef __IR_OBSTACLE_H__ 2 | #define __IR_OBSTACLE_H__ 3 | 4 | #include "hc165.h" 5 | 6 | /** 7 | * @brief init IR Obstacle Module 8 | * 9 | */ 10 | void irObstacleBegin(); 11 | 12 | /** 13 | * @brief Returns the IO level status of the infrared obstacle avoidance module 14 | * connected with HC165 IO expansion chip. 15 | * Actually it is the function hc165Read() 16 | * 17 | * @return byte 18 | */ 19 | byte irObstacleRead(); 20 | 21 | #endif // __IR_OBSTACLE_H__ 22 | -------------------------------------------------------------------------------- /examples/18_app_control_plus/ir_obstacle.h: -------------------------------------------------------------------------------- 1 | #ifndef __IR_OBSTACLE_H__ 2 | #define __IR_OBSTACLE_H__ 3 | 4 | #include "hc165.h" 5 | 6 | /** 7 | * @brief init IR Obstacle Module 8 | * 9 | */ 10 | void irObstacleBegin(); 11 | 12 | /** 13 | * @brief Returns the IO level status of the infrared obstacle avoidance module 14 | * connected with HC165 IO expansion chip. 15 | * Actually it is the function hc165Read() 16 | * 17 | * @return byte 18 | */ 19 | byte irObstacleRead(); 20 | 21 | #endif // __IR_OBSTACLE_H__ 22 | -------------------------------------------------------------------------------- /examples/7_compass/rgb.h: -------------------------------------------------------------------------------- 1 | #ifndef __RGB_H__ 2 | #define __RGB_H__ 3 | 4 | #include 5 | 6 | /** Indicate whether RGB leds are common-anodes or not 7 | * - 0 common cathode 8 | * - 1 common anode 9 | */ 10 | #define COMMON_ANODE 0 11 | 12 | /** Set the pins of RGB leds, the order is R,G,B */ 13 | #define RGB_PINS (uint8_t[3]){12, 13, 11} 14 | 15 | /** Initialize RGB leds */ 16 | void rgbBegin(); 17 | 18 | /** Set LED color in HEX */ 19 | void rgbWrite(uint32_t color); 20 | 21 | /** Set LED color in 8bit R,G,B (0 ~ 255)*/ 22 | void rgbWrite(uint8_t r, uint8_t g, uint8_t b); 23 | 24 | /** Turn odd RGB LEDs*/ 25 | void rgbOff(); 26 | 27 | #endif // __RGB_H__ 28 | -------------------------------------------------------------------------------- /examples/17_app_control/rgb.h: -------------------------------------------------------------------------------- 1 | #ifndef __RGB_H__ 2 | #define __RGB_H__ 3 | 4 | #include 5 | 6 | /** Indicate whether RGB leds are common-anodes or not 7 | * - 0 common cathode 8 | * - 1 common anode 9 | */ 10 | #define COMMON_ANODE 0 11 | 12 | /** Set the pins of RGB leds, the order is R,G,B */ 13 | #define RGB_PINS (uint8_t[3]){12, 13, 11} 14 | 15 | /** Initialize RGB leds */ 16 | void rgbBegin(); 17 | 18 | /** Set LED color in HEX */ 19 | void rgbWrite(uint32_t color); 20 | 21 | /** Set LED color in 8bit R,G,B (0 ~ 255)*/ 22 | void rgbWrite(uint8_t r, uint8_t g, uint8_t b); 23 | 24 | /** Turn odd RGB LEDs*/ 25 | void rgbOff(); 26 | 27 | #endif // __RGB_H__ 28 | -------------------------------------------------------------------------------- /examples/18_app_control_plus/rgb.h: -------------------------------------------------------------------------------- 1 | #ifndef __RGB_H__ 2 | #define __RGB_H__ 3 | 4 | #include 5 | 6 | /** Indicate whether RGB leds are common-anodes or not 7 | * - 0 common cathode 8 | * - 1 common anode 9 | */ 10 | #define COMMON_ANODE 0 11 | 12 | /** Set the pins of RGB leds, the order is R,G,B */ 13 | #define RGB_PINS (uint8_t[3]){12, 13, 11} 14 | 15 | /** Initialize RGB leds */ 16 | void rgbBegin(); 17 | 18 | /** Set LED color in HEX */ 19 | void rgbWrite(uint32_t color); 20 | 21 | /** Set LED color in 8bit R,G,B (0 ~ 255)*/ 22 | void rgbWrite(uint8_t r, uint8_t g, uint8_t b); 23 | 24 | /** Turn odd RGB LEDs*/ 25 | void rgbOff(); 26 | 27 | #endif // __RGB_H__ 28 | -------------------------------------------------------------------------------- /examples/8_move_field_centric/rgb.h: -------------------------------------------------------------------------------- 1 | #ifndef __RGB_H__ 2 | #define __RGB_H__ 3 | 4 | #include 5 | 6 | /** Indicate whether RGB leds are common-anodes or not 7 | * - 0 common cathode 8 | * - 1 common anode 9 | */ 10 | #define COMMON_ANODE 0 11 | 12 | /** Set the pins of RGB leds, the order is R,G,B */ 13 | #define RGB_PINS (uint8_t[3]){12, 13, 11} 14 | 15 | /** Initialize RGB leds */ 16 | void rgbBegin(); 17 | 18 | /** Set LED color in HEX */ 19 | void rgbWrite(uint32_t color); 20 | 21 | /** Set LED color in 8bit R,G,B (0 ~ 255)*/ 22 | void rgbWrite(uint8_t r, uint8_t g, uint8_t b); 23 | 24 | /** Turn odd RGB LEDs*/ 25 | void rgbOff(); 26 | 27 | #endif // __RGB_H__ 28 | -------------------------------------------------------------------------------- /Zeus_Car/hc165.cpp: -------------------------------------------------------------------------------- 1 | #include "hc165.h" 2 | 3 | void hc165Begin() { 4 | pinMode(PIN_74HC165_CP, OUTPUT); 5 | pinMode(PIN_74HC165_PL, OUTPUT); 6 | pinMode(PIN_74HC165_Q7, INPUT); 7 | } 8 | 9 | uint16_t hc165Read() { 10 | // Write pulse to load pin 11 | digitalWrite(PIN_74HC165_PL, LOW); 12 | delayMicroseconds(5); 13 | digitalWrite(PIN_74HC165_CP, HIGH); 14 | delayMicroseconds(5); 15 | digitalWrite(PIN_74HC165_PL, HIGH); 16 | delayMicroseconds(5); 17 | 18 | // Get data from 74HC165 19 | uint16_t first8 = shiftIn(PIN_74HC165_Q7, PIN_74HC165_CP, MSBFIRST); 20 | uint16_t last8 = shiftIn(PIN_74HC165_Q7, PIN_74HC165_CP, MSBFIRST); 21 | 22 | return last8 << 8 | first8; 23 | } 24 | 25 | -------------------------------------------------------------------------------- /examples/12_follow/hc165.cpp: -------------------------------------------------------------------------------- 1 | #include "hc165.h" 2 | 3 | void hc165Begin() { 4 | pinMode(PIN_74HC165_CP, OUTPUT); 5 | pinMode(PIN_74HC165_PL, OUTPUT); 6 | pinMode(PIN_74HC165_Q7, INPUT); 7 | } 8 | 9 | uint16_t hc165Read() { 10 | // Write pulse to load pin 11 | digitalWrite(PIN_74HC165_PL, LOW); 12 | delayMicroseconds(5); 13 | digitalWrite(PIN_74HC165_CP, HIGH); 14 | delayMicroseconds(5); 15 | digitalWrite(PIN_74HC165_PL, HIGH); 16 | delayMicroseconds(5); 17 | 18 | // Get data from 74HC165 19 | uint16_t first8 = shiftIn(PIN_74HC165_Q7, PIN_74HC165_CP, MSBFIRST); 20 | uint16_t last8 = shiftIn(PIN_74HC165_Q7, PIN_74HC165_CP, MSBFIRST); 21 | 22 | return last8 << 8 | first8; 23 | } 24 | -------------------------------------------------------------------------------- /examples/11_obstacle_avoid/hc165.cpp: -------------------------------------------------------------------------------- 1 | #include "hc165.h" 2 | 3 | void hc165Begin() { 4 | pinMode(PIN_74HC165_CP, OUTPUT); 5 | pinMode(PIN_74HC165_PL, OUTPUT); 6 | pinMode(PIN_74HC165_Q7, INPUT); 7 | } 8 | 9 | uint16_t hc165Read() { 10 | // Write pulse to load pin 11 | digitalWrite(PIN_74HC165_PL, LOW); 12 | delayMicroseconds(5); 13 | digitalWrite(PIN_74HC165_CP, HIGH); 14 | delayMicroseconds(5); 15 | digitalWrite(PIN_74HC165_PL, HIGH); 16 | delayMicroseconds(5); 17 | 18 | // Get data from 74HC165 19 | uint16_t first8 = shiftIn(PIN_74HC165_Q7, PIN_74HC165_CP, MSBFIRST); 20 | uint16_t last8 = shiftIn(PIN_74HC165_Q7, PIN_74HC165_CP, MSBFIRST); 21 | 22 | return last8 << 8 | first8; 23 | } 24 | -------------------------------------------------------------------------------- /examples/14_line_track/hc165.cpp: -------------------------------------------------------------------------------- 1 | #include "hc165.h" 2 | 3 | void hc165Begin() { 4 | pinMode(PIN_74HC165_CP, OUTPUT); 5 | pinMode(PIN_74HC165_PL, OUTPUT); 6 | pinMode(PIN_74HC165_Q7, INPUT); 7 | } 8 | 9 | uint16_t hc165Read() { 10 | // Write pulse to load pin 11 | digitalWrite(PIN_74HC165_PL, LOW); 12 | delayMicroseconds(5); 13 | digitalWrite(PIN_74HC165_CP, HIGH); 14 | delayMicroseconds(5); 15 | digitalWrite(PIN_74HC165_PL, HIGH); 16 | delayMicroseconds(5); 17 | 18 | // Get data from 74HC165 19 | uint16_t first8 = shiftIn(PIN_74HC165_Q7, PIN_74HC165_CP, MSBFIRST); 20 | uint16_t last8 = shiftIn(PIN_74HC165_Q7, PIN_74HC165_CP, MSBFIRST); 21 | 22 | return last8 << 8 | first8; 23 | } 24 | -------------------------------------------------------------------------------- /examples/13_hc165_and_grayscale/hc165.cpp: -------------------------------------------------------------------------------- 1 | #include "hc165.h" 2 | 3 | void hc165Begin() { 4 | pinMode(PIN_74HC165_CP, OUTPUT); 5 | pinMode(PIN_74HC165_PL, OUTPUT); 6 | pinMode(PIN_74HC165_Q7, INPUT); 7 | } 8 | 9 | uint16_t hc165Read() { 10 | // Write pulse to load pin 11 | digitalWrite(PIN_74HC165_PL, LOW); 12 | delayMicroseconds(5); 13 | digitalWrite(PIN_74HC165_CP, HIGH); 14 | delayMicroseconds(5); 15 | digitalWrite(PIN_74HC165_PL, HIGH); 16 | delayMicroseconds(5); 17 | 18 | // Get data from 74HC165 19 | uint16_t first8 = shiftIn(PIN_74HC165_Q7, PIN_74HC165_CP, MSBFIRST); 20 | uint16_t last8 = shiftIn(PIN_74HC165_Q7, PIN_74HC165_CP, MSBFIRST); 21 | 22 | return last8 << 8 | first8; 23 | } 24 | -------------------------------------------------------------------------------- /examples/18_app_control_plus/hc165.cpp: -------------------------------------------------------------------------------- 1 | #include "hc165.h" 2 | 3 | void hc165Begin() { 4 | pinMode(PIN_74HC165_CP, OUTPUT); 5 | pinMode(PIN_74HC165_PL, OUTPUT); 6 | pinMode(PIN_74HC165_Q7, INPUT); 7 | } 8 | 9 | uint16_t hc165Read() { 10 | // Write pulse to load pin 11 | digitalWrite(PIN_74HC165_PL, LOW); 12 | delayMicroseconds(5); 13 | digitalWrite(PIN_74HC165_CP, HIGH); 14 | delayMicroseconds(5); 15 | digitalWrite(PIN_74HC165_PL, HIGH); 16 | delayMicroseconds(5); 17 | 18 | // Get data from 74HC165 19 | uint16_t first8 = shiftIn(PIN_74HC165_Q7, PIN_74HC165_CP, MSBFIRST); 20 | uint16_t last8 = shiftIn(PIN_74HC165_Q7, PIN_74HC165_CP, MSBFIRST); 21 | 22 | return last8 << 8 | first8; 23 | } 24 | -------------------------------------------------------------------------------- /examples/15_line_track_field_centric/hc165.cpp: -------------------------------------------------------------------------------- 1 | #include "hc165.h" 2 | 3 | void hc165Begin() { 4 | pinMode(PIN_74HC165_CP, OUTPUT); 5 | pinMode(PIN_74HC165_PL, OUTPUT); 6 | pinMode(PIN_74HC165_Q7, INPUT); 7 | } 8 | 9 | uint16_t hc165Read() { 10 | // Write pulse to load pin 11 | digitalWrite(PIN_74HC165_PL, LOW); 12 | delayMicroseconds(5); 13 | digitalWrite(PIN_74HC165_CP, HIGH); 14 | delayMicroseconds(5); 15 | digitalWrite(PIN_74HC165_PL, HIGH); 16 | delayMicroseconds(5); 17 | 18 | // Get data from 74HC165 19 | uint16_t first8 = shiftIn(PIN_74HC165_Q7, PIN_74HC165_CP, MSBFIRST); 20 | uint16_t last8 = shiftIn(PIN_74HC165_Q7, PIN_74HC165_CP, MSBFIRST); 21 | 22 | return last8 << 8 | first8; 23 | } 24 | -------------------------------------------------------------------------------- /examples/7_compass/rgb.cpp: -------------------------------------------------------------------------------- 1 | #include "rgb.h" 2 | #include 3 | 4 | void rgbBegin() { 5 | for (uint8_t i = 0; i < 3; i++) { 6 | SoftPWMSet(RGB_PINS[i], 0); 7 | SoftPWMSetFadeTime(RGB_PINS[i], 100, 100); 8 | } 9 | } 10 | 11 | void rgbWrite(uint32_t color) { 12 | uint8_t r = (color >> 16) & 0xFF; 13 | uint8_t g = (color >> 8) & 0xFF; 14 | uint8_t b = (color >> 0) & 0xFF; 15 | rgbWrite(r, g, b); 16 | } 17 | 18 | void rgbWrite(uint8_t r, uint8_t g, uint8_t b) { 19 | #if COMMON_ANODE 20 | r = 255 - r; 21 | g = 255 - g; 22 | b = 255 - b; 23 | #endif 24 | SoftPWMSet(RGB_PINS[0], r); 25 | SoftPWMSet(RGB_PINS[1], g); 26 | SoftPWMSet(RGB_PINS[2], b); 27 | } 28 | 29 | void rgbOff() { 30 | rgbWrite(0, 0, 0); 31 | } 32 | -------------------------------------------------------------------------------- /examples/8_move_field_centric/rgb.cpp: -------------------------------------------------------------------------------- 1 | #include "rgb.h" 2 | #include 3 | 4 | void rgbBegin() { 5 | for (uint8_t i = 0; i < 3; i++) { 6 | SoftPWMSet(RGB_PINS[i], 0); 7 | SoftPWMSetFadeTime(RGB_PINS[i], 100, 100); 8 | } 9 | } 10 | 11 | void rgbWrite(uint32_t color) { 12 | uint8_t r = (color >> 16) & 0xFF; 13 | uint8_t g = (color >> 8) & 0xFF; 14 | uint8_t b = (color >> 0) & 0xFF; 15 | rgbWrite(r, g, b); 16 | } 17 | 18 | void rgbWrite(uint8_t r, uint8_t g, uint8_t b) { 19 | #if COMMON_ANODE 20 | r = 255 - r; 21 | g = 255 - g; 22 | b = 255 - b; 23 | #endif 24 | SoftPWMSet(RGB_PINS[0], r); 25 | SoftPWMSet(RGB_PINS[1], g); 26 | SoftPWMSet(RGB_PINS[2], b); 27 | } 28 | 29 | void rgbOff() { 30 | rgbWrite(0, 0, 0); 31 | } 32 | -------------------------------------------------------------------------------- /examples/17_app_control/rgb.cpp: -------------------------------------------------------------------------------- 1 | #include "rgb.h" 2 | #include 3 | 4 | void rgbBegin() { 5 | SoftPWMBegin(); 6 | for (uint8_t i = 0; i < 3; i++) { 7 | SoftPWMSet(RGB_PINS[i], 0); 8 | SoftPWMSetFadeTime(RGB_PINS[i], 100, 100); 9 | } 10 | } 11 | 12 | void rgbWrite(uint32_t color) { 13 | uint8_t r = (color >> 16) & 0xFF; 14 | uint8_t g = (color >> 8) & 0xFF; 15 | uint8_t b = (color >> 0) & 0xFF; 16 | rgbWrite(r, g, b); 17 | } 18 | 19 | void rgbWrite(uint8_t r, uint8_t g, uint8_t b) { 20 | #if COMMON_ANODE 21 | r = 255 - r; 22 | g = 255 - g; 23 | b = 255 - b; 24 | #endif 25 | SoftPWMSet(RGB_PINS[0], r); 26 | SoftPWMSet(RGB_PINS[1], g); 27 | SoftPWMSet(RGB_PINS[2], b); 28 | } 29 | 30 | void rgbOff() { 31 | rgbWrite(0, 0, 0); 32 | } 33 | -------------------------------------------------------------------------------- /examples/18_app_control_plus/rgb.cpp: -------------------------------------------------------------------------------- 1 | #include "rgb.h" 2 | #include 3 | 4 | void rgbBegin() { 5 | SoftPWMBegin(); 6 | for (uint8_t i = 0; i < 3; i++) { 7 | SoftPWMSet(RGB_PINS[i], 0); 8 | SoftPWMSetFadeTime(RGB_PINS[i], 100, 100); 9 | } 10 | } 11 | 12 | void rgbWrite(uint32_t color) { 13 | uint8_t r = (color >> 16) & 0xFF; 14 | uint8_t g = (color >> 8) & 0xFF; 15 | uint8_t b = (color >> 0) & 0xFF; 16 | rgbWrite(r, g, b); 17 | } 18 | 19 | void rgbWrite(uint8_t r, uint8_t g, uint8_t b) { 20 | #if COMMON_ANODE 21 | r = 255 - r; 22 | g = 255 - g; 23 | b = 255 - b; 24 | #endif 25 | SoftPWMSet(RGB_PINS[0], r); 26 | SoftPWMSet(RGB_PINS[1], g); 27 | SoftPWMSet(RGB_PINS[2], b); 28 | } 29 | 30 | void rgbOff() { 31 | rgbWrite(0, 0, 0); 32 | } 33 | -------------------------------------------------------------------------------- /Zeus_Car/ultrasonic.h: -------------------------------------------------------------------------------- 1 | #ifndef __ULTRASONIC_H__ 2 | #define __ULTRASONIC_H__ 3 | 4 | /** Set pins of ultrasonic 5 | * |To save IO ports, echo and tring could share an identical pin 6 | */ 7 | #define ULTRASONIC_TRIG_PIN 10 8 | #define ULTRASONIC_ECHO_PIN 10 9 | 10 | /** Configure ultrasonic obstacle avoidance distance, unit cm */ 11 | #define ULTRASONIC_AVOIDANCE_THRESHOLD 20 12 | 13 | #define MAX_DISTANCE 2000 // unit: cm 14 | 15 | /** Return the distance read by the ultrasonic module, unit cm */ 16 | float ultrasonicRead(); 17 | 18 | /** Determine whether there is an obstacle ahead according to the set ULTRASONIC_AVOIDANCE_THRESHOLD */ 19 | bool ultrasonicIsObstacle(); 20 | 21 | /** Determine whether there is clear ahead according to the set ULTRASONIC_AVOIDANCE_THRESHOLD */ 22 | bool ultrasonicIsClear(); 23 | 24 | #endif // __ULTRASONIC_H__ 25 | -------------------------------------------------------------------------------- /examples/12_follow/ultrasonic.h: -------------------------------------------------------------------------------- 1 | #ifndef __ULTRASONIC_H__ 2 | #define __ULTRASONIC_H__ 3 | 4 | /** Set pins of ultrasonic 5 | * |To save IO ports, echo and tring could share an identical pin 6 | */ 7 | #define ULTRASONIC_TRIG_PIN 10 8 | #define ULTRASONIC_ECHO_PIN 10 9 | 10 | /** Configure ultrasonic obstacle avoidance distance, unit cm */ 11 | #define ULTRASONIC_AVOIDANCE_THRESHOLD 20 12 | 13 | #define MAX_DISTANCE 2000 // unit: cm 14 | 15 | /** Return the distance read by the ultrasonic module, unit cm */ 16 | float ultrasonicRead(); 17 | 18 | /** Determine whether there is an obstacle ahead according to the set ULTRASONIC_AVOIDANCE_THRESHOLD */ 19 | bool ultrasonicIsObstacle(); 20 | 21 | /** Determine whether there is clear ahead according to the set ULTRASONIC_AVOIDANCE_THRESHOLD */ 22 | bool ultrasonicIsClear(); 23 | 24 | #endif // __ULTRASONIC_H__ 25 | -------------------------------------------------------------------------------- /examples/11_obstacle_avoid/ultrasonic.h: -------------------------------------------------------------------------------- 1 | #ifndef __ULTRASONIC_H__ 2 | #define __ULTRASONIC_H__ 3 | 4 | /** Set pins of ultrasonic 5 | * |To save IO ports, echo and tring could share an identical pin 6 | */ 7 | #define ULTRASONIC_TRIG_PIN 10 8 | #define ULTRASONIC_ECHO_PIN 10 9 | 10 | /** Configure ultrasonic obstacle avoidance distance, unit cm */ 11 | #define ULTRASONIC_AVOIDANCE_THRESHOLD 20 12 | 13 | #define MAX_DISTANCE 2000 // unit: cm 14 | 15 | /** Return the distance read by the ultrasonic module, unit cm */ 16 | float ultrasonicRead(); 17 | 18 | /** Determine whether there is an obstacle ahead according to the set ULTRASONIC_AVOIDANCE_THRESHOLD */ 19 | bool ultrasonicIsObstacle(); 20 | 21 | /** Determine whether there is clear ahead according to the set ULTRASONIC_AVOIDANCE_THRESHOLD */ 22 | bool ultrasonicIsClear(); 23 | 24 | #endif // __ULTRASONIC_H__ 25 | -------------------------------------------------------------------------------- /examples/18_app_control_plus/ultrasonic.h: -------------------------------------------------------------------------------- 1 | #ifndef __ULTRASONIC_H__ 2 | #define __ULTRASONIC_H__ 3 | 4 | /** Set pins of ultrasonic 5 | * |To save IO ports, echo and tring could share an identical pin 6 | */ 7 | #define ULTRASONIC_TRIG_PIN 10 8 | #define ULTRASONIC_ECHO_PIN 10 9 | 10 | /** Configure ultrasonic obstacle avoidance distance, unit cm */ 11 | #define ULTRASONIC_AVOIDANCE_THRESHOLD 20 12 | 13 | #define MAX_DISTANCE 2000 // unit: cm 14 | 15 | /** Return the distance read by the ultrasonic module, unit cm */ 16 | float ultrasonicRead(); 17 | 18 | /** Determine whether there is an obstacle ahead according to the set ULTRASONIC_AVOIDANCE_THRESHOLD */ 19 | bool ultrasonicIsObstacle(); 20 | 21 | /** Determine whether there is clear ahead according to the set ULTRASONIC_AVOIDANCE_THRESHOLD */ 22 | bool ultrasonicIsClear(); 23 | 24 | #endif // __ULTRASONIC_H__ 25 | -------------------------------------------------------------------------------- /Zeus_Car/rgb.cpp: -------------------------------------------------------------------------------- 1 | #include "rgb.h" 2 | #include 3 | 4 | void rgbBegin() { 5 | for (uint8_t i = 0; i < 3; i++) { 6 | SoftPWMSet(RGB_PINS[i], 0); 7 | SoftPWMSetFadeTime(RGB_PINS[i], 100, 100); 8 | } 9 | } 10 | 11 | void rgbWrite(uint32_t color) { 12 | uint8_t r = (color >> 16) & 0xFF; 13 | uint8_t g = (color >> 8) & 0xFF; 14 | uint8_t b = (color >> 0) & 0xFF; 15 | rgbWrite(r, g, b); 16 | } 17 | 18 | void rgbWrite(uint8_t r, uint8_t g, uint8_t b) { 19 | // calibrate brightness 20 | r = int(r * R_OFFSET); 21 | g = int(g * G_OFFSET); 22 | b = int(b * B_OFFSET); 23 | // COMMON_ANODE reverse 24 | #if COMMON_ANODE 25 | r = 255 - r; 26 | g = 255 - g; 27 | b = 255 - b; 28 | #endif 29 | // set volatge 30 | SoftPWMSet(RGB_PINS[0], r); 31 | SoftPWMSet(RGB_PINS[1], g); 32 | SoftPWMSet(RGB_PINS[2], b); 33 | } 34 | 35 | void rgbOff() { 36 | rgbWrite(0, 0, 0); 37 | } 38 | 39 | -------------------------------------------------------------------------------- /Zeus_Car/compass.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMPASS_H__ 2 | #define __COMPASS_H__ 3 | 4 | #include 5 | 6 | /** Set the number of samples for average filtering 7 | * 8 | * default 30 9 | */ 10 | #define AVERAGE_FILTER_SIZE 30 11 | 12 | /** Set the EEPROM start address where the calibration value is stored 13 | * 14 | * default 0 15 | */ 16 | #define EEPROM_CALIBRATION_ADDRESS 0 17 | 18 | /** Set the time required for calibration values to stabilize 19 | * 20 | * uinit millisecond, default 3000 21 | */ 22 | #define CALIBRATION_TIME 3000 23 | 24 | /** Whether to turn on the average filter 25 | * 26 | * default true 27 | */ 28 | #define AVERAGE_FILTER true 29 | // #define AVERAGE_FILTER false 30 | 31 | void compassBegin(); 32 | int16_t compassReadAngle(); 33 | int16_t compassGetAzimuth(); 34 | void compassCalibrateStart(); 35 | bool compassCalibrateLoop(); 36 | bool compassCalibrateDone(); 37 | 38 | #endif // __COMPASS_H__ 39 | 40 | -------------------------------------------------------------------------------- /examples/12_follow/compass.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMPASS_H__ 2 | #define __COMPASS_H__ 3 | 4 | #include 5 | 6 | /** Set the number of samples for average filtering 7 | * 8 | * default 30 9 | */ 10 | #define AVERAGE_FILTER_SIZE 30 11 | 12 | /** Set the EEPROM start address where the calibration value is stored 13 | * 14 | * default 0 15 | */ 16 | #define EEPROM_CALIBRATION_ADDRESS 0 17 | 18 | /** Set the time required for calibration values to stabilize 19 | * 20 | * uinit millisecond, default 3000 21 | */ 22 | #define CALIBRATION_TIME 3000 23 | 24 | /** Whether to turn on the average filter 25 | * 26 | * default true 27 | */ 28 | #define AVERAGE_FILTER true 29 | // #define AVERAGE_FILTER false 30 | 31 | void compassBegin(); 32 | int16_t compassReadAngle(); 33 | int16_t compassGetAzimuth(); 34 | void compassCalibrateStart(); 35 | bool compassCalibrateLoop(); 36 | bool compassCalibrateDone(); 37 | 38 | #endif // __COMPASS_H__ 39 | -------------------------------------------------------------------------------- /examples/7_compass/compass.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMPASS_H__ 2 | #define __COMPASS_H__ 3 | 4 | #include 5 | 6 | /** Set the number of samples for average filtering 7 | * 8 | * default 30 9 | */ 10 | #define AVERAGE_FILTER_SIZE 30 11 | 12 | /** Set the EEPROM start address where the calibration value is stored 13 | * 14 | * default 0 15 | */ 16 | #define EEPROM_CALIBRATION_ADDRESS 0 17 | 18 | /** Set the time required for calibration values to stabilize 19 | * 20 | * uinit millisecond, default 3000 21 | */ 22 | #define CALIBRATION_TIME 3000 23 | 24 | /** Whether to turn on the average filter 25 | * 26 | * default true 27 | */ 28 | #define AVERAGE_FILTER true 29 | // #define AVERAGE_FILTER false 30 | 31 | void compassBegin(); 32 | int16_t compassReadAngle(); 33 | int16_t compassGetAzimuth(); 34 | void compassCalibrateStart(); 35 | bool compassCalibrateLoop(); 36 | bool compassCalibrateDone(); 37 | 38 | #endif // __COMPASS_H__ 39 | -------------------------------------------------------------------------------- /examples/14_line_track/compass.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMPASS_H__ 2 | #define __COMPASS_H__ 3 | 4 | #include 5 | 6 | /** Set the number of samples for average filtering 7 | * 8 | * default 30 9 | */ 10 | #define AVERAGE_FILTER_SIZE 30 11 | 12 | /** Set the EEPROM start address where the calibration value is stored 13 | * 14 | * default 0 15 | */ 16 | #define EEPROM_CALIBRATION_ADDRESS 0 17 | 18 | /** Set the time required for calibration values to stabilize 19 | * 20 | * uinit millisecond, default 3000 21 | */ 22 | #define CALIBRATION_TIME 3000 23 | 24 | /** Whether to turn on the average filter 25 | * 26 | * default true 27 | */ 28 | #define AVERAGE_FILTER true 29 | // #define AVERAGE_FILTER false 30 | 31 | void compassBegin(); 32 | int16_t compassReadAngle(); 33 | int16_t compassGetAzimuth(); 34 | void compassCalibrateStart(); 35 | bool compassCalibrateLoop(); 36 | bool compassCalibrateDone(); 37 | 38 | #endif // __COMPASS_H__ 39 | -------------------------------------------------------------------------------- /examples/17_app_control/compass.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMPASS_H__ 2 | #define __COMPASS_H__ 3 | 4 | #include 5 | 6 | /** Set the number of samples for average filtering 7 | * 8 | * default 30 9 | */ 10 | #define AVERAGE_FILTER_SIZE 30 11 | 12 | /** Set the EEPROM start address where the calibration value is stored 13 | * 14 | * default 0 15 | */ 16 | #define EEPROM_CALIBRATION_ADDRESS 0 17 | 18 | /** Set the time required for calibration values to stabilize 19 | * 20 | * uinit millisecond, default 3000 21 | */ 22 | #define CALIBRATION_TIME 3000 23 | 24 | /** Whether to turn on the average filter 25 | * 26 | * default true 27 | */ 28 | #define AVERAGE_FILTER true 29 | // #define AVERAGE_FILTER false 30 | 31 | void compassBegin(); 32 | int16_t compassReadAngle(); 33 | int16_t compassGetAzimuth(); 34 | void compassCalibrateStart(); 35 | bool compassCalibrateLoop(); 36 | bool compassCalibrateDone(); 37 | 38 | #endif // __COMPASS_H__ 39 | -------------------------------------------------------------------------------- /examples/11_obstacle_avoid/compass.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMPASS_H__ 2 | #define __COMPASS_H__ 3 | 4 | #include 5 | 6 | /** Set the number of samples for average filtering 7 | * 8 | * default 30 9 | */ 10 | #define AVERAGE_FILTER_SIZE 30 11 | 12 | /** Set the EEPROM start address where the calibration value is stored 13 | * 14 | * default 0 15 | */ 16 | #define EEPROM_CALIBRATION_ADDRESS 0 17 | 18 | /** Set the time required for calibration values to stabilize 19 | * 20 | * uinit millisecond, default 3000 21 | */ 22 | #define CALIBRATION_TIME 3000 23 | 24 | /** Whether to turn on the average filter 25 | * 26 | * default true 27 | */ 28 | #define AVERAGE_FILTER true 29 | // #define AVERAGE_FILTER false 30 | 31 | void compassBegin(); 32 | int16_t compassReadAngle(); 33 | int16_t compassGetAzimuth(); 34 | void compassCalibrateStart(); 35 | bool compassCalibrateLoop(); 36 | bool compassCalibrateDone(); 37 | 38 | #endif // __COMPASS_H__ 39 | -------------------------------------------------------------------------------- /examples/18_app_control_plus/compass.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMPASS_H__ 2 | #define __COMPASS_H__ 3 | 4 | #include 5 | 6 | /** Set the number of samples for average filtering 7 | * 8 | * default 30 9 | */ 10 | #define AVERAGE_FILTER_SIZE 30 11 | 12 | /** Set the EEPROM start address where the calibration value is stored 13 | * 14 | * default 0 15 | */ 16 | #define EEPROM_CALIBRATION_ADDRESS 0 17 | 18 | /** Set the time required for calibration values to stabilize 19 | * 20 | * uinit millisecond, default 3000 21 | */ 22 | #define CALIBRATION_TIME 3000 23 | 24 | /** Whether to turn on the average filter 25 | * 26 | * default true 27 | */ 28 | #define AVERAGE_FILTER true 29 | // #define AVERAGE_FILTER false 30 | 31 | void compassBegin(); 32 | int16_t compassReadAngle(); 33 | int16_t compassGetAzimuth(); 34 | void compassCalibrateStart(); 35 | bool compassCalibrateLoop(); 36 | bool compassCalibrateDone(); 37 | 38 | #endif // __COMPASS_H__ 39 | -------------------------------------------------------------------------------- /examples/8_move_field_centric/compass.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMPASS_H__ 2 | #define __COMPASS_H__ 3 | 4 | #include 5 | 6 | /** Set the number of samples for average filtering 7 | * 8 | * default 30 9 | */ 10 | #define AVERAGE_FILTER_SIZE 30 11 | 12 | /** Set the EEPROM start address where the calibration value is stored 13 | * 14 | * default 0 15 | */ 16 | #define EEPROM_CALIBRATION_ADDRESS 0 17 | 18 | /** Set the time required for calibration values to stabilize 19 | * 20 | * uinit millisecond, default 3000 21 | */ 22 | #define CALIBRATION_TIME 3000 23 | 24 | /** Whether to turn on the average filter 25 | * 26 | * default true 27 | */ 28 | #define AVERAGE_FILTER true 29 | // #define AVERAGE_FILTER false 30 | 31 | void compassBegin(); 32 | int16_t compassReadAngle(); 33 | int16_t compassGetAzimuth(); 34 | void compassCalibrateStart(); 35 | bool compassCalibrateLoop(); 36 | bool compassCalibrateDone(); 37 | 38 | #endif // __COMPASS_H__ 39 | -------------------------------------------------------------------------------- /examples/15_line_track_field_centric/compass.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMPASS_H__ 2 | #define __COMPASS_H__ 3 | 4 | #include 5 | 6 | /** Set the number of samples for average filtering 7 | * 8 | * default 30 9 | */ 10 | #define AVERAGE_FILTER_SIZE 30 11 | 12 | /** Set the EEPROM start address where the calibration value is stored 13 | * 14 | * default 0 15 | */ 16 | #define EEPROM_CALIBRATION_ADDRESS 0 17 | 18 | /** Set the time required for calibration values to stabilize 19 | * 20 | * uinit millisecond, default 3000 21 | */ 22 | #define CALIBRATION_TIME 3000 23 | 24 | /** Whether to turn on the average filter 25 | * 26 | * default true 27 | */ 28 | #define AVERAGE_FILTER true 29 | // #define AVERAGE_FILTER false 30 | 31 | void compassBegin(); 32 | int16_t compassReadAngle(); 33 | int16_t compassGetAzimuth(); 34 | void compassCalibrateStart(); 35 | bool compassCalibrateLoop(); 36 | bool compassCalibrateDone(); 37 | 38 | #endif // __COMPASS_H__ 39 | -------------------------------------------------------------------------------- /examples/5_remote_control/car_control.h: -------------------------------------------------------------------------------- 1 | #ifndef __CAR_CONTROL_H__ 2 | #define __CAR_CONTROL_H__ 3 | 4 | #include 5 | 6 | /* 7 | * [0]--|||--[1] 8 | * | | 9 | * | | 10 | * | | 11 | * | | 12 | * [3]-------[2] 13 | */ 14 | 15 | /** Set the pins for the motors */ 16 | #define MOTOR_PINS (uint8_t[8]){3, 4, 5, 6, A3, A2, A1, A0} 17 | /** Set the positive and negative directions for the motors */ 18 | #define MOTOR_DIRECTIONS (uint8_t[4]){1, 0, 0, 1} 19 | 20 | 21 | void carBegin(); 22 | void carSetMotors(int8_t power0, int8_t power1, int8_t power2, int8_t power3); 23 | void carForward(int8_t power); 24 | void carBackward(int8_t power); 25 | void carTurnLeft(int8_t power); 26 | void carTurnRight(int8_t power); 27 | void carLeftForward(int8_t power); 28 | void carRightForward(int8_t power); 29 | void carLeftBackward(int8_t power); 30 | void carRightBackward(int8_t power); 31 | void carLeft(int8_t power); 32 | void carRight(int8_t power); 33 | void carStop(); 34 | void carMove(int16_t angle, int8_t power, int8_t rot=0, bool drift=false); 35 | 36 | 37 | #endif // __CAR_CONTROL_H__ 38 | 39 | -------------------------------------------------------------------------------- /Zeus_Car/grayscale.h: -------------------------------------------------------------------------------- 1 | #ifndef __GRAYSCALE_H__ 2 | #define __GRAYSCALE_H__ 3 | #include 4 | 5 | /** 6 | * @name Define the returned value of angle status detected by the 8-way grayscale module 7 | */ 8 | #define ANGLE_N45 0 9 | #define ANGLE_0 1 10 | #define ANGLE_45 2 11 | #define ANGLE_90 3 12 | #define ANGLE_ERROR 255 13 | 14 | /** 15 | * @name Define the returned value of angle offset status detected by the 8-way grayscale module 16 | */ 17 | #define OFFSET_N1 0 18 | #define OFFSET_0 1 19 | #define OFFSET_1 2 20 | #define OFFSET_ERROR 255 21 | 22 | /** 23 | * @brief init grayscale module 24 | */ 25 | void gsBegin(); 26 | 27 | /** 28 | * @brief Read the value of 8-way grayscale module 29 | * 30 | * @return byte eg:0b01001001 31 | */ 32 | byte gsRead(); 33 | 34 | /** 35 | * @brief Get the angle value and offset value of 8-way grayscale module 36 | * 37 | * @return uint16_t 38 | * 39 | * @code {.cpp} 40 | * uint16_t result = gsGetAngleOffset(); 41 | * uint8_t angleType = result >> 8 & 0xFF; 42 | * uint8_t offsetType = result & 0xFF; 43 | * @endcode 44 | * 45 | */ 46 | uint16_t gsGetAngleOffset(); 47 | 48 | #endif // __GRAYSCALE_H__ 49 | 50 | -------------------------------------------------------------------------------- /examples/14_line_track/grayscale.h: -------------------------------------------------------------------------------- 1 | #ifndef __GRAYSCALE_H__ 2 | #define __GRAYSCALE_H__ 3 | #include 4 | 5 | /** 6 | * @name Define the returned value of angle status detected by the 8-way grayscale module 7 | */ 8 | #define ANGLE_N45 0 9 | #define ANGLE_0 1 10 | #define ANGLE_45 2 11 | #define ANGLE_90 3 12 | #define ANGLE_ERROR 255 13 | 14 | /** 15 | * @name Define the returned value of angle offset status detected by the 8-way grayscale module 16 | */ 17 | #define OFFSET_N1 0 18 | #define OFFSET_0 1 19 | #define OFFSET_1 2 20 | #define OFFSET_ERROR 255 21 | 22 | /** 23 | * @brief init grayscale module 24 | */ 25 | void gsBegin(); 26 | 27 | /** 28 | * @brief Read the value of 8-way grayscale module 29 | * 30 | * @return byte eg:0b01001001 31 | */ 32 | byte gsRead(); 33 | 34 | /** 35 | * @brief Get the angle value and offset value of 8-way grayscale module 36 | * 37 | * @return uint16_t 38 | * 39 | * @code {.cpp} 40 | * uint16_t result = gsGetAngleOffset(); 41 | * uint8_t angleType = result >> 8 & 0xFF; 42 | * uint8_t offsetType = result & 0xFF; 43 | * @endcode 44 | * 45 | */ 46 | uint16_t gsGetAngleOffset(); 47 | 48 | #endif // __GRAYSCALE_H__ 49 | -------------------------------------------------------------------------------- /examples/18_app_control_plus/grayscale.h: -------------------------------------------------------------------------------- 1 | #ifndef __GRAYSCALE_H__ 2 | #define __GRAYSCALE_H__ 3 | #include 4 | 5 | /** 6 | * @name Define the returned value of angle status detected by the 8-way grayscale module 7 | */ 8 | #define ANGLE_N45 0 9 | #define ANGLE_0 1 10 | #define ANGLE_45 2 11 | #define ANGLE_90 3 12 | #define ANGLE_ERROR 255 13 | 14 | /** 15 | * @name Define the returned value of angle offset status detected by the 8-way grayscale module 16 | */ 17 | #define OFFSET_N1 0 18 | #define OFFSET_0 1 19 | #define OFFSET_1 2 20 | #define OFFSET_ERROR 255 21 | 22 | /** 23 | * @brief init grayscale module 24 | */ 25 | void gsBegin(); 26 | 27 | /** 28 | * @brief Read the value of 8-way grayscale module 29 | * 30 | * @return byte eg:0b01001001 31 | */ 32 | byte gsRead(); 33 | 34 | /** 35 | * @brief Get the angle value and offset value of 8-way grayscale module 36 | * 37 | * @return uint16_t 38 | * 39 | * @code {.cpp} 40 | * uint16_t result = gsGetAngleOffset(); 41 | * uint8_t angleType = result >> 8 & 0xFF; 42 | * uint8_t offsetType = result & 0xFF; 43 | * @endcode 44 | * 45 | */ 46 | uint16_t gsGetAngleOffset(); 47 | 48 | #endif // __GRAYSCALE_H__ 49 | -------------------------------------------------------------------------------- /examples/15_line_track_field_centric/grayscale.h: -------------------------------------------------------------------------------- 1 | #ifndef __GRAYSCALE_H__ 2 | #define __GRAYSCALE_H__ 3 | #include 4 | 5 | /** 6 | * @name Define the returned value of angle status detected by the 8-way grayscale module 7 | */ 8 | #define ANGLE_N45 0 9 | #define ANGLE_0 1 10 | #define ANGLE_45 2 11 | #define ANGLE_90 3 12 | #define ANGLE_ERROR 255 13 | 14 | /** 15 | * @name Define the returned value of angle offset status detected by the 8-way grayscale module 16 | */ 17 | #define OFFSET_N1 0 18 | #define OFFSET_0 1 19 | #define OFFSET_1 2 20 | #define OFFSET_ERROR 255 21 | 22 | /** 23 | * @brief init grayscale module 24 | */ 25 | void gsBegin(); 26 | 27 | /** 28 | * @brief Read the value of 8-way grayscale module 29 | * 30 | * @return byte eg:0b01001001 31 | */ 32 | byte gsRead(); 33 | 34 | /** 35 | * @brief Get the angle value and offset value of 8-way grayscale module 36 | * 37 | * @return uint16_t 38 | * 39 | * @code {.cpp} 40 | * uint16_t result = gsGetAngleOffset(); 41 | * uint8_t angleType = result >> 8 & 0xFF; 42 | * uint8_t offsetType = result & 0xFF; 43 | * @endcode 44 | * 45 | */ 46 | uint16_t gsGetAngleOffset(); 47 | 48 | #endif // __GRAYSCALE_H__ 49 | -------------------------------------------------------------------------------- /examples/12_follow/ultrasonic.cpp: -------------------------------------------------------------------------------- 1 | #include "ultrasonic.h" 2 | #include 3 | 4 | float ultrasonicRead() { 5 | delay(4); // A delay is required between consecutive readings, otherwise the reading may be 0 6 | 7 | pinMode(ULTRASONIC_TRIG_PIN, OUTPUT); 8 | digitalWrite(ULTRASONIC_TRIG_PIN, LOW); 9 | delayMicroseconds(2); 10 | digitalWrite(ULTRASONIC_TRIG_PIN, HIGH); 11 | delayMicroseconds(10); 12 | digitalWrite(ULTRASONIC_TRIG_PIN, LOW); 13 | pinMode(ULTRASONIC_ECHO_PIN, INPUT); 14 | 15 | // noInterrupts(); // Pause all interruptions to avoid affecting data 16 | // However,turning off interrupts affects the functionality of softpwm, such as motors 17 | 18 | float duration = pulseIn(ULTRASONIC_ECHO_PIN, HIGH); 19 | float distance = duration * 0.017; // S = vt = 340m/s * (t/2)us= (340 * 100 cm/s) * 0.5 * (t / 10^6)s = 0.017 * t 20 | 21 | // interrupts(); // resume interruptions 22 | 23 | if (distance > MAX_DISTANCE) { 24 | return -1; 25 | } 26 | return distance; 27 | } 28 | 29 | bool ultrasonicIsObstacle() { 30 | return ultrasonicRead() < ULTRASONIC_AVOIDANCE_THRESHOLD; 31 | } 32 | 33 | bool ultrasonicIsClear() { 34 | return ultrasonicRead() > ULTRASONIC_AVOIDANCE_THRESHOLD; 35 | } 36 | -------------------------------------------------------------------------------- /examples/11_obstacle_avoid/ultrasonic.cpp: -------------------------------------------------------------------------------- 1 | #include "ultrasonic.h" 2 | #include 3 | 4 | float ultrasonicRead() { 5 | delay(4); // A delay is required between consecutive readings, otherwise the reading may be 0 6 | 7 | pinMode(ULTRASONIC_TRIG_PIN, OUTPUT); 8 | digitalWrite(ULTRASONIC_TRIG_PIN, LOW); 9 | delayMicroseconds(2); 10 | digitalWrite(ULTRASONIC_TRIG_PIN, HIGH); 11 | delayMicroseconds(10); 12 | digitalWrite(ULTRASONIC_TRIG_PIN, LOW); 13 | pinMode(ULTRASONIC_ECHO_PIN, INPUT); 14 | 15 | // noInterrupts(); // Pause all interruptions to avoid affecting data 16 | // However,turning off interrupts affects the functionality of softpwm, such as motors 17 | 18 | float duration = pulseIn(ULTRASONIC_ECHO_PIN, HIGH); 19 | float distance = duration * 0.017; // S = vt = 340m/s * (t/2)us= (340 * 100 cm/s) * 0.5 * (t / 10^6)s = 0.017 * t 20 | 21 | // interrupts(); // resume interruptions 22 | 23 | if (distance > MAX_DISTANCE) { 24 | return -1; 25 | } 26 | return distance; 27 | } 28 | 29 | bool ultrasonicIsObstacle() { 30 | return ultrasonicRead() < ULTRASONIC_AVOIDANCE_THRESHOLD; 31 | } 32 | 33 | bool ultrasonicIsClear() { 34 | return ultrasonicRead() > ULTRASONIC_AVOIDANCE_THRESHOLD; 35 | } 36 | -------------------------------------------------------------------------------- /examples/18_app_control_plus/ultrasonic.cpp: -------------------------------------------------------------------------------- 1 | #include "ultrasonic.h" 2 | #include 3 | 4 | float ultrasonicRead() { 5 | delay(4); // A delay is required between consecutive readings, otherwise the reading may be 0 6 | 7 | pinMode(ULTRASONIC_TRIG_PIN, OUTPUT); 8 | digitalWrite(ULTRASONIC_TRIG_PIN, LOW); 9 | delayMicroseconds(2); 10 | digitalWrite(ULTRASONIC_TRIG_PIN, HIGH); 11 | delayMicroseconds(10); 12 | digitalWrite(ULTRASONIC_TRIG_PIN, LOW); 13 | pinMode(ULTRASONIC_ECHO_PIN, INPUT); 14 | 15 | // noInterrupts(); // Pause all interruptions to avoid affecting data 16 | // However,turning off interrupts affects the functionality of softpwm, such as motors 17 | 18 | float duration = pulseIn(ULTRASONIC_ECHO_PIN, HIGH); 19 | float distance = duration * 0.017; // S = vt = 340m/s * (t/2)us= (340 * 100 cm/s) * 0.5 * (t / 10^6)s = 0.017 * t 20 | 21 | // interrupts(); // resume interruptions 22 | 23 | if (distance > MAX_DISTANCE) { 24 | return -1; 25 | } 26 | return distance; 27 | } 28 | 29 | bool ultrasonicIsObstacle() { 30 | return ultrasonicRead() < ULTRASONIC_AVOIDANCE_THRESHOLD; 31 | } 32 | 33 | bool ultrasonicIsClear() { 34 | return ultrasonicRead() > ULTRASONIC_AVOIDANCE_THRESHOLD; 35 | } 36 | -------------------------------------------------------------------------------- /examples/12_follow/car_control.h: -------------------------------------------------------------------------------- 1 | #ifndef __CAR_CONTROL_H__ 2 | #define __CAR_CONTROL_H__ 3 | 4 | #include 5 | #include "compass.h" 6 | 7 | /* 8 | * [0]--|||--[1] 9 | * | | 10 | * | | 11 | * | | 12 | * | | 13 | * [3]-------[2] 14 | */ 15 | 16 | /** Set the pins for the motors */ 17 | #define MOTOR_PINS (uint8_t[8]){3, 4, 5, 6, A3, A2, A1, A0} 18 | /** Set the positive and negative directions for the motors */ 19 | #define MOTOR_DIRECTIONS (uint8_t[4]){1, 0, 0, 1} 20 | 21 | 22 | void carBegin(); 23 | void carSetMotors(int8_t power0, int8_t power1, int8_t power2, int8_t power3); 24 | void carForward(int8_t power); 25 | void carBackward(int8_t power); 26 | void carTurnLeft(int8_t power); 27 | void carTurnRight(int8_t power); 28 | void carLeftForward(int8_t power); 29 | void carRightForward(int8_t power); 30 | void carLeftBackward(int8_t power); 31 | void carRightBackward(int8_t power); 32 | void carLeft(int8_t power); 33 | void carRight(int8_t power); 34 | void carStop(); 35 | void carMove(int16_t angle, int8_t power, int8_t rot=0, bool drift=false); 36 | void carMoveFieldCentric(int16_t angle, int8_t power, int16_t heading=0, bool drift=false); 37 | void carResetHeading(); 38 | 39 | #endif // __CAR_CONTROL_H__ 40 | -------------------------------------------------------------------------------- /examples/14_line_track/car_control.h: -------------------------------------------------------------------------------- 1 | #ifndef __CAR_CONTROL_H__ 2 | #define __CAR_CONTROL_H__ 3 | 4 | #include 5 | #include "compass.h" 6 | 7 | /* 8 | * [0]--|||--[1] 9 | * | | 10 | * | | 11 | * | | 12 | * | | 13 | * [3]-------[2] 14 | */ 15 | 16 | /** Set the pins for the motors */ 17 | #define MOTOR_PINS (uint8_t[8]){3, 4, 5, 6, A3, A2, A1, A0} 18 | /** Set the positive and negative directions for the motors */ 19 | #define MOTOR_DIRECTIONS (uint8_t[4]){1, 0, 0, 1} 20 | 21 | 22 | void carBegin(); 23 | void carSetMotors(int8_t power0, int8_t power1, int8_t power2, int8_t power3); 24 | void carForward(int8_t power); 25 | void carBackward(int8_t power); 26 | void carTurnLeft(int8_t power); 27 | void carTurnRight(int8_t power); 28 | void carLeftForward(int8_t power); 29 | void carRightForward(int8_t power); 30 | void carLeftBackward(int8_t power); 31 | void carRightBackward(int8_t power); 32 | void carLeft(int8_t power); 33 | void carRight(int8_t power); 34 | void carStop(); 35 | void carMove(int16_t angle, int8_t power, int8_t rot=0, bool drift=false); 36 | void carMoveFieldCentric(int16_t angle, int8_t power, int16_t heading=0, bool drift=false); 37 | void carResetHeading(); 38 | 39 | #endif // __CAR_CONTROL_H__ 40 | -------------------------------------------------------------------------------- /examples/11_obstacle_avoid/car_control.h: -------------------------------------------------------------------------------- 1 | #ifndef __CAR_CONTROL_H__ 2 | #define __CAR_CONTROL_H__ 3 | 4 | #include 5 | #include "compass.h" 6 | 7 | /* 8 | * [0]--|||--[1] 9 | * | | 10 | * | | 11 | * | | 12 | * | | 13 | * [3]-------[2] 14 | */ 15 | 16 | /** Set the pins for the motors */ 17 | #define MOTOR_PINS (uint8_t[8]){3, 4, 5, 6, A3, A2, A1, A0} 18 | /** Set the positive and negative directions for the motors */ 19 | #define MOTOR_DIRECTIONS (uint8_t[4]){1, 0, 0, 1} 20 | 21 | 22 | void carBegin(); 23 | void carSetMotors(int8_t power0, int8_t power1, int8_t power2, int8_t power3); 24 | void carForward(int8_t power); 25 | void carBackward(int8_t power); 26 | void carTurnLeft(int8_t power); 27 | void carTurnRight(int8_t power); 28 | void carLeftForward(int8_t power); 29 | void carRightForward(int8_t power); 30 | void carLeftBackward(int8_t power); 31 | void carRightBackward(int8_t power); 32 | void carLeft(int8_t power); 33 | void carRight(int8_t power); 34 | void carStop(); 35 | void carMove(int16_t angle, int8_t power, int8_t rot=0, bool drift=false); 36 | void carMoveFieldCentric(int16_t angle, int8_t power, int16_t heading=0, bool drift=false); 37 | void carResetHeading(); 38 | 39 | #endif // __CAR_CONTROL_H__ 40 | -------------------------------------------------------------------------------- /Zeus_Car/rgb.h: -------------------------------------------------------------------------------- 1 | #ifndef __RGB_H__ 2 | #define __RGB_H__ 3 | 4 | #include 5 | 6 | /** Indicate whether RGB leds are common-anodes or not 7 | * - 0 common cathode 8 | * - 1 common anode 9 | */ 10 | #define COMMON_ANODE 0 11 | 12 | /** Set the pins of RGB leds, the order is R,G,B */ 13 | #define RGB_PINS (uint8_t[3]){12, 13, 11} 14 | 15 | /** 16 | *@name Defines the hexadecimal value of the color 17 | */ 18 | #define RED 0xFF0202 19 | #define ORANGE 0xFFA500 20 | #define YELLOW 0xFFFF0A 21 | #define YELLOW_GREEN 0xA5FF0A 22 | #define GREEN 0x0AFF0A 23 | #define GREEN_CYAN 0x0AFFA5 24 | #define CYAN 0x0AFFFF 25 | #define CYAN_BLUE 0x0AA5FF 26 | #define BLUE 0x0A0AFF 27 | #define PURPLE 0xA50AFF 28 | #define VOILET 0xFF0AFF 29 | #define MAGENTA 0xFF0AA5 30 | 31 | /* Calibrate brightness */ 32 | #define R_OFFSET 1.0 33 | #define G_OFFSET 0.16 34 | #define B_OFFSET 0.30 35 | 36 | /** Initialize RGB leds */ 37 | void rgbBegin(); 38 | 39 | /** Set LED color in HEX */ 40 | void rgbWrite(uint32_t color); 41 | 42 | /** Set LED color in 8bit R,G,B (0 ~ 255)*/ 43 | void rgbWrite(uint8_t r, uint8_t g, uint8_t b); 44 | 45 | /** Turn odd RGB LEDs*/ 46 | void rgbOff(); 47 | 48 | #endif // __RGB_H__ 49 | 50 | -------------------------------------------------------------------------------- /examples/15_line_track_field_centric/car_control.h: -------------------------------------------------------------------------------- 1 | #ifndef __CAR_CONTROL_H__ 2 | #define __CAR_CONTROL_H__ 3 | 4 | #include 5 | #include "compass.h" 6 | 7 | /* 8 | * [0]--|||--[1] 9 | * | | 10 | * | | 11 | * | | 12 | * | | 13 | * [3]-------[2] 14 | */ 15 | 16 | /** Set the pins for the motors */ 17 | #define MOTOR_PINS (uint8_t[8]){3, 4, 5, 6, A3, A2, A1, A0} 18 | /** Set the positive and negative directions for the motors */ 19 | #define MOTOR_DIRECTIONS (uint8_t[4]){1, 0, 0, 1} 20 | 21 | 22 | void carBegin(); 23 | void carSetMotors(int8_t power0, int8_t power1, int8_t power2, int8_t power3); 24 | void carForward(int8_t power); 25 | void carBackward(int8_t power); 26 | void carTurnLeft(int8_t power); 27 | void carTurnRight(int8_t power); 28 | void carLeftForward(int8_t power); 29 | void carRightForward(int8_t power); 30 | void carLeftBackward(int8_t power); 31 | void carRightBackward(int8_t power); 32 | void carLeft(int8_t power); 33 | void carRight(int8_t power); 34 | void carStop(); 35 | void carMove(int16_t angle, int8_t power, int8_t rot=0, bool drift=false); 36 | void carMoveFieldCentric(int16_t angle, int8_t power, int16_t heading=0, bool drift=false); 37 | void carResetHeading(); 38 | 39 | #endif // __CAR_CONTROL_H__ 40 | -------------------------------------------------------------------------------- /examples/7_compass/car_control.h: -------------------------------------------------------------------------------- 1 | #ifndef __CAR_CONTROL_H__ 2 | #define __CAR_CONTROL_H__ 3 | 4 | #include 5 | #include 6 | #include "compass.h" 7 | 8 | /* 9 | * [0]--|||--[1] 10 | * | | 11 | * | | 12 | * | | 13 | * | | 14 | * [3]-------[2] 15 | */ 16 | 17 | /** Set the pins for the motors */ 18 | #define MOTOR_PINS (uint8_t[8]){3, 4, 5, 6, A3, A2, A1, A0} 19 | /** Set the positive and negative directions for the motors */ 20 | #define MOTOR_DIRECTIONS (uint8_t[4]){1, 0, 0, 1} 21 | 22 | 23 | void carBegin(); 24 | void carSetMotors(int8_t power0, int8_t power1, int8_t power2, int8_t power3); 25 | void carForward(int8_t power); 26 | void carBackward(int8_t power); 27 | void carTurnLeft(int8_t power); 28 | void carTurnRight(int8_t power); 29 | void carLeftForward(int8_t power); 30 | void carRightForward(int8_t power); 31 | void carLeftBackward(int8_t power); 32 | void carRightBackward(int8_t power); 33 | void carLeft(int8_t power); 34 | void carRight(int8_t power); 35 | void carStop(); 36 | void carMove(int16_t angle, int8_t power, int8_t rot=0, bool drift=false); 37 | void carMoveFieldCentric(int16_t angle, int8_t power, int16_t heading=0, bool drift=false); 38 | void carResetHeading(); 39 | 40 | #endif // __CAR_CONTROL_H__ 41 | -------------------------------------------------------------------------------- /examples/8_move_field_centric/car_control.h: -------------------------------------------------------------------------------- 1 | #ifndef __CAR_CONTROL_H__ 2 | #define __CAR_CONTROL_H__ 3 | 4 | #include 5 | #include "compass.h" 6 | #include 7 | 8 | /* 9 | * [0]--|||--[1] 10 | * | | 11 | * | | 12 | * | | 13 | * | | 14 | * [3]-------[2] 15 | */ 16 | 17 | /** Set the pins for the motors */ 18 | #define MOTOR_PINS (uint8_t[8]){3, 4, 5, 6, A3, A2, A1, A0} 19 | /** Set the positive and negative directions for the motors */ 20 | #define MOTOR_DIRECTIONS (uint8_t[4]){1, 0, 0, 1} 21 | 22 | 23 | void carBegin(); 24 | void carSetMotors(int8_t power0, int8_t power1, int8_t power2, int8_t power3); 25 | void carForward(int8_t power); 26 | void carBackward(int8_t power); 27 | void carTurnLeft(int8_t power); 28 | void carTurnRight(int8_t power); 29 | void carLeftForward(int8_t power); 30 | void carRightForward(int8_t power); 31 | void carLeftBackward(int8_t power); 32 | void carRightBackward(int8_t power); 33 | void carLeft(int8_t power); 34 | void carRight(int8_t power); 35 | void carStop(); 36 | void carMove(int16_t angle, int8_t power, int8_t rot=0, bool drift=false); 37 | void carMoveFieldCentric(int16_t angle, int8_t power, int16_t heading=0, bool drift=false); 38 | void carResetHeading(); 39 | 40 | #endif // __CAR_CONTROL_H__ 41 | -------------------------------------------------------------------------------- /Zeus_Car/ultrasonic.cpp: -------------------------------------------------------------------------------- 1 | #include "ultrasonic.h" 2 | #include 3 | 4 | float ultrasonicRead() { 5 | delay(4); // A delay is required between consecutive readings, otherwise the reading may be 0 6 | 7 | pinMode(ULTRASONIC_TRIG_PIN, OUTPUT); 8 | digitalWrite(ULTRASONIC_TRIG_PIN, LOW); 9 | delayMicroseconds(2); 10 | digitalWrite(ULTRASONIC_TRIG_PIN, HIGH); 11 | delayMicroseconds(10); 12 | digitalWrite(ULTRASONIC_TRIG_PIN, LOW); 13 | pinMode(ULTRASONIC_ECHO_PIN, INPUT); 14 | 15 | // noInterrupts(); // Pause all interruptions to avoid affecting data 16 | // However,turning off interrupts affects the functionality of softpwm, such as motors 17 | 18 | float duration = pulseIn(ULTRASONIC_ECHO_PIN, HIGH); 19 | float distance = duration * 0.017; // S = vt = 340m/s * (t/2)us= (340 * 100 cm/s) * 0.5 * (t / 10^6)s = 0.017 * t 20 | 21 | // interrupts(); // resume interruptions 22 | 23 | if (distance > MAX_DISTANCE) { 24 | return -1; 25 | } 26 | return distance; 27 | } 28 | 29 | bool ultrasonicIsObstacle() { 30 | return ultrasonicRead() < ULTRASONIC_AVOIDANCE_THRESHOLD; 31 | } 32 | 33 | bool ultrasonicIsClear() { 34 | float distance = ultrasonicRead(); 35 | if (distance > ULTRASONIC_AVOIDANCE_THRESHOLD || distance < 0) { 36 | return true; 37 | } else { 38 | return false; 39 | } 40 | } -------------------------------------------------------------------------------- /examples/17_app_control/car_control.h: -------------------------------------------------------------------------------- 1 | #ifndef __CAR_CONTROL_H__ 2 | #define __CAR_CONTROL_H__ 3 | 4 | #include 5 | #include "compass.h" 6 | 7 | /* 8 | * [0]--|||--[1] 9 | * | | 10 | * | | 11 | * | | 12 | * | | 13 | * [3]-------[2] 14 | */ 15 | 16 | /** Set the pins for the motors */ 17 | #define MOTOR_PINS (uint8_t[8]){3, 4, 5, 6, A3, A2, A1, A0} 18 | /** Set the positive and negative directions for the motors */ 19 | #define MOTOR_DIRECTIONS (uint8_t[4]){1, 0, 0, 1} 20 | 21 | /** define motors default speed */ 22 | #define CAR_DEFAULT_POWER 80 23 | 24 | 25 | void carBegin(); 26 | void carSetMotors(int8_t power0, int8_t power1, int8_t power2, int8_t power3); 27 | void carForward(int8_t power); 28 | void carBackward(int8_t power); 29 | void carTurnLeft(int8_t power); 30 | void carTurnRight(int8_t power); 31 | void carLeftForward(int8_t power); 32 | void carRightForward(int8_t power); 33 | void carLeftBackward(int8_t power); 34 | void carRightBackward(int8_t power); 35 | void carLeft(int8_t power); 36 | void carRight(int8_t power); 37 | void carStop(); 38 | void carMove(int16_t angle, int8_t power, int8_t rot=0, bool drift=false); 39 | void carMoveFieldCentric(int16_t angle, int8_t power, int16_t heading=0, bool drift=false); 40 | void carResetHeading(); 41 | 42 | #endif // __CAR_CONTROL_H__ 43 | -------------------------------------------------------------------------------- /examples/18_app_control_plus/car_control.h: -------------------------------------------------------------------------------- 1 | #ifndef __CAR_CONTROL_H__ 2 | #define __CAR_CONTROL_H__ 3 | 4 | #include 5 | #include "compass.h" 6 | 7 | /* 8 | * [0]--|||--[1] 9 | * | | 10 | * | | 11 | * | | 12 | * | | 13 | * [3]-------[2] 14 | */ 15 | 16 | /** Set the pins for the motors */ 17 | #define MOTOR_PINS (uint8_t[8]){3, 4, 5, 6, A3, A2, A1, A0} 18 | /** Set the positive and negative directions for the motors */ 19 | #define MOTOR_DIRECTIONS (uint8_t[4]){1, 0, 0, 1} 20 | 21 | /** define motors default speed */ 22 | #define CAR_DEFAULT_POWER 80 23 | 24 | 25 | void carBegin(); 26 | void carSetMotors(int8_t power0, int8_t power1, int8_t power2, int8_t power3); 27 | void carForward(int8_t power); 28 | void carBackward(int8_t power); 29 | void carTurnLeft(int8_t power); 30 | void carTurnRight(int8_t power); 31 | void carLeftForword(int8_t power); 32 | void carRightForword(int8_t power); 33 | void carLeftBackward(int8_t power); 34 | void carRightBackward(int8_t power); 35 | void carLeft(int8_t power); 36 | void carRight(int8_t power); 37 | void carStop(); 38 | void carMove(int16_t angle, int8_t power, int8_t rot=0, bool drift=false); 39 | void carMoveFieldCentric(int16_t angle, int8_t power, int16_t heading=0, bool drift=false); 40 | void carResetHeading(); 41 | 42 | #endif // __CAR_CONTROL_H__ 43 | -------------------------------------------------------------------------------- /Zeus_Car/car_control.h: -------------------------------------------------------------------------------- 1 | #ifndef __CAR_CONTROL_H__ 2 | #define __CAR_CONTROL_H__ 3 | 4 | #include 5 | #include "compass.h" 6 | 7 | /* 8 | * [0]--|||--[1] 9 | * | | 10 | * | | 11 | * | | 12 | * | | 13 | * [3]-------[2] 14 | */ 15 | 16 | /** Set the pins for the motors */ 17 | #define MOTOR_PINS (uint8_t[8]){3, 4, 5, 6, A3, A2, A1, A0} 18 | /** Set the positive and negative directions for the motors */ 19 | #define MOTOR_DIRECTIONS (uint8_t[4]){1, 0, 0, 1} 20 | 21 | /** define motors default speed */ 22 | #define CAR_DEFAULT_POWER 80 23 | 24 | 25 | void carBegin(); 26 | void carSetMotors(int8_t power0, int8_t power1, int8_t power2, int8_t power3); 27 | void carForward(int8_t power); 28 | void carBackward(int8_t power); 29 | void carTurnLeft(int8_t power); 30 | void carTurnRight(int8_t power); 31 | void carLeftForword(int8_t power); 32 | void carRightForword(int8_t power); 33 | void carLeftBackward(int8_t power); 34 | void carRightBackward(int8_t power); 35 | void carLeft(int8_t power); 36 | void carRight(int8_t power); 37 | void carStop(); 38 | void carMove(int16_t angle, int8_t power, int8_t rot=0, bool drift=false); 39 | void carMoveFieldCentric(int16_t angle, int8_t power, int16_t heading=0, bool drift=false, bool angFlag=false); 40 | void carResetHeading(); 41 | 42 | #endif // __CAR_CONTROL_H__ 43 | 44 | -------------------------------------------------------------------------------- /examples/13_hc165_and_grayscale/13_hc165_and_grayscale.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | * hc165_and_grayscale 3 | 4 | Read the value of 8-channel grayscale module 5 | 6 | - Due to the lack of IO, the car uses two 3-to-8 io expansion chips HC165 to connect 7 | two IR obstacle avoidance modules and one 8-channel grayscale module 8 | - Two IR obstacle avoidance modules use the lower two io 9 | The 8-channel grayscale module uses the high 8-bit io 10 | 11 | ******************************************************************/ 12 | #include 13 | #include "hc165.h" 14 | 15 | void setup() { 16 | Serial.begin(115200); 17 | gsBegin(); 18 | } 19 | 20 | void loop() { 21 | byte data = gsRead(); 22 | /* A certain light of the module is on, the corresponding io becomes low level, and the bit value is 0 */ 23 | Serial.print("data: "); 24 | for(int i = 7;i>=0;i--){ 25 | if(data & (1<> 8 & 0xFF; 47 | } 48 | -------------------------------------------------------------------------------- /Zeus_Car/ir_remote.h: -------------------------------------------------------------------------------- 1 | #ifndef __IR_REMOTE_H__ 2 | #define __IR_REMOTE_H__ 3 | 4 | #include 5 | 6 | /** @name set pin of IR RECEIVER sensor*/ 7 | #define IR_RECEIVER_PIN 2 8 | 9 | /** @name Define the code sent by the IR remote control keys 10 | */ 11 | //@{ 12 | #define IR_KEY_POWER 0x45 13 | #define IR_KEY_MODE 0x46 14 | #define IR_KEY_MUTE 0x47 15 | 16 | #define IR_KEY_PLAY_PAUSE 0x44 17 | #define IR_KEY_BACKWARD 0x40 18 | #define IR_KEY_FORWARD 0x43 19 | 20 | #define IR_KEY_EQ 0x07 21 | #define IR_KEY_MINUS 0x15 22 | #define IR_KEY_PLUS 0x09 23 | 24 | #define IR_KEY_0 0x16 25 | #define IR_KEY_CYCLE 0x19 26 | #define IR_KEY_U_SD 0x0D 27 | 28 | #define IR_KEY_1 0x0C 29 | #define IR_KEY_2 0x18 30 | #define IR_KEY_3 0x5E 31 | 32 | #define IR_KEY_4 0x08 33 | #define IR_KEY_5 0x1C 34 | #define IR_KEY_6 0x5A 35 | 36 | #define IR_KEY_7 0x42 37 | #define IR_KEY_8 0x52 38 | #define IR_KEY_9 0x4A 39 | 40 | #define IR_KEY_ERROR 0x00 41 | //@} 42 | 43 | /** 44 | * @brief IRremote init 45 | */ 46 | void irBegin(); 47 | 48 | /** 49 | * @brief Read the code received by IR 50 | * 51 | * @code {.cpp} 52 | * uint8_t key = irRead(); 53 | * Serial.print('IR recv code:'); 54 | * Serial.print(key); 55 | * if (key == IR_KEY_POWER) { 56 | * Serial.println("IR_KEY_POWER"); 57 | * } 58 | * @endcode 59 | * 60 | * @return uint8_t 61 | * 62 | */ 63 | uint8_t irRead(); 64 | 65 | #endif // __IR_REMOTE_H__ 66 | 67 | -------------------------------------------------------------------------------- /examples/7_compass/ir_remote.h: -------------------------------------------------------------------------------- 1 | #ifndef __IR_REMOTE_H__ 2 | #define __IR_REMOTE_H__ 3 | 4 | #include 5 | 6 | /** @name set pin of IR RECEIVER sensor*/ 7 | #define IR_RECEIVER_PIN 2 8 | 9 | /** @name Define the code sent by the IR remote control keys 10 | */ 11 | //@{ 12 | #define IR_KEY_POWER 0x45 13 | #define IR_KEY_MODE 0x46 14 | #define IR_KEY_MUTE 0x47 15 | 16 | #define IR_KEY_PLAY_PAUSE 0x44 17 | #define IR_KEY_BACKWARD 0x40 18 | #define IR_KEY_FORWARD 0x43 19 | 20 | #define IR_KEY_EQ 0x07 21 | #define IR_KEY_MINUS 0x15 22 | #define IR_KEY_PLUS 0x09 23 | 24 | #define IR_KEY_0 0x16 25 | #define IR_KEY_CYCLE 0x19 26 | #define IR_KEY_U_SD 0x0D 27 | 28 | #define IR_KEY_1 0x0C 29 | #define IR_KEY_2 0x18 30 | #define IR_KEY_3 0x5E 31 | 32 | #define IR_KEY_4 0x08 33 | #define IR_KEY_5 0x1C 34 | #define IR_KEY_6 0x5A 35 | 36 | #define IR_KEY_7 0x42 37 | #define IR_KEY_8 0x52 38 | #define IR_KEY_9 0x4A 39 | 40 | #define IR_KEY_ERROR 0x00 41 | //@} 42 | 43 | /** 44 | * @brief IRremote init 45 | */ 46 | void irBegin(); 47 | 48 | /** 49 | * @brief Read the code received by IR 50 | * 51 | * @code {.cpp} 52 | * uint8_t key = irRead(); 53 | * Serial.print('IR recv code:'); 54 | * Serial.print(key); 55 | * if (key == IR_KEY_POWER) { 56 | * Serial.println("IR_KEY_POWER"); 57 | * } 58 | * @endcode 59 | * 60 | * @return uint8_t 61 | * 62 | */ 63 | uint8_t irRead(); 64 | 65 | #endif // __IR_REMOTE_H__ 66 | -------------------------------------------------------------------------------- /examples/6_car_light/ir_remote.h: -------------------------------------------------------------------------------- 1 | #ifndef __IR_REMOTE_H__ 2 | #define __IR_REMOTE_H__ 3 | 4 | #include 5 | 6 | /** @name set pin of IR RECEIVER sensor*/ 7 | #define IR_RECEIVER_PIN 2 8 | 9 | /** @name Define the code sent by the IR remote control keys 10 | */ 11 | //@{ 12 | #define IR_KEY_POWER 0x45 13 | #define IR_KEY_MODE 0x46 14 | #define IR_KEY_MUTE 0x47 15 | 16 | #define IR_KEY_PLAY_PAUSE 0x44 17 | #define IR_KEY_BACKWARD 0x40 18 | #define IR_KEY_FORWARD 0x43 19 | 20 | #define IR_KEY_EQ 0x07 21 | #define IR_KEY_MINUS 0x15 22 | #define IR_KEY_PLUS 0x09 23 | 24 | #define IR_KEY_0 0x16 25 | #define IR_KEY_CYCLE 0x19 26 | #define IR_KEY_U_SD 0x0D 27 | 28 | #define IR_KEY_1 0x0C 29 | #define IR_KEY_2 0x18 30 | #define IR_KEY_3 0x5E 31 | 32 | #define IR_KEY_4 0x08 33 | #define IR_KEY_5 0x1C 34 | #define IR_KEY_6 0x5A 35 | 36 | #define IR_KEY_7 0x42 37 | #define IR_KEY_8 0x52 38 | #define IR_KEY_9 0x4A 39 | 40 | #define IR_KEY_ERROR 0x00 41 | //@} 42 | 43 | /** 44 | * @brief IRremote init 45 | */ 46 | void irBegin(); 47 | 48 | /** 49 | * @brief Read the code received by IR 50 | * 51 | * @code {.cpp} 52 | * uint8_t key = irRead(); 53 | * Serial.print('IR recv code:'); 54 | * Serial.print(key); 55 | * if (key == IR_KEY_POWER) { 56 | * Serial.println("IR_KEY_POWER"); 57 | * } 58 | * @endcode 59 | * 60 | * @return uint8_t 61 | * 62 | */ 63 | uint8_t irRead(); 64 | 65 | #endif // __IR_REMOTE_H__ 66 | 67 | -------------------------------------------------------------------------------- /examples/5_remote_control/ir_remote.h: -------------------------------------------------------------------------------- 1 | #ifndef __IR_REMOTE_H__ 2 | #define __IR_REMOTE_H__ 3 | 4 | #include 5 | 6 | /** @name set pin of IR RECEIVER sensor*/ 7 | #define IR_RECEIVER_PIN 2 8 | 9 | /** @name Define the code sent by the IR remote control keys 10 | */ 11 | //@{ 12 | #define IR_KEY_POWER 0x45 13 | #define IR_KEY_MODE 0x46 14 | #define IR_KEY_MUTE 0x47 15 | 16 | #define IR_KEY_PLAY_PAUSE 0x44 17 | #define IR_KEY_BACKWARD 0x40 18 | #define IR_KEY_FORWARD 0x43 19 | 20 | #define IR_KEY_EQ 0x07 21 | #define IR_KEY_MINUS 0x15 22 | #define IR_KEY_PLUS 0x09 23 | 24 | #define IR_KEY_0 0x16 25 | #define IR_KEY_CYCLE 0x19 26 | #define IR_KEY_U_SD 0x0D 27 | 28 | #define IR_KEY_1 0x0C 29 | #define IR_KEY_2 0x18 30 | #define IR_KEY_3 0x5E 31 | 32 | #define IR_KEY_4 0x08 33 | #define IR_KEY_5 0x1C 34 | #define IR_KEY_6 0x5A 35 | 36 | #define IR_KEY_7 0x42 37 | #define IR_KEY_8 0x52 38 | #define IR_KEY_9 0x4A 39 | 40 | #define IR_KEY_ERROR 0x00 41 | //@} 42 | 43 | /** 44 | * @brief IRremote init 45 | */ 46 | void irBegin(); 47 | 48 | /** 49 | * @brief Read the code received by IR 50 | * 51 | * @code {.cpp} 52 | * uint8_t key = irRead(); 53 | * Serial.print('IR recv code:'); 54 | * Serial.print(key); 55 | * if (key == IR_KEY_POWER) { 56 | * Serial.println("IR_KEY_POWER"); 57 | * } 58 | * @endcode 59 | * 60 | * @return uint8_t 61 | * 62 | */ 63 | uint8_t irRead(); 64 | 65 | #endif // __IR_REMOTE_H__ 66 | 67 | -------------------------------------------------------------------------------- /examples/8_move_field_centric/ir_remote.h: -------------------------------------------------------------------------------- 1 | #ifndef __IR_REMOTE_H__ 2 | #define __IR_REMOTE_H__ 3 | 4 | #include 5 | 6 | /** @name set pin of IR RECEIVER sensor*/ 7 | #define IR_RECEIVER_PIN 2 8 | 9 | /** @name Define the code sent by the IR remote control keys 10 | */ 11 | //@{ 12 | #define IR_KEY_POWER 0x45 13 | #define IR_KEY_MODE 0x46 14 | #define IR_KEY_MUTE 0x47 15 | 16 | #define IR_KEY_PLAY_PAUSE 0x44 17 | #define IR_KEY_BACKWARD 0x40 18 | #define IR_KEY_FORWARD 0x43 19 | 20 | #define IR_KEY_EQ 0x07 21 | #define IR_KEY_MINUS 0x15 22 | #define IR_KEY_PLUS 0x09 23 | 24 | #define IR_KEY_0 0x16 25 | #define IR_KEY_CYCLE 0x19 26 | #define IR_KEY_U_SD 0x0D 27 | 28 | #define IR_KEY_1 0x0C 29 | #define IR_KEY_2 0x18 30 | #define IR_KEY_3 0x5E 31 | 32 | #define IR_KEY_4 0x08 33 | #define IR_KEY_5 0x1C 34 | #define IR_KEY_6 0x5A 35 | 36 | #define IR_KEY_7 0x42 37 | #define IR_KEY_8 0x52 38 | #define IR_KEY_9 0x4A 39 | 40 | #define IR_KEY_ERROR 0x00 41 | //@} 42 | 43 | /** 44 | * @brief IRremote init 45 | */ 46 | void irBegin(); 47 | 48 | /** 49 | * @brief Read the code received by IR 50 | * 51 | * @code {.cpp} 52 | * uint8_t key = irRead(); 53 | * Serial.print('IR recv code:'); 54 | * Serial.print(key); 55 | * if (key == IR_KEY_POWER) { 56 | * Serial.println("IR_KEY_POWER"); 57 | * } 58 | * @endcode 59 | * 60 | * @return uint8_t 61 | * 62 | */ 63 | uint8_t irRead(); 64 | 65 | #endif // __IR_REMOTE_H__ 66 | -------------------------------------------------------------------------------- /examples/18_app_control_plus/common_definition.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARDUINO_CAR_H__ 2 | #define __ARDUINO_CAR_H__ 3 | 4 | /** 5 | * @name Mode Value Definition 6 | */ 7 | #define MODE_NONE 0 8 | #define MODE_LINE_TRACK 1 9 | #define MODE_ROTATE_LINE_FOLLOWING 2 10 | #define MODE_OBSTACLE_FOLLOWING 3 11 | #define MODE_OBSTACLE_AVOIDANCE 4 12 | #define MODE_REMOTE_CONTROL 5 13 | #define MODE_APP_CONTROL 6 14 | #define MODE_COMPASS_CALIBRATION 7 15 | 16 | /** 17 | *@name Defines the hexadecimal value of the color 18 | */ 19 | #define RED 0xFF0A0A 20 | #define ORANGE 0xFF2500 //0xFFA500 21 | #define YELLOW 0xFFFF0A 22 | #define YELLOW_GREEN 0xA5FF0A 23 | #define GREEN 0x0AFF0A 24 | #define GREEN_CYAN 0x0AFFA5 25 | #define CYAN 0x0AFFFF 26 | #define CYAN_BLUE 0x0AA5FF 27 | #define BLUE 0x0A0AFF 28 | #define PURPLE 0xA50AFF 29 | #define VOILET 0xFF0AFF 30 | #define MAGENTA 0xFF0AA5 31 | 32 | /** 33 | * @name Set the color to match the mode 34 | */ 35 | #define MODE_NONE_COLOR GREEN_CYAN 36 | #define MODE_LINE_TRACK_COLOR CYAN 37 | #define MODE_ROTATE_LINE_FOLLOWING_COLOR CYAN_BLUE 38 | #define MODE_OBSTACLE_FOLLOWING_COLOR BLUE 39 | #define MODE_OBSTACLE_AVOIDANCE_COLOR PURPLE 40 | #define MODE_REMOTE_CONTROL_COLOR VOILET 41 | #define MODE_APP_CONTROL_COLOR MAGENTA 42 | 43 | #endif // __ARDUINO_CAR_H__ 44 | -------------------------------------------------------------------------------- /examples/12_follow/12_follow.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | * follow 3 | 4 | Follow the object 5 | using ultrasonic module and two infrared obstacle avoidance modules 6 | 7 | - Before use, you need to adjust the distance reference knob of 8 | the two IR obstacle avoidance modules to the appropriate position 9 | 10 | ******************************************************************/ 11 | #include 12 | #include "car_control.h" 13 | #include "ir_obstacle.h" 14 | #include "ultrasonic.h" 15 | 16 | #define FOLLOW_DISTANCE 20 17 | 18 | int8_t power = 80; 19 | int8_t rotate_power = 50; 20 | bool leftIsClear = false; 21 | bool rightIsClear = false; 22 | bool middleIsClear = false; 23 | 24 | void setup() { 25 | Serial.begin(115200); 26 | Serial.println("Zeus Car auto follow"); 27 | carBegin(); 28 | irObstacleBegin(); 29 | } 30 | 31 | void loop() { 32 | byte result = irObstacleRead(); 33 | leftIsClear = result & 0b00000001; 34 | rightIsClear = result & 0b00000010; 35 | 36 | float usDistance = ultrasonicRead(); 37 | Serial.print("usDistance:");Serial.print(usDistance); 38 | Serial.print(" leftIsClear:");Serial.print(leftIsClear); 39 | Serial.print(" rightIsClear:");Serial.println(rightIsClear); 40 | 41 | if (usDistance < 4) { 42 | carStop(); 43 | } else if (usDistance < 10) { 44 | carForward(30); 45 | } 46 | else if (usDistance < FOLLOW_DISTANCE) { 47 | carForward(power); 48 | } else { 49 | if (!leftIsClear) { 50 | carTurnLeft(rotate_power); 51 | } else if (!rightIsClear) { 52 | carTurnRight(rotate_power); 53 | } else { 54 | carStop(); 55 | } 56 | } 57 | 58 | delay(20); 59 | } 60 | -------------------------------------------------------------------------------- /examples/9_hc165_and_ir_obstacle/9_hc165_and_ir_obstacle.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | * hc165_and_ir_obstacle 3 | 4 | Read the value of two ir_obstacle 5 | 6 | - Due to the lack of IO, the car uses two 3-to-8 io expansion chips HC165 to connect 7 | two IR obstacle avoidance modules and one 8-channel grayscale module 8 | - Two IR obstacle avoidance modules use the lower two io 9 | The 8-channel grayscale module uses the high 8-bit io 10 | 11 | ******************************************************************/ 12 | #include 13 | 14 | /** 15 | * @name Define pins of the HC165 IO expansion chip 16 | */ 17 | #define PIN_74HC165_CP 8 18 | #define PIN_74HC165_PL 9 19 | #define PIN_74HC165_Q7 7 20 | 21 | void setup() { 22 | Serial.begin(115200); 23 | irObstacleBegin(); 24 | } 25 | 26 | void loop() { 27 | byte result = irObstacleRead(); 28 | bool leftIsClear = result & 0b00000001; 29 | bool rightIsClear = result & 0b00000010; 30 | Serial.print(leftIsClear); 31 | Serial.print(", "); 32 | Serial.println(rightIsClear); 33 | delay(100); 34 | } 35 | 36 | void hc165Begin() { 37 | pinMode(PIN_74HC165_CP, OUTPUT); 38 | pinMode(PIN_74HC165_PL, OUTPUT); 39 | pinMode(PIN_74HC165_Q7, INPUT); 40 | } 41 | 42 | uint16_t hc165Read() { 43 | // Write pulse to load pin 44 | digitalWrite(PIN_74HC165_PL, LOW); 45 | delayMicroseconds(5); 46 | digitalWrite(PIN_74HC165_CP, HIGH); 47 | delayMicroseconds(5); 48 | digitalWrite(PIN_74HC165_PL, HIGH); 49 | delayMicroseconds(5); 50 | 51 | // Get data from 74HC165 52 | uint16_t first8 = shiftIn(PIN_74HC165_Q7, PIN_74HC165_CP, MSBFIRST); 53 | uint16_t last8 = shiftIn(PIN_74HC165_Q7, PIN_74HC165_CP, MSBFIRST); 54 | 55 | return last8 << 8 | first8; 56 | } 57 | 58 | void irObstacleBegin() { 59 | hc165Begin(); 60 | } 61 | 62 | byte irObstacleRead() { 63 | return hc165Read(); 64 | } 65 | -------------------------------------------------------------------------------- /examples/11_obstacle_avoid/11_obstacle_avoid.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | * obstacle_avoid 3 | 4 | Automatic obstacle avoidance driving using ultrasonic module 5 | and two infrared obstacle avoidance modules 6 | 7 | - Before use, you need to adjust the distance reference knob of 8 | the two IR obstacle avoidance modules to the appropriate position 9 | 10 | ******************************************************************/ 11 | #include 12 | #include "car_control.h" 13 | #include "ir_obstacle.h" 14 | #include "ultrasonic.h" 15 | 16 | #define AVOID_DISTANCE 20 17 | 18 | int8_t power = 80; 19 | int8_t rotate_power = 80; 20 | bool leftIsClear = false; 21 | bool rightIsClear = false; 22 | bool middleIsClear = false; 23 | 24 | void setup() { 25 | Serial.begin(115200); 26 | Serial.println("Zeus Car auto obstacle avoid"); 27 | carBegin(); 28 | irObstacleBegin(); 29 | } 30 | 31 | void loop() { 32 | byte result = irObstacleRead(); 33 | leftIsClear = result & 0b00000001; 34 | rightIsClear = result & 0b00000010; 35 | 36 | float distance = ultrasonicRead(); 37 | Serial.print("distance: ");Serial.print(distance); 38 | if (distance > AVOID_DISTANCE) { 39 | middleIsClear = true; 40 | } else { 41 | middleIsClear = false; 42 | } 43 | 44 | Serial.print(" obstacle: [ ");Serial.print(leftIsClear? "_" : "X"); 45 | Serial.print(" ");Serial.print(middleIsClear? "_" : "X"); 46 | Serial.print(" ");Serial.print(rightIsClear? "_" : "X"); 47 | Serial.println("]"); 48 | 49 | 50 | if (middleIsClear && leftIsClear && rightIsClear) { 51 | carForward(power); 52 | } else { 53 | if (leftIsClear) { 54 | carTurnLeft(rotate_power); 55 | } else if (rightIsClear) { 56 | carTurnRight(rotate_power); 57 | } else { 58 | carMove(0, 0, 20); 59 | delay(400); 60 | carStop(); 61 | } 62 | } 63 | delay(20); 64 | } 65 | -------------------------------------------------------------------------------- /examples/16_ai_detection_from_app/16_ai_detection_from_app.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | * APP control 3 | 4 | Use esp32-cam to communicate with the app via wifi to control the car 5 | 6 | 1. Note: 7 | when downloading the code, you need to set the switch on the expansion board to upload, 8 | and when running, you need to set the switch to cam. 9 | 2. Firstly, set the wifi, name, etc., send the service command to esp32-cam, 10 | esp32-cam will open the websocket server and communicate with app after 11 | screensuccessfully connect to the wifi, and also open the webcam 12 | 13 | ******************************************************************/ 14 | #include 15 | #include "ai_camera.h" 16 | 17 | /** Configure Wifi AP mode,SSID, password*/ 18 | #define WIFI_MODE WIFI_MODE_AP 19 | #define SSID "Zeus_Car" 20 | #define PASSWORD "12345678" 21 | 22 | /** Configure Wifi STA mode,SSID, password*/ 23 | // #define WIFI_MODE WIFI_MODE_STA 24 | // #define SSID "xxxxxxxxxx" 25 | // #define PASSWORD "xxxxxxxxxx" 26 | 27 | /** Configure product name and type*/ 28 | #define NAME "Zeus_Car" 29 | #define TYPE "Zeus_Car" 30 | 31 | /* Configure websockets port 32 | * - Sunfounder Controller APP fixed using port 8765 33 | */ 34 | #define PORT "8765" 35 | 36 | /** Instantiate aicamera, a class for serial communication with ESP32-CAM */ 37 | AiCamera aiCam = AiCamera(NAME, TYPE); 38 | 39 | 40 | 41 | 42 | /*********************** setup() & loop() ************************/ 43 | void setup() { 44 | 45 | Serial.begin(115200); 46 | 47 | aiCam.begin(SSID, PASSWORD, WIFI_MODE, PORT); 48 | aiCam.setOnReceived(onReceive); 49 | 50 | 51 | 52 | } 53 | 54 | void loop() { 55 | aiCam.loop(); 56 | } 57 | 58 | /***************************** Functions ******************************/ 59 | /** 60 | * websocket received data processing 61 | */ 62 | void onReceive(char* recvBuf, char* sendBuf) { 63 | 64 | } 65 | 66 | -------------------------------------------------------------------------------- /examples/15_line_track_field_centric/15_line_track_field_centric.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | * line_track ((fixed head direction) 3 | 4 | Use the eight-way grayscale module to trace the line 5 | 6 | - Before use, you need to adjust the potentiometer on the expansion board 7 | to calibrate the grayscale module 8 | 9 | ******************************************************************/ 10 | #include 11 | #include "car_control.h" 12 | #include "grayscale.h" 13 | 14 | #define LINE_TRACK_POWER 30 15 | #define LINE_TRACK_OFFSET_ANGLE 20 16 | 17 | int16_t currentAngle = 0; 18 | 19 | void setup() { 20 | Serial.begin(115200); 21 | carBegin(); 22 | gsBegin(); 23 | } 24 | 25 | void loop() { 26 | line_track(); 27 | // delay(2); 28 | 29 | } 30 | 31 | void line_track() { 32 | uint16_t result = gsGetAngleOffset(); 33 | uint8_t angleType = result >> 8 & 0xFF; 34 | uint8_t offsetType = result & 0xFF; 35 | int16_t angle = 0; 36 | int8_t offset = 0; 37 | 38 | switch (angleType) { 39 | case ANGLE_N45: angle = -45;break; 40 | case ANGLE_0: angle = 0;break; 41 | case ANGLE_45: angle = 45;break; 42 | case ANGLE_90: angle = 90;break; 43 | case ANGLE_ERROR: angle = currentAngle;break; 44 | } 45 | switch (offsetType) { 46 | case OFFSET_N1: offset = -1;break; 47 | case OFFSET_0: offset = 0;break; 48 | case OFFSET_1: offset = 1;break; 49 | case OFFSET_ERROR: offset = 0;break; 50 | } 51 | 52 | int16_t deltaAngle = currentAngle - angle; 53 | if (deltaAngle > 180) { 54 | deltaAngle -= 360; 55 | } else if (deltaAngle < -180) { 56 | deltaAngle += 360; 57 | } 58 | 59 | if (deltaAngle > 90) { 60 | angle -= 180; 61 | offset *= -1; 62 | } else if (deltaAngle < -90) { 63 | angle += 180; 64 | offset *= -1; 65 | } 66 | 67 | currentAngle = angle + (offset*LINE_TRACK_OFFSET_ANGLE); 68 | carMoveFieldCentric(currentAngle, LINE_TRACK_POWER, 0, false); 69 | } 70 | -------------------------------------------------------------------------------- /test/qmc6310test/qmc6310.h: -------------------------------------------------------------------------------- 1 | #ifndef __QMC6310_H__ 2 | #define __QMC6310_H__ 3 | 4 | #include 5 | #include 6 | 7 | #define QMC6310_ADDR 0x1C 8 | 9 | #define QMC6310_REG_DATA_START 0x01 10 | #define QMC6310_REG_STATUS 0x09 11 | #define QMC6310_REG_CONTROL_1 0x0A 12 | #define QMC6310_REG_CONTROL_2 0x0B 13 | 14 | #define QMC6310_VAL_MODE_SUSPEND 0 << 0 15 | #define QMC6310_VAL_MODE_NORMAL 1 << 0 16 | #define QMC6310_VAL_MODE_SINGLE 2 << 0 17 | #define QMC6310_VAL_MODE_CONTINUOUS 3 << 0 18 | 19 | #define QMC6310_VAL_ODR_10HZ 0 << 2 20 | #define QMC6310_VAL_ODR_50HZ 1 << 2 21 | #define QMC6310_VAL_ODR_100HZ 2 << 2 22 | #define QMC6310_VAL_ODR_200HZ 3 << 2 23 | 24 | #define QMC6310_VAL_OSR1_8 0 << 4 25 | #define QMC6310_VAL_OSR1_4 1 << 4 26 | #define QMC6310_VAL_OSR1_2 2 << 4 27 | #define QMC6310_VAL_OSR1_1 3 << 4 28 | 29 | #define QMC6310_VAL_OSR2_1 0 << 6 30 | #define QMC6310_VAL_OSR2_2 1 << 6 31 | #define QMC6310_VAL_OSR2_4 2 << 6 32 | #define QMC6310_VAL_OSR2_8 3 << 6 33 | 34 | #define QMC6310_VAL_MODE_SET_RESET_ON 0 << 0 35 | #define QMC6310_VAL_MODE_SET_ON 1 << 0 36 | #define QMC6310_VAL_MODE_SET_RESET_OFF 2 << 0 37 | 38 | #define QMC6310_VAL_RNG_30G 0 << 2 39 | #define QMC6310_VAL_RNG_12G 1 << 2 40 | #define QMC6310_VAL_RNG_8G 2 << 2 41 | #define QMC6310_VAL_RNG_2G 3 << 2 42 | 43 | #define QMC6310_VAL_SELF_TEST_ON 1 << 6 44 | #define QMC6310_VAL_SELF_TEST_OFF 0 << 6 45 | 46 | #define QMC6310_VAL_SOFT_RST_ON 1 << 7 47 | #define QMC6310_VAL_SOFT_RST_OFF 0 << 7 48 | 49 | 50 | class QMC6310{ 51 | public: 52 | QMC6310(); 53 | void init(); 54 | void read(); 55 | int16_t getX(); 56 | int16_t getY(); 57 | int16_t getZ(); 58 | uint16_t getAzimuth(); 59 | void setCalibration(int16_t xMin, int16_t xMax, int16_t yMin, int16_t yMax, int16_t zMin, int16_t zMax); 60 | void clearCalibration(); 61 | private: 62 | void _i2cWrite(byte reg, byte val); 63 | void _i2cReadInto(byte reg, byte num, byte* dest); 64 | bool _calibrated = false; 65 | }; 66 | 67 | #endif // __QMC6310_H__ -------------------------------------------------------------------------------- /examples/7_compass/7_compass.ino: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * direction_hold 3 | - Use the geomagnetic sensor and PID control to keep the car head in a fixed direction (field center control) 4 | - Turn the trolley, the front of the car will return to its place 5 | - (lift the car, change the direction) press the remote control IR_KEY_PLAY_PAUSE key to reset the direction of the car 6 | 7 | a. car_control.h adds a pid-controlled head-holding movement function carMoveFieldCentric() 8 | b. CarBegin() contains compassBegin() and executes carResetHeading() 9 | c. The function carResetHeading() to reset the head angle is added to car_control.h 10 | ----------------------------------------------------------------*/ 11 | 12 | #include 13 | #include "compass.h" 14 | #include "car_control.h" 15 | #include "ir_remote.h" 16 | #include "rgb.h" 17 | 18 | #define CAR_CALIBRATION_POWER 80 19 | 20 | void setup() { 21 | Serial.begin(115200); 22 | SoftPWMBegin(); //init softpwm, before the motors initialization and the rgb LEDs initialization 23 | rgbBegin(); 24 | irBegin(); 25 | carBegin(); 26 | } 27 | 28 | void loop() { 29 | uint8_t key = irRead(); 30 | if (key == IR_KEY_MUTE) { 31 | Serial.println("Start compass calibration ..."); 32 | compassCalibrate(); 33 | } else if (key == IR_KEY_PLAY_PAUSE) { 34 | Serial.println("Reset Heading"); 35 | carResetHeading(); 36 | } else if (key == IR_KEY_POWER) { 37 | Serial.println("Stop"); 38 | carStop(); 39 | } 40 | 41 | carMoveFieldCentric(0, 0, 0); 42 | // delay(2); // If the delay is too long, the PID adjustment of the car will be deteriorated, and it needs < 5ms 43 | } 44 | 45 | void compassCalibrate() { 46 | carMove(0, 0, CAR_CALIBRATION_POWER); 47 | compassCalibrateStart(); 48 | while (! compassCalibrateDone()) { 49 | uint8_t key = irRead(); 50 | if (key == IR_KEY_POWER) { 51 | break; 52 | } 53 | 54 | bool changed = compassCalibrateLoop(); 55 | if (changed) { 56 | rgbWrite(0, 255, 0); 57 | delay(20); 58 | rgbOff(); 59 | } 60 | } 61 | Serial.println("Compass calibration done"); 62 | carStop(); 63 | delay(1000); 64 | } 65 | -------------------------------------------------------------------------------- /examples/5_remote_control/5_remote_control.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | * remote_control 3 | 4 | Use the IR remote control to control the car 5 | to move or rotate in different directions. 6 | 7 | ******************************************************************/ 8 | #include 9 | #include 10 | #include "car_control.h" 11 | #include "ir_remote.h" 12 | 13 | int angle=0; 14 | int power=0; 15 | int rotate=0; 16 | 17 | void setup() { 18 | Serial.begin(115200); 19 | Serial.println("Zeus Car IR remote control"); 20 | SoftPWMBegin(); //init softpwm, before the motors initialization 21 | carBegin(); // init motors 22 | irBegin(); 23 | } 24 | 25 | void loop() { 26 | uint8_t key = irRead(); 27 | if (key != IR_KEY_ERROR) { 28 | Serial.print("key: 0x");Serial.println(key, HEX); 29 | } 30 | 31 | switch (key) { 32 | case IR_KEY_ERROR: 33 | break; 34 | case IR_KEY_POWER: 35 | angle=0; 36 | power=0; 37 | rotate=0; 38 | break; 39 | case IR_KEY_2: 40 | angle=0; 41 | power=80; 42 | rotate=0; 43 | break; 44 | case IR_KEY_3: 45 | angle=45; 46 | power=80; 47 | rotate=0; 48 | break; 49 | case IR_KEY_6: 50 | angle=90; 51 | power=80; 52 | rotate=0; 53 | break; 54 | case IR_KEY_9: 55 | angle=135; 56 | power=80; 57 | rotate=0; 58 | break; 59 | case IR_KEY_8: 60 | angle=180; 61 | power=80; 62 | rotate=0; 63 | break; 64 | case IR_KEY_7: 65 | angle=255; 66 | power=80; 67 | rotate=0; 68 | break; 69 | case IR_KEY_4: 70 | angle=270; 71 | power=80; 72 | rotate=0; 73 | break; 74 | case IR_KEY_1: 75 | angle=315; 76 | power=80; 77 | rotate=0; 78 | break; 79 | case IR_KEY_5: 80 | angle=0; 81 | power=0; 82 | rotate=0; 83 | break; 84 | case IR_KEY_CYCLE: 85 | rotate=50; 86 | break; 87 | case IR_KEY_U_SD: 88 | rotate=-50; 89 | break; 90 | default: 91 | break; 92 | } 93 | carMove(angle, power,rotate); 94 | delay(20); 95 | } 96 | -------------------------------------------------------------------------------- /examples/14_line_track/14_line_track.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | * line_track_v2 (turn the head of the car) 3 | 4 | Use the eight-way grayscale module to trace the line 5 | 6 | - Before use, you need to adjust the potentiometer on the expansion board 7 | to calibrate the grayscale module 8 | 9 | ******************************************************************/ 10 | #include 11 | #include "car_control.h" 12 | #include "grayscale.h" 13 | 14 | #define LINE_TRACK_POWER 30 15 | #define LINE_TRACK_OFFSET_ANGLE 20 16 | 17 | int16_t currentAngle = 0; 18 | extern int16_t originHeading; 19 | bool useMag = false; 20 | 21 | void setup() 22 | { 23 | Serial.begin(115200); 24 | carBegin(); 25 | gsBegin(); 26 | } 27 | 28 | void loop() 29 | { 30 | line_track(); 31 | // delay(2); 32 | } 33 | 34 | void line_track() 35 | { 36 | uint16_t result = gsGetAngleOffset(); 37 | uint8_t angleType = result >> 8 & 0xFF; 38 | uint8_t offsetType = result & 0xFF; 39 | int16_t angle = 0; 40 | int8_t offset = 0; 41 | 42 | switch (angleType) 43 | { 44 | case ANGLE_N45: 45 | angle = -45; 46 | break; 47 | case ANGLE_0: 48 | angle = 0; 49 | break; 50 | case ANGLE_45: 51 | angle = 45; 52 | break; 53 | case ANGLE_90: 54 | angle = 90; 55 | break; 56 | case ANGLE_ERROR: 57 | angle = currentAngle; 58 | break; 59 | } 60 | switch (offsetType) 61 | { 62 | case OFFSET_N1: 63 | offset = -1; 64 | break; 65 | case OFFSET_0: 66 | offset = 0; 67 | break; 68 | case OFFSET_1: 69 | offset = 1; 70 | break; 71 | case OFFSET_ERROR: 72 | offset = 0; 73 | break; 74 | } 75 | 76 | int16_t deltaAngle = currentAngle - angle; 77 | if (deltaAngle > 180) 78 | { 79 | deltaAngle -= 360; 80 | } 81 | else if (deltaAngle < -180) 82 | { 83 | deltaAngle += 360; 84 | } 85 | 86 | if (deltaAngle > 90) 87 | { 88 | angle -= 180; 89 | offset *= -1; 90 | } 91 | else if (deltaAngle < -90) 92 | { 93 | angle += 180; 94 | offset *= -1; 95 | } 96 | 97 | currentAngle = angle + (offset * LINE_TRACK_OFFSET_ANGLE); 98 | 99 | if (useMag) 100 | { 101 | carMoveFieldCentric(currentAngle, LINE_TRACK_POWER, 0, false, true); 102 | } 103 | else 104 | { 105 | carMove(currentAngle, LINE_TRACK_POWER, 0, false); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /examples/10_ultrasonic/10_ultrasonic.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | * ultrasonic 3 | 4 | Read the value of two ultrasonic module 5 | 6 | - To save Io, echo and string share one pin 7 | 8 | ******************************************************************/ 9 | #include 10 | #include 11 | 12 | /** Set pins of ultrasonic 13 | * To save IO ports, echo and tring could share an identical pin 14 | */ 15 | #define ULTRASONIC_TRIG_PIN 10 16 | #define ULTRASONIC_ECHO_PIN 10 17 | 18 | /** Configure ultrasonic obstacle avoidance distance, unit cm */ 19 | #define ULTRASONIC_AVOIDANCE_THRESHOLD 20 20 | #define MAX_DISTANCE 2000 // unit: cm 21 | 22 | void setup() { 23 | Serial.begin(115200); 24 | SoftPWMBegin(); 25 | 26 | } 27 | 28 | void loop() { 29 | float distance = ultrasonicRead(); 30 | Serial.print("distance: ");Serial.print(distance); 31 | bool is_obstacle = ultrasonicIsObstacle(); 32 | Serial.print(" is_obstacle: ");Serial.println(is_obstacle); 33 | delay(200); 34 | } 35 | 36 | /** Return the distance read by the ultrasonic module, unit cm */ 37 | float ultrasonicRead() { 38 | delay(4); // A delay is required between consecutive readings, otherwise the reading may be 0 39 | 40 | pinMode(ULTRASONIC_TRIG_PIN, OUTPUT); 41 | digitalWrite(ULTRASONIC_TRIG_PIN, LOW); 42 | delayMicroseconds(2); 43 | digitalWrite(ULTRASONIC_TRIG_PIN, HIGH); 44 | delayMicroseconds(10); 45 | digitalWrite(ULTRASONIC_TRIG_PIN, LOW); 46 | pinMode(ULTRASONIC_ECHO_PIN, INPUT); 47 | 48 | // noInterrupts(); // Pause all interruptions to avoid affecting data 49 | // However,turning off interrupts affects the functionality of softpwm, such as motors 50 | 51 | float duration = pulseIn(ULTRASONIC_ECHO_PIN, HIGH); 52 | float distance = duration * 0.017; // S = vt = 340m/s * t_us / 2= (340 * 100 cm/s) * 0.5 * (t / 10^6)s = 0.017 * t (divided by 2 (go and back)) 53 | 54 | // interrupts(); // resume interruptions 55 | 56 | if (distance > MAX_DISTANCE) { 57 | return -1; 58 | } 59 | return distance; 60 | } 61 | 62 | 63 | /** Determine whether there is an obstacle ahead according to the set ULTRASONIC_AVOIDANCE_THRESHOLD */ 64 | bool ultrasonicIsObstacle() { 65 | return ultrasonicRead() < ULTRASONIC_AVOIDANCE_THRESHOLD; 66 | } 67 | 68 | /** Determine whether there is clear ahead according to the set ULTRASONIC_AVOIDANCE_THRESHOLD */ 69 | bool ultrasonicIsClear() { 70 | return ultrasonicRead() > ULTRASONIC_AVOIDANCE_THRESHOLD; 71 | } 72 | -------------------------------------------------------------------------------- /test/qmc6310test/qmc6310.cpp: -------------------------------------------------------------------------------- 1 | #include "qmc6310.h" 2 | 3 | int16_t _calibrationData[6]; 4 | 5 | int16_t _x; 6 | int16_t _y; 7 | int16_t _z; 8 | 9 | QMC6310::QMC6310() { 10 | } 11 | 12 | void QMC6310::init() { 13 | Wire.begin(); 14 | // According to the datasheet, 7.1 Define the sign for X Y and Z axis 15 | this->_i2cWrite(0x29, 0x06); 16 | this->_i2cWrite(QMC6310_REG_CONTROL_2, QMC6310_VAL_RNG_8G); 17 | this->_i2cWrite(QMC6310_REG_CONTROL_1, QMC6310_VAL_MODE_NORMAL | QMC6310_VAL_ODR_200HZ | QMC6310_VAL_OSR1_8 | QMC6310_VAL_OSR2_8); 18 | } 19 | 20 | void QMC6310::read() { 21 | byte datas[6]; 22 | this->_i2cReadInto(QMC6310_REG_DATA_START, 6, datas); 23 | _x = (int16_t)((datas[1] << 8) | datas[0]); 24 | _y = (int16_t)((datas[3] << 8) | datas[2]); 25 | _z = (int16_t)((datas[5] << 8) | datas[4]); 26 | 27 | // calibrate: 28 | if (this->_calibrated) { 29 | int x_offset = (_calibrationData[0] + _calibrationData[1]) / 2; 30 | int y_offset = (_calibrationData[2] + _calibrationData[3]) / 2; 31 | int z_offset = (_calibrationData[4] + _calibrationData[5]) / 2; 32 | float x_avg = (_calibrationData[1] - _calibrationData[0]) / 2.0; 33 | float y_avg = (_calibrationData[3] - _calibrationData[2]) / 2.0; 34 | float z_avg = (_calibrationData[5] - _calibrationData[4]) / 2.0; 35 | 36 | float avg = (x_avg + y_avg + z_avg) / 3; 37 | 38 | float x_scale = avg / x_avg; 39 | float y_scale = avg / y_avg; 40 | float z_scale = avg / z_avg; 41 | 42 | _x = (int16_t)((_x - x_offset) * x_scale); 43 | _y = (int16_t)((_y - y_offset) * y_scale); 44 | _z = (int16_t)((_z - z_offset) * z_scale); 45 | } 46 | } 47 | 48 | int16_t QMC6310::getX() {return _x;} 49 | int16_t QMC6310::getY() {return _y;} 50 | int16_t QMC6310::getZ() {return _z;} 51 | 52 | uint16_t QMC6310::getAzimuth() { 53 | int16_t azimuth = atan2(_y, _x) * 180.0 / PI; 54 | if (azimuth < 0) azimuth += 360; 55 | return azimuth; 56 | } 57 | 58 | void QMC6310::clearCalibration() { 59 | this->_calibrated = false; 60 | } 61 | 62 | void QMC6310::setCalibration(int xMin, int xMax, int yMin, int yMax, int zMin, int zMax) { 63 | this->_calibrated = true; 64 | _calibrationData[0] = xMin; 65 | _calibrationData[1] = xMax; 66 | _calibrationData[2] = yMin; 67 | _calibrationData[3] = yMax; 68 | _calibrationData[4] = zMin; 69 | _calibrationData[5] = zMax; 70 | } 71 | 72 | void QMC6310::_i2cWrite(byte reg, byte val) { 73 | Wire.beginTransmission(QMC6310_ADDR); 74 | Wire.write(reg); 75 | Wire.write(val); 76 | Wire.endTransmission(); 77 | } 78 | 79 | void QMC6310::_i2cReadInto(byte reg, byte num, byte* dest) { 80 | Wire.beginTransmission(QMC6310_ADDR); 81 | Wire.write(reg); 82 | Wire.endTransmission(); 83 | Wire.requestFrom(QMC6310_ADDR, num); 84 | while(Wire.available() < num); 85 | for(int i = 0; i < num; i++) { 86 | dest[i] = Wire.read(); 87 | } 88 | } -------------------------------------------------------------------------------- /Zeus_Car/test.h: -------------------------------------------------------------------------------- 1 | #ifndef _TEST_H_ 2 | #define _TEST_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "car_control.h" 8 | #include "ir_remote.h" 9 | #include "hc165.h" 10 | #include "ir_obstacle.h" 11 | #include "grayscale.h" 12 | #include "ultrasonic.h" 13 | #include "rgb.h" 14 | 15 | /** motors test, the car cycles forward and backward */ 16 | void motors_test(){ 17 | carMove( 0, 80, 0); 18 | rgbWrite(0, 255, 0); 19 | delay(500); 20 | carMove( 180, 80, 0); 21 | rgbWrite(0, 0, 255); 22 | delay(500); 23 | rgbWrite(255, 255, 255); 24 | } 25 | 26 | /** RGB LEDs test, the LEDs cyclic transformation of R,G,B three colors */ 27 | void rgb_test() { 28 | rgbWrite(RED); 29 | delay(1000); 30 | rgbWrite(GREEN); 31 | delay(1000); 32 | rgbWrite(BLUE); 33 | delay(1000); 34 | } 35 | 36 | /** 8-way grayscale module test 37 | * |Cyclic printing of the detected data 38 | */ 39 | void grayscale_test() { 40 | int angle = 0; 41 | uint16_t result = gsGetAngleOffset(); 42 | uint8_t angleType = result >> 8 & 0xFF; 43 | uint8_t offsetType = result & 0xFF; 44 | // Serial.print("angleType: "); 45 | // Serial.print(angleType); 46 | // Serial.print(", offsetType: "); 47 | // Serial.println(offsetType); 48 | // delay(200); 49 | 50 | byte data = gsRead(); 51 | Serial.print("data: ");Serial.print(data, BIN); 52 | 53 | switch (angleType) { 54 | case ANGLE_N45: angle = -45;break; 55 | case ANGLE_0: angle = 0;break; 56 | case ANGLE_45: angle = 45;break; 57 | case ANGLE_90: angle = 90;break; 58 | // case ANGLE_ERROR: angle = currentAngle;break; 59 | } 60 | Serial.print(", angle: ");Serial.println(angle); 61 | 62 | delay(200); 63 | 64 | } 65 | 66 | /** ultrasonictest, cyclic printing of the detected data */ 67 | void ultrasonic_test() { 68 | rgbWrite(BLUE); 69 | float distance = ultrasonicRead(); 70 | Serial.print("distance: "); 71 | Serial.println(distance); 72 | delay(100); 73 | rgbOff(); 74 | delay(500); 75 | } 76 | 77 | /** infrared obstacle avoidance module test, cyclic printing of the detected data */ 78 | void ir_obstacle_test() { 79 | // uint16_t result = hc165Read(); 80 | // Serial.println(result, BIN); 81 | byte result = irObstacleRead(); 82 | bool leftIsClear = result & 0b00000001; 83 | bool rightIsClear = result & 0b00000010; 84 | Serial.print(leftIsClear); 85 | Serial.print(", "); 86 | Serial.println(rightIsClear); 87 | delay(100); 88 | } 89 | 90 | /** compasd sensor test, cyclic printing of the detected data */ 91 | void compass_test(){ 92 | int16_t result = compassGetAzimuth(); 93 | Serial.println(result); 94 | delay(200); 95 | } 96 | 97 | /** IR receiver test, cyclic printing of the received data */ 98 | void ir_remote_test() { 99 | uint8_t result = irRead(); 100 | if (result != IR_KEY_ERROR) { 101 | Serial.print("result: "); 102 | Serial.println(result, HEX); 103 | } 104 | delay(100); 105 | } 106 | 107 | #endif // TEST_H_INCLUDED 108 | 109 | -------------------------------------------------------------------------------- /examples/2_omni_move/2_omni_move.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | * omni_move 3 | 4 | The car uses the characteristics of the Mecanum wheel 5 | to move in different directions. 6 | 7 | Move along 0, 45, 90, 135, 180, 225, 270, 315, 360 direction 8 | in turn for 1 second 9 | ******************************************************************/ 10 | #include 11 | #include 12 | 13 | 14 | /* 15 | * [0]--|||--[1] 16 | * | | 17 | * | | 18 | * | | 19 | * | | 20 | * [3]-------[2] 21 | */ 22 | /** Set the pins for the motors */ 23 | #define MOTOR_PINS (uint8_t[8]){3, 4, 5, 6, A3, A2, A1, A0} 24 | /** Set the positive and negative directions for the motors */ 25 | #define MOTOR_DIRECTIONS (uint8_t[4]){1, 0, 0, 1} 26 | 27 | #define MOTOR_POWER_MIN 28 // 28/255 28 | 29 | int8_t power = 80; 30 | 31 | void setup() { 32 | Serial.begin(115200); 33 | Serial.println("Zeus Car omni-directional move"); 34 | SoftPWMBegin(); //init softpwm, before the motors initialization 35 | carBegin(); // init motors 36 | } 37 | 38 | void loop() { 39 | carMove(0, power); 40 | delay(800); 41 | carMove(45, power); 42 | delay(1000); 43 | carMove(90, power); 44 | delay(1000); 45 | carMove(135, power); 46 | delay(1000); 47 | carMove(180, power); 48 | delay(800); 49 | carMove(225, power); 50 | delay(1000); 51 | carMove(270, power); 52 | delay(1000); 53 | carMove(315, power); 54 | delay(1000); 55 | } 56 | 57 | void carBegin() { 58 | for (uint8_t i = 0; i < 8; i++) { 59 | SoftPWMSet(MOTOR_PINS[i], 0); 60 | SoftPWMSetFadeTime(MOTOR_PINS[i], 100, 100); 61 | } 62 | } 63 | 64 | void carSetMotors(int8_t power0, int8_t power1, int8_t power2, int8_t power3) { 65 | bool dir[4]; 66 | int8_t power[4] = {power0, power1, power2, power3}; 67 | int8_t newPower[4]; 68 | 69 | for (uint8_t i = 0; i < 4; i++) { 70 | dir[i] = power[i] > 0; 71 | 72 | if (MOTOR_DIRECTIONS[i]) dir[i] = !dir[i]; 73 | 74 | if (power[i] == 0) { 75 | newPower[i] = 0; 76 | } else { 77 | newPower[i] = map(abs(power[i]), 0, 100, MOTOR_POWER_MIN, 255); 78 | } 79 | SoftPWMSet(MOTOR_PINS[i*2], dir[i] * newPower[i]); 80 | SoftPWMSet(MOTOR_PINS[i*2+1], !dir[i] * newPower[i]); 81 | } 82 | } 83 | 84 | /** 85 | * Control the car to move 86 | * 87 | * @code {.cpp} 88 | * carMove(-90, 80); 89 | * @endcode 90 | * 91 | * @param angle the direction you want the car to move 92 | * @param power moving speed 93 | */ 94 | void carMove(int16_t angle, int8_t power) { 95 | int8_t power_0, power_1, power_2, power_3; 96 | // Make forward 0 97 | angle += 90; 98 | // Offset angle as 0 to the front 99 | float rad = angle * PI / 180; 100 | 101 | power /= sqrt(2); 102 | 103 | 104 | power_0 = (power * sin(rad) - power * cos(rad)); 105 | power_1 = (power * sin(rad) + power * cos(rad)); 106 | power_2 = (power * sin(rad) - power * cos(rad)); 107 | power_3 = (power * sin(rad) + power * cos(rad)); 108 | 109 | carSetMotors(power_0, power_1, power_2, power_3); 110 | 111 | } 112 | 113 | void carStop() { 114 | carSetMotors(0, 0, 0, 0); 115 | } 116 | -------------------------------------------------------------------------------- /Zeus_Car/qmc6310.h: -------------------------------------------------------------------------------- 1 | #ifndef __QMC6310_H__ 2 | #define __QMC6310_H__ 3 | 4 | #include 5 | #include 6 | 7 | /** @name Define I2C address of QMC6310 compass sensor */ 8 | #define QMC6310_ADDR 0x1C 9 | 10 | /** @name Define register address of QMC6310 compass sensor */ 11 | //@{ 12 | #define QMC6310_REG_DATA_START 0x01 13 | #define QMC6310_REG_STATUS 0x09 14 | #define QMC6310_REG_CONTROL_1 0x0A 15 | #define QMC6310_REG_CONTROL_2 0x0B 16 | //@} 17 | 18 | /** @name Define the register parameter configuration of the sensor */ 19 | //@{ 20 | #define QMC6310_VAL_MODE_SUSPEND 0 << 0 21 | #define QMC6310_VAL_MODE_NORMAL 1 << 0 22 | #define QMC6310_VAL_MODE_SINGLE 2 << 0 23 | #define QMC6310_VAL_MODE_CONTINUOUS 3 << 0 24 | 25 | #define QMC6310_VAL_ODR_10HZ 0 << 2 26 | #define QMC6310_VAL_ODR_50HZ 1 << 2 27 | #define QMC6310_VAL_ODR_100HZ 2 << 2 28 | #define QMC6310_VAL_ODR_200HZ 3 << 2 29 | 30 | #define QMC6310_VAL_OSR1_8 0 << 4 31 | #define QMC6310_VAL_OSR1_4 1 << 4 32 | #define QMC6310_VAL_OSR1_2 2 << 4 33 | #define QMC6310_VAL_OSR1_1 3 << 4 34 | 35 | #define QMC6310_VAL_OSR2_1 0 << 6 36 | #define QMC6310_VAL_OSR2_2 1 << 6 37 | #define QMC6310_VAL_OSR2_4 2 << 6 38 | #define QMC6310_VAL_OSR2_8 3 << 6 39 | 40 | #define QMC6310_VAL_MODE_SET_RESET_ON 0 << 0 41 | #define QMC6310_VAL_MODE_SET_ON 1 << 0 42 | #define QMC6310_VAL_MODE_SET_RESET_OFF 2 << 0 43 | 44 | #define QMC6310_VAL_RNG_30G 0 << 2 45 | #define QMC6310_VAL_RNG_12G 1 << 2 46 | #define QMC6310_VAL_RNG_8G 2 << 2 47 | #define QMC6310_VAL_RNG_2G 3 << 2 48 | 49 | #define QMC6310_VAL_SELF_TEST_ON 1 << 6 50 | #define QMC6310_VAL_SELF_TEST_OFF 0 << 6 51 | 52 | #define QMC6310_VAL_SOFT_RST_ON 1 << 7 53 | #define QMC6310_VAL_SOFT_RST_OFF 0 << 7 54 | //@} 55 | 56 | /** A class. Class of QMC6310 compass sensor */ 57 | class QMC6310{ 58 | public: 59 | /** Construct a new QMC6310 object */ 60 | QMC6310(); 61 | 62 | /** Initialize QMC6310 */ 63 | void init(); 64 | 65 | /** Read values of QMC6310 */ 66 | void read(); 67 | 68 | /** Get x-axis values of QMC6310 */ 69 | int16_t getX(); 70 | 71 | /** Get y-axis values of QMC6310 */ 72 | int16_t getY(); 73 | 74 | /** Get z-axis values of QMC6310 */ 75 | int16_t getZ(); 76 | 77 | /** Get azimuth of QMC6310 */ 78 | uint16_t getAzimuth(); 79 | 80 | /** Set calibration values */ 81 | void setCalibration(int16_t xMin, int16_t xMax, int16_t yMin, int16_t yMax, int16_t zMin, int16_t zMax); 82 | 83 | /** clear calibration values */ 84 | void clearCalibration(); 85 | 86 | private: 87 | /** i2c wite 88 | * 89 | * @param reg byte, register address 90 | * @param val byte, value to write 91 | * 92 | */ 93 | void _i2cWrite(byte reg, byte val); 94 | 95 | /** i2c read data 96 | * 97 | * @param reg byte, register address 98 | * @param num number of bytes to read 99 | * @param dest pointer to store read data 100 | * 101 | * @return Whether the execution is successful 102 | * - true succeed 103 | * - flase failed 104 | */ 105 | bool _i2cReadInto(byte reg, byte num, byte* dest); 106 | 107 | /** whether calibration is in progress */ 108 | bool _calibrated = false; 109 | }; 110 | 111 | #endif // __QMC6310_H__ -------------------------------------------------------------------------------- /examples/12_follow/qmc6310.h: -------------------------------------------------------------------------------- 1 | #ifndef __QMC6310_H__ 2 | #define __QMC6310_H__ 3 | 4 | #include 5 | #include 6 | 7 | /** @name Define I2C address of QMC6310 compass sensor */ 8 | #define QMC6310_ADDR 0x1C 9 | 10 | /** @name Define register address of QMC6310 compass sensor */ 11 | //@{ 12 | #define QMC6310_REG_DATA_START 0x01 13 | #define QMC6310_REG_STATUS 0x09 14 | #define QMC6310_REG_CONTROL_1 0x0A 15 | #define QMC6310_REG_CONTROL_2 0x0B 16 | //@} 17 | 18 | /** @name Define the register parameter configuration of the sensor */ 19 | //@{ 20 | #define QMC6310_VAL_MODE_SUSPEND 0 << 0 21 | #define QMC6310_VAL_MODE_NORMAL 1 << 0 22 | #define QMC6310_VAL_MODE_SINGLE 2 << 0 23 | #define QMC6310_VAL_MODE_CONTINUOUS 3 << 0 24 | 25 | #define QMC6310_VAL_ODR_10HZ 0 << 2 26 | #define QMC6310_VAL_ODR_50HZ 1 << 2 27 | #define QMC6310_VAL_ODR_100HZ 2 << 2 28 | #define QMC6310_VAL_ODR_200HZ 3 << 2 29 | 30 | #define QMC6310_VAL_OSR1_8 0 << 4 31 | #define QMC6310_VAL_OSR1_4 1 << 4 32 | #define QMC6310_VAL_OSR1_2 2 << 4 33 | #define QMC6310_VAL_OSR1_1 3 << 4 34 | 35 | #define QMC6310_VAL_OSR2_1 0 << 6 36 | #define QMC6310_VAL_OSR2_2 1 << 6 37 | #define QMC6310_VAL_OSR2_4 2 << 6 38 | #define QMC6310_VAL_OSR2_8 3 << 6 39 | 40 | #define QMC6310_VAL_MODE_SET_RESET_ON 0 << 0 41 | #define QMC6310_VAL_MODE_SET_ON 1 << 0 42 | #define QMC6310_VAL_MODE_SET_RESET_OFF 2 << 0 43 | 44 | #define QMC6310_VAL_RNG_30G 0 << 2 45 | #define QMC6310_VAL_RNG_12G 1 << 2 46 | #define QMC6310_VAL_RNG_8G 2 << 2 47 | #define QMC6310_VAL_RNG_2G 3 << 2 48 | 49 | #define QMC6310_VAL_SELF_TEST_ON 1 << 6 50 | #define QMC6310_VAL_SELF_TEST_OFF 0 << 6 51 | 52 | #define QMC6310_VAL_SOFT_RST_ON 1 << 7 53 | #define QMC6310_VAL_SOFT_RST_OFF 0 << 7 54 | //@} 55 | 56 | /** A class. Class of QMC6310 compass sensor */ 57 | class QMC6310{ 58 | public: 59 | /** Construct a new QMC6310 object */ 60 | QMC6310(); 61 | 62 | /** Initialize QMC6310 */ 63 | void init(); 64 | 65 | /** Read values of QMC6310 */ 66 | void read(); 67 | 68 | /** Get x-axis values of QMC6310 */ 69 | int16_t getX(); 70 | 71 | /** Get y-axis values of QMC6310 */ 72 | int16_t getY(); 73 | 74 | /** Get z-axis values of QMC6310 */ 75 | int16_t getZ(); 76 | 77 | /** Get azimuth of QMC6310 */ 78 | uint16_t getAzimuth(); 79 | 80 | /** Set calibration values */ 81 | void setCalibration(int16_t xMin, int16_t xMax, int16_t yMin, int16_t yMax, int16_t zMin, int16_t zMax); 82 | 83 | /** clear calibration values */ 84 | void clearCalibration(); 85 | 86 | private: 87 | /** i2c wite 88 | * 89 | * @param reg byte, register address 90 | * @param val byte, value to write 91 | * 92 | */ 93 | void _i2cWrite(byte reg, byte val); 94 | 95 | /** i2c read data 96 | * 97 | * @param reg byte, register address 98 | * @param num number of bytes to read 99 | * @param dest pointer to store read data 100 | * 101 | * @return Whether the execution is successful 102 | * - true succeed 103 | * - flase failed 104 | */ 105 | bool _i2cReadInto(byte reg, byte num, byte* dest); 106 | 107 | /** whether calibration is in progress */ 108 | bool _calibrated = false; 109 | }; 110 | 111 | #endif // __QMC6310_H__ 112 | -------------------------------------------------------------------------------- /examples/14_line_track/qmc6310.h: -------------------------------------------------------------------------------- 1 | #ifndef __QMC6310_H__ 2 | #define __QMC6310_H__ 3 | 4 | #include 5 | #include 6 | 7 | /** @name Define I2C address of QMC6310 compass sensor */ 8 | #define QMC6310_ADDR 0x1C 9 | 10 | /** @name Define register address of QMC6310 compass sensor */ 11 | //@{ 12 | #define QMC6310_REG_DATA_START 0x01 13 | #define QMC6310_REG_STATUS 0x09 14 | #define QMC6310_REG_CONTROL_1 0x0A 15 | #define QMC6310_REG_CONTROL_2 0x0B 16 | //@} 17 | 18 | /** @name Define the register parameter configuration of the sensor */ 19 | //@{ 20 | #define QMC6310_VAL_MODE_SUSPEND 0 << 0 21 | #define QMC6310_VAL_MODE_NORMAL 1 << 0 22 | #define QMC6310_VAL_MODE_SINGLE 2 << 0 23 | #define QMC6310_VAL_MODE_CONTINUOUS 3 << 0 24 | 25 | #define QMC6310_VAL_ODR_10HZ 0 << 2 26 | #define QMC6310_VAL_ODR_50HZ 1 << 2 27 | #define QMC6310_VAL_ODR_100HZ 2 << 2 28 | #define QMC6310_VAL_ODR_200HZ 3 << 2 29 | 30 | #define QMC6310_VAL_OSR1_8 0 << 4 31 | #define QMC6310_VAL_OSR1_4 1 << 4 32 | #define QMC6310_VAL_OSR1_2 2 << 4 33 | #define QMC6310_VAL_OSR1_1 3 << 4 34 | 35 | #define QMC6310_VAL_OSR2_1 0 << 6 36 | #define QMC6310_VAL_OSR2_2 1 << 6 37 | #define QMC6310_VAL_OSR2_4 2 << 6 38 | #define QMC6310_VAL_OSR2_8 3 << 6 39 | 40 | #define QMC6310_VAL_MODE_SET_RESET_ON 0 << 0 41 | #define QMC6310_VAL_MODE_SET_ON 1 << 0 42 | #define QMC6310_VAL_MODE_SET_RESET_OFF 2 << 0 43 | 44 | #define QMC6310_VAL_RNG_30G 0 << 2 45 | #define QMC6310_VAL_RNG_12G 1 << 2 46 | #define QMC6310_VAL_RNG_8G 2 << 2 47 | #define QMC6310_VAL_RNG_2G 3 << 2 48 | 49 | #define QMC6310_VAL_SELF_TEST_ON 1 << 6 50 | #define QMC6310_VAL_SELF_TEST_OFF 0 << 6 51 | 52 | #define QMC6310_VAL_SOFT_RST_ON 1 << 7 53 | #define QMC6310_VAL_SOFT_RST_OFF 0 << 7 54 | //@} 55 | 56 | /** A class. Class of QMC6310 compass sensor */ 57 | class QMC6310{ 58 | public: 59 | /** Construct a new QMC6310 object */ 60 | QMC6310(); 61 | 62 | /** Initialize QMC6310 */ 63 | void init(); 64 | 65 | /** Read values of QMC6310 */ 66 | void read(); 67 | 68 | /** Get x-axis values of QMC6310 */ 69 | int16_t getX(); 70 | 71 | /** Get y-axis values of QMC6310 */ 72 | int16_t getY(); 73 | 74 | /** Get z-axis values of QMC6310 */ 75 | int16_t getZ(); 76 | 77 | /** Get azimuth of QMC6310 */ 78 | uint16_t getAzimuth(); 79 | 80 | /** Set calibration values */ 81 | void setCalibration(int16_t xMin, int16_t xMax, int16_t yMin, int16_t yMax, int16_t zMin, int16_t zMax); 82 | 83 | /** clear calibration values */ 84 | void clearCalibration(); 85 | 86 | private: 87 | /** i2c wite 88 | * 89 | * @param reg byte, register address 90 | * @param val byte, value to write 91 | * 92 | */ 93 | void _i2cWrite(byte reg, byte val); 94 | 95 | /** i2c read data 96 | * 97 | * @param reg byte, register address 98 | * @param num number of bytes to read 99 | * @param dest pointer to store read data 100 | * 101 | * @return Whether the execution is successful 102 | * - true succeed 103 | * - flase failed 104 | */ 105 | bool _i2cReadInto(byte reg, byte num, byte* dest); 106 | 107 | /** whether calibration is in progress */ 108 | bool _calibrated = false; 109 | }; 110 | 111 | #endif // __QMC6310_H__ 112 | -------------------------------------------------------------------------------- /examples/7_compass/qmc6310.h: -------------------------------------------------------------------------------- 1 | #ifndef __QMC6310_H__ 2 | #define __QMC6310_H__ 3 | 4 | #include 5 | #include 6 | 7 | /** @name Define I2C address of QMC6310 compass sensor */ 8 | #define QMC6310_ADDR 0x1C 9 | 10 | /** @name Define register address of QMC6310 compass sensor */ 11 | //@{ 12 | #define QMC6310_REG_DATA_START 0x01 13 | #define QMC6310_REG_STATUS 0x09 14 | #define QMC6310_REG_CONTROL_1 0x0A 15 | #define QMC6310_REG_CONTROL_2 0x0B 16 | //@} 17 | 18 | /** @name Define the register parameter configuration of the sensor */ 19 | //@{ 20 | #define QMC6310_VAL_MODE_SUSPEND 0 << 0 21 | #define QMC6310_VAL_MODE_NORMAL 1 << 0 22 | #define QMC6310_VAL_MODE_SINGLE 2 << 0 23 | #define QMC6310_VAL_MODE_CONTINUOUS 3 << 0 24 | 25 | #define QMC6310_VAL_ODR_10HZ 0 << 2 26 | #define QMC6310_VAL_ODR_50HZ 1 << 2 27 | #define QMC6310_VAL_ODR_100HZ 2 << 2 28 | #define QMC6310_VAL_ODR_200HZ 3 << 2 29 | 30 | #define QMC6310_VAL_OSR1_8 0 << 4 31 | #define QMC6310_VAL_OSR1_4 1 << 4 32 | #define QMC6310_VAL_OSR1_2 2 << 4 33 | #define QMC6310_VAL_OSR1_1 3 << 4 34 | 35 | #define QMC6310_VAL_OSR2_1 0 << 6 36 | #define QMC6310_VAL_OSR2_2 1 << 6 37 | #define QMC6310_VAL_OSR2_4 2 << 6 38 | #define QMC6310_VAL_OSR2_8 3 << 6 39 | 40 | #define QMC6310_VAL_MODE_SET_RESET_ON 0 << 0 41 | #define QMC6310_VAL_MODE_SET_ON 1 << 0 42 | #define QMC6310_VAL_MODE_SET_RESET_OFF 2 << 0 43 | 44 | #define QMC6310_VAL_RNG_30G 0 << 2 45 | #define QMC6310_VAL_RNG_12G 1 << 2 46 | #define QMC6310_VAL_RNG_8G 2 << 2 47 | #define QMC6310_VAL_RNG_2G 3 << 2 48 | 49 | #define QMC6310_VAL_SELF_TEST_ON 1 << 6 50 | #define QMC6310_VAL_SELF_TEST_OFF 0 << 6 51 | 52 | #define QMC6310_VAL_SOFT_RST_ON 1 << 7 53 | #define QMC6310_VAL_SOFT_RST_OFF 0 << 7 54 | //@} 55 | 56 | /** A class. Class of QMC6310 compass sensor */ 57 | class QMC6310{ 58 | public: 59 | /** Construct a new QMC6310 object */ 60 | QMC6310(); 61 | 62 | /** Initialize QMC6310 */ 63 | void init(); 64 | 65 | /** Read values of QMC6310 */ 66 | void read(); 67 | 68 | /** Get x-axis values of QMC6310 */ 69 | int16_t getX(); 70 | 71 | /** Get y-axis values of QMC6310 */ 72 | int16_t getY(); 73 | 74 | /** Get z-axis values of QMC6310 */ 75 | int16_t getZ(); 76 | 77 | /** Get azimuth of QMC6310 */ 78 | uint16_t getAzimuth(); 79 | 80 | /** Set calibration values */ 81 | void setCalibration(int16_t xMin, int16_t xMax, int16_t yMin, int16_t yMax, int16_t zMin, int16_t zMax); 82 | 83 | /** clear calibration values */ 84 | void clearCalibration(); 85 | 86 | private: 87 | /** i2c wite 88 | * 89 | * @param reg byte, register address 90 | * @param val byte, value to write 91 | * 92 | */ 93 | void _i2cWrite(byte reg, byte val); 94 | 95 | /** i2c read data 96 | * 97 | * @param reg byte, register address 98 | * @param num number of bytes to read 99 | * @param dest pointer to store read data 100 | * 101 | * @return Whether the execution is successful 102 | * - true succeed 103 | * - flase failed 104 | */ 105 | bool _i2cReadInto(byte reg, byte num, byte* dest); 106 | 107 | /** whether calibration is in progress */ 108 | bool _calibrated = false; 109 | }; 110 | 111 | #endif // __QMC6310_H__ 112 | -------------------------------------------------------------------------------- /examples/11_obstacle_avoid/qmc6310.h: -------------------------------------------------------------------------------- 1 | #ifndef __QMC6310_H__ 2 | #define __QMC6310_H__ 3 | 4 | #include 5 | #include 6 | 7 | /** @name Define I2C address of QMC6310 compass sensor */ 8 | #define QMC6310_ADDR 0x1C 9 | 10 | /** @name Define register address of QMC6310 compass sensor */ 11 | //@{ 12 | #define QMC6310_REG_DATA_START 0x01 13 | #define QMC6310_REG_STATUS 0x09 14 | #define QMC6310_REG_CONTROL_1 0x0A 15 | #define QMC6310_REG_CONTROL_2 0x0B 16 | //@} 17 | 18 | /** @name Define the register parameter configuration of the sensor */ 19 | //@{ 20 | #define QMC6310_VAL_MODE_SUSPEND 0 << 0 21 | #define QMC6310_VAL_MODE_NORMAL 1 << 0 22 | #define QMC6310_VAL_MODE_SINGLE 2 << 0 23 | #define QMC6310_VAL_MODE_CONTINUOUS 3 << 0 24 | 25 | #define QMC6310_VAL_ODR_10HZ 0 << 2 26 | #define QMC6310_VAL_ODR_50HZ 1 << 2 27 | #define QMC6310_VAL_ODR_100HZ 2 << 2 28 | #define QMC6310_VAL_ODR_200HZ 3 << 2 29 | 30 | #define QMC6310_VAL_OSR1_8 0 << 4 31 | #define QMC6310_VAL_OSR1_4 1 << 4 32 | #define QMC6310_VAL_OSR1_2 2 << 4 33 | #define QMC6310_VAL_OSR1_1 3 << 4 34 | 35 | #define QMC6310_VAL_OSR2_1 0 << 6 36 | #define QMC6310_VAL_OSR2_2 1 << 6 37 | #define QMC6310_VAL_OSR2_4 2 << 6 38 | #define QMC6310_VAL_OSR2_8 3 << 6 39 | 40 | #define QMC6310_VAL_MODE_SET_RESET_ON 0 << 0 41 | #define QMC6310_VAL_MODE_SET_ON 1 << 0 42 | #define QMC6310_VAL_MODE_SET_RESET_OFF 2 << 0 43 | 44 | #define QMC6310_VAL_RNG_30G 0 << 2 45 | #define QMC6310_VAL_RNG_12G 1 << 2 46 | #define QMC6310_VAL_RNG_8G 2 << 2 47 | #define QMC6310_VAL_RNG_2G 3 << 2 48 | 49 | #define QMC6310_VAL_SELF_TEST_ON 1 << 6 50 | #define QMC6310_VAL_SELF_TEST_OFF 0 << 6 51 | 52 | #define QMC6310_VAL_SOFT_RST_ON 1 << 7 53 | #define QMC6310_VAL_SOFT_RST_OFF 0 << 7 54 | //@} 55 | 56 | /** A class. Class of QMC6310 compass sensor */ 57 | class QMC6310{ 58 | public: 59 | /** Construct a new QMC6310 object */ 60 | QMC6310(); 61 | 62 | /** Initialize QMC6310 */ 63 | void init(); 64 | 65 | /** Read values of QMC6310 */ 66 | void read(); 67 | 68 | /** Get x-axis values of QMC6310 */ 69 | int16_t getX(); 70 | 71 | /** Get y-axis values of QMC6310 */ 72 | int16_t getY(); 73 | 74 | /** Get z-axis values of QMC6310 */ 75 | int16_t getZ(); 76 | 77 | /** Get azimuth of QMC6310 */ 78 | uint16_t getAzimuth(); 79 | 80 | /** Set calibration values */ 81 | void setCalibration(int16_t xMin, int16_t xMax, int16_t yMin, int16_t yMax, int16_t zMin, int16_t zMax); 82 | 83 | /** clear calibration values */ 84 | void clearCalibration(); 85 | 86 | private: 87 | /** i2c wite 88 | * 89 | * @param reg byte, register address 90 | * @param val byte, value to write 91 | * 92 | */ 93 | void _i2cWrite(byte reg, byte val); 94 | 95 | /** i2c read data 96 | * 97 | * @param reg byte, register address 98 | * @param num number of bytes to read 99 | * @param dest pointer to store read data 100 | * 101 | * @return Whether the execution is successful 102 | * - true succeed 103 | * - flase failed 104 | */ 105 | bool _i2cReadInto(byte reg, byte num, byte* dest); 106 | 107 | /** whether calibration is in progress */ 108 | bool _calibrated = false; 109 | }; 110 | 111 | #endif // __QMC6310_H__ 112 | -------------------------------------------------------------------------------- /examples/17_app_control/qmc6310.h: -------------------------------------------------------------------------------- 1 | #ifndef __QMC6310_H__ 2 | #define __QMC6310_H__ 3 | 4 | #include 5 | #include 6 | 7 | /** @name Define I2C address of QMC6310 compass sensor */ 8 | #define QMC6310_ADDR 0x1C 9 | 10 | /** @name Define register address of QMC6310 compass sensor */ 11 | //@{ 12 | #define QMC6310_REG_DATA_START 0x01 13 | #define QMC6310_REG_STATUS 0x09 14 | #define QMC6310_REG_CONTROL_1 0x0A 15 | #define QMC6310_REG_CONTROL_2 0x0B 16 | //@} 17 | 18 | /** @name Define the register parameter configuration of the sensor */ 19 | //@{ 20 | #define QMC6310_VAL_MODE_SUSPEND 0 << 0 21 | #define QMC6310_VAL_MODE_NORMAL 1 << 0 22 | #define QMC6310_VAL_MODE_SINGLE 2 << 0 23 | #define QMC6310_VAL_MODE_CONTINUOUS 3 << 0 24 | 25 | #define QMC6310_VAL_ODR_10HZ 0 << 2 26 | #define QMC6310_VAL_ODR_50HZ 1 << 2 27 | #define QMC6310_VAL_ODR_100HZ 2 << 2 28 | #define QMC6310_VAL_ODR_200HZ 3 << 2 29 | 30 | #define QMC6310_VAL_OSR1_8 0 << 4 31 | #define QMC6310_VAL_OSR1_4 1 << 4 32 | #define QMC6310_VAL_OSR1_2 2 << 4 33 | #define QMC6310_VAL_OSR1_1 3 << 4 34 | 35 | #define QMC6310_VAL_OSR2_1 0 << 6 36 | #define QMC6310_VAL_OSR2_2 1 << 6 37 | #define QMC6310_VAL_OSR2_4 2 << 6 38 | #define QMC6310_VAL_OSR2_8 3 << 6 39 | 40 | #define QMC6310_VAL_MODE_SET_RESET_ON 0 << 0 41 | #define QMC6310_VAL_MODE_SET_ON 1 << 0 42 | #define QMC6310_VAL_MODE_SET_RESET_OFF 2 << 0 43 | 44 | #define QMC6310_VAL_RNG_30G 0 << 2 45 | #define QMC6310_VAL_RNG_12G 1 << 2 46 | #define QMC6310_VAL_RNG_8G 2 << 2 47 | #define QMC6310_VAL_RNG_2G 3 << 2 48 | 49 | #define QMC6310_VAL_SELF_TEST_ON 1 << 6 50 | #define QMC6310_VAL_SELF_TEST_OFF 0 << 6 51 | 52 | #define QMC6310_VAL_SOFT_RST_ON 1 << 7 53 | #define QMC6310_VAL_SOFT_RST_OFF 0 << 7 54 | //@} 55 | 56 | /** A class. Class of QMC6310 compass sensor */ 57 | class QMC6310{ 58 | public: 59 | /** Construct a new QMC6310 object */ 60 | QMC6310(); 61 | 62 | /** Initialize QMC6310 */ 63 | void init(); 64 | 65 | /** Read values of QMC6310 */ 66 | void read(); 67 | 68 | /** Get x-axis values of QMC6310 */ 69 | int16_t getX(); 70 | 71 | /** Get y-axis values of QMC6310 */ 72 | int16_t getY(); 73 | 74 | /** Get z-axis values of QMC6310 */ 75 | int16_t getZ(); 76 | 77 | /** Get azimuth of QMC6310 */ 78 | uint16_t getAzimuth(); 79 | 80 | /** Set calibration values */ 81 | void setCalibration(int16_t xMin, int16_t xMax, int16_t yMin, int16_t yMax, int16_t zMin, int16_t zMax); 82 | 83 | /** clear calibration values */ 84 | void clearCalibration(); 85 | 86 | private: 87 | /** i2c wite 88 | * 89 | * @param reg byte, register address 90 | * @param val byte, value to write 91 | * 92 | */ 93 | void _i2cWrite(byte reg, byte val); 94 | 95 | /** i2c read data 96 | * 97 | * @param reg byte, register address 98 | * @param num number of bytes to read 99 | * @param dest pointer to store read data 100 | * 101 | * @return Whether the execution is successful 102 | * - true succeed 103 | * - flase failed 104 | */ 105 | bool _i2cReadInto(byte reg, byte num, byte* dest); 106 | 107 | /** whether calibration is in progress */ 108 | bool _calibrated = false; 109 | }; 110 | 111 | #endif // __QMC6310_H__ 112 | -------------------------------------------------------------------------------- /examples/18_app_control_plus/qmc6310.h: -------------------------------------------------------------------------------- 1 | #ifndef __QMC6310_H__ 2 | #define __QMC6310_H__ 3 | 4 | #include 5 | #include 6 | 7 | /** @name Define I2C address of QMC6310 compass sensor */ 8 | #define QMC6310_ADDR 0x1C 9 | 10 | /** @name Define register address of QMC6310 compass sensor */ 11 | //@{ 12 | #define QMC6310_REG_DATA_START 0x01 13 | #define QMC6310_REG_STATUS 0x09 14 | #define QMC6310_REG_CONTROL_1 0x0A 15 | #define QMC6310_REG_CONTROL_2 0x0B 16 | //@} 17 | 18 | /** @name Define the register parameter configuration of the sensor */ 19 | //@{ 20 | #define QMC6310_VAL_MODE_SUSPEND 0 << 0 21 | #define QMC6310_VAL_MODE_NORMAL 1 << 0 22 | #define QMC6310_VAL_MODE_SINGLE 2 << 0 23 | #define QMC6310_VAL_MODE_CONTINUOUS 3 << 0 24 | 25 | #define QMC6310_VAL_ODR_10HZ 0 << 2 26 | #define QMC6310_VAL_ODR_50HZ 1 << 2 27 | #define QMC6310_VAL_ODR_100HZ 2 << 2 28 | #define QMC6310_VAL_ODR_200HZ 3 << 2 29 | 30 | #define QMC6310_VAL_OSR1_8 0 << 4 31 | #define QMC6310_VAL_OSR1_4 1 << 4 32 | #define QMC6310_VAL_OSR1_2 2 << 4 33 | #define QMC6310_VAL_OSR1_1 3 << 4 34 | 35 | #define QMC6310_VAL_OSR2_1 0 << 6 36 | #define QMC6310_VAL_OSR2_2 1 << 6 37 | #define QMC6310_VAL_OSR2_4 2 << 6 38 | #define QMC6310_VAL_OSR2_8 3 << 6 39 | 40 | #define QMC6310_VAL_MODE_SET_RESET_ON 0 << 0 41 | #define QMC6310_VAL_MODE_SET_ON 1 << 0 42 | #define QMC6310_VAL_MODE_SET_RESET_OFF 2 << 0 43 | 44 | #define QMC6310_VAL_RNG_30G 0 << 2 45 | #define QMC6310_VAL_RNG_12G 1 << 2 46 | #define QMC6310_VAL_RNG_8G 2 << 2 47 | #define QMC6310_VAL_RNG_2G 3 << 2 48 | 49 | #define QMC6310_VAL_SELF_TEST_ON 1 << 6 50 | #define QMC6310_VAL_SELF_TEST_OFF 0 << 6 51 | 52 | #define QMC6310_VAL_SOFT_RST_ON 1 << 7 53 | #define QMC6310_VAL_SOFT_RST_OFF 0 << 7 54 | //@} 55 | 56 | /** A class. Class of QMC6310 compass sensor */ 57 | class QMC6310{ 58 | public: 59 | /** Construct a new QMC6310 object */ 60 | QMC6310(); 61 | 62 | /** Initialize QMC6310 */ 63 | void init(); 64 | 65 | /** Read values of QMC6310 */ 66 | void read(); 67 | 68 | /** Get x-axis values of QMC6310 */ 69 | int16_t getX(); 70 | 71 | /** Get y-axis values of QMC6310 */ 72 | int16_t getY(); 73 | 74 | /** Get z-axis values of QMC6310 */ 75 | int16_t getZ(); 76 | 77 | /** Get azimuth of QMC6310 */ 78 | uint16_t getAzimuth(); 79 | 80 | /** Set calibration values */ 81 | void setCalibration(int16_t xMin, int16_t xMax, int16_t yMin, int16_t yMax, int16_t zMin, int16_t zMax); 82 | 83 | /** clear calibration values */ 84 | void clearCalibration(); 85 | 86 | private: 87 | /** i2c wite 88 | * 89 | * @param reg byte, register address 90 | * @param val byte, value to write 91 | * 92 | */ 93 | void _i2cWrite(byte reg, byte val); 94 | 95 | /** i2c read data 96 | * 97 | * @param reg byte, register address 98 | * @param num number of bytes to read 99 | * @param dest pointer to store read data 100 | * 101 | * @return Whether the execution is successful 102 | * - true succeed 103 | * - flase failed 104 | */ 105 | bool _i2cReadInto(byte reg, byte num, byte* dest); 106 | 107 | /** whether calibration is in progress */ 108 | bool _calibrated = false; 109 | }; 110 | 111 | #endif // __QMC6310_H__ 112 | -------------------------------------------------------------------------------- /examples/8_move_field_centric/qmc6310.h: -------------------------------------------------------------------------------- 1 | #ifndef __QMC6310_H__ 2 | #define __QMC6310_H__ 3 | 4 | #include 5 | #include 6 | 7 | /** @name Define I2C address of QMC6310 compass sensor */ 8 | #define QMC6310_ADDR 0x1C 9 | 10 | /** @name Define register address of QMC6310 compass sensor */ 11 | //@{ 12 | #define QMC6310_REG_DATA_START 0x01 13 | #define QMC6310_REG_STATUS 0x09 14 | #define QMC6310_REG_CONTROL_1 0x0A 15 | #define QMC6310_REG_CONTROL_2 0x0B 16 | //@} 17 | 18 | /** @name Define the register parameter configuration of the sensor */ 19 | //@{ 20 | #define QMC6310_VAL_MODE_SUSPEND 0 << 0 21 | #define QMC6310_VAL_MODE_NORMAL 1 << 0 22 | #define QMC6310_VAL_MODE_SINGLE 2 << 0 23 | #define QMC6310_VAL_MODE_CONTINUOUS 3 << 0 24 | 25 | #define QMC6310_VAL_ODR_10HZ 0 << 2 26 | #define QMC6310_VAL_ODR_50HZ 1 << 2 27 | #define QMC6310_VAL_ODR_100HZ 2 << 2 28 | #define QMC6310_VAL_ODR_200HZ 3 << 2 29 | 30 | #define QMC6310_VAL_OSR1_8 0 << 4 31 | #define QMC6310_VAL_OSR1_4 1 << 4 32 | #define QMC6310_VAL_OSR1_2 2 << 4 33 | #define QMC6310_VAL_OSR1_1 3 << 4 34 | 35 | #define QMC6310_VAL_OSR2_1 0 << 6 36 | #define QMC6310_VAL_OSR2_2 1 << 6 37 | #define QMC6310_VAL_OSR2_4 2 << 6 38 | #define QMC6310_VAL_OSR2_8 3 << 6 39 | 40 | #define QMC6310_VAL_MODE_SET_RESET_ON 0 << 0 41 | #define QMC6310_VAL_MODE_SET_ON 1 << 0 42 | #define QMC6310_VAL_MODE_SET_RESET_OFF 2 << 0 43 | 44 | #define QMC6310_VAL_RNG_30G 0 << 2 45 | #define QMC6310_VAL_RNG_12G 1 << 2 46 | #define QMC6310_VAL_RNG_8G 2 << 2 47 | #define QMC6310_VAL_RNG_2G 3 << 2 48 | 49 | #define QMC6310_VAL_SELF_TEST_ON 1 << 6 50 | #define QMC6310_VAL_SELF_TEST_OFF 0 << 6 51 | 52 | #define QMC6310_VAL_SOFT_RST_ON 1 << 7 53 | #define QMC6310_VAL_SOFT_RST_OFF 0 << 7 54 | //@} 55 | 56 | /** A class. Class of QMC6310 compass sensor */ 57 | class QMC6310{ 58 | public: 59 | /** Construct a new QMC6310 object */ 60 | QMC6310(); 61 | 62 | /** Initialize QMC6310 */ 63 | void init(); 64 | 65 | /** Read values of QMC6310 */ 66 | void read(); 67 | 68 | /** Get x-axis values of QMC6310 */ 69 | int16_t getX(); 70 | 71 | /** Get y-axis values of QMC6310 */ 72 | int16_t getY(); 73 | 74 | /** Get z-axis values of QMC6310 */ 75 | int16_t getZ(); 76 | 77 | /** Get azimuth of QMC6310 */ 78 | uint16_t getAzimuth(); 79 | 80 | /** Set calibration values */ 81 | void setCalibration(int16_t xMin, int16_t xMax, int16_t yMin, int16_t yMax, int16_t zMin, int16_t zMax); 82 | 83 | /** clear calibration values */ 84 | void clearCalibration(); 85 | 86 | private: 87 | /** i2c wite 88 | * 89 | * @param reg byte, register address 90 | * @param val byte, value to write 91 | * 92 | */ 93 | void _i2cWrite(byte reg, byte val); 94 | 95 | /** i2c read data 96 | * 97 | * @param reg byte, register address 98 | * @param num number of bytes to read 99 | * @param dest pointer to store read data 100 | * 101 | * @return Whether the execution is successful 102 | * - true succeed 103 | * - flase failed 104 | */ 105 | bool _i2cReadInto(byte reg, byte num, byte* dest); 106 | 107 | /** whether calibration is in progress */ 108 | bool _calibrated = false; 109 | }; 110 | 111 | #endif // __QMC6310_H__ 112 | -------------------------------------------------------------------------------- /test/qmc6310test/qmc6310test.ino: -------------------------------------------------------------------------------- 1 | #include "qmc6310.h" 2 | 3 | QMC6310 compass; 4 | 5 | int calibrationData[6]; 6 | bool changed = false; 7 | bool done = false; 8 | int t = 0; 9 | int c = 0; 10 | 11 | void setup() { 12 | Serial.begin(115200); 13 | compass.init(); 14 | // calibrateInit(); 15 | compass.setCalibration(2237, 2426, -121, 2529, -3931, -1168); 16 | 17 | Serial.println("Start!"); 18 | } 19 | 20 | int16_t compassGetAzimuth() { 21 | compass.read(); 22 | int16_t y = compass.getY(); 23 | int16_t z = compass.getZ(); 24 | int heading = atan2(y, -z) * RAD_TO_DEG; 25 | return heading; 26 | } 27 | 28 | void loop() { 29 | // calibrate(); 30 | 31 | test(); 32 | } 33 | 34 | void test() { 35 | compass.read(); 36 | Serial.print("x: "); 37 | Serial.print(compass.getX()); 38 | Serial.print(", y: "); 39 | Serial.print(compass.getY()); 40 | Serial.print(", z: "); 41 | Serial.print(compass.getZ()); 42 | Serial.print(", Azimuth YZ: "); 43 | Serial.println(compassGetAzimuth()); 44 | delay(100); 45 | } 46 | 47 | void calibrateInit() { 48 | // Serial.println("This will provide calibration settings for your QMC5883L chip. When prompted, move the magnetometer in all directions until the calibration is complete."); 49 | // Serial.println("Calibration will begin in 5 seconds."); 50 | // delay(5000); 51 | compass.read(); 52 | calibrationData[0] = compass.getX(); 53 | calibrationData[1] = compass.getX(); 54 | calibrationData[2] = compass.getY(); 55 | calibrationData[3] = compass.getY(); 56 | calibrationData[4] = compass.getZ(); 57 | calibrationData[5] = compass.getZ(); 58 | } 59 | 60 | void calibrate() { 61 | int x, y, z; 62 | 63 | // Read compass values 64 | compass.read(); 65 | 66 | // Return XYZ readings 67 | x = compass.getX(); 68 | y = compass.getY(); 69 | z = compass.getZ(); 70 | 71 | changed = false; 72 | 73 | if(x < calibrationData[0]) { 74 | calibrationData[0] = x; 75 | changed = true; 76 | } 77 | if(x > calibrationData[1]) { 78 | calibrationData[1] = x; 79 | changed = true; 80 | } 81 | 82 | if(y < calibrationData[2]) { 83 | calibrationData[2] = y; 84 | changed = true; 85 | } 86 | if(y > calibrationData[3]) { 87 | calibrationData[3] = y; 88 | changed = true; 89 | } 90 | 91 | if(z < calibrationData[4]) { 92 | calibrationData[4] = z; 93 | changed = true; 94 | } 95 | if(z > calibrationData[5]) { 96 | calibrationData[5] = z; 97 | changed = true; 98 | } 99 | 100 | if (changed && !done) { 101 | Serial.println("CALIBRATING... Keep moving your sensor around."); 102 | c = millis(); 103 | } 104 | t = millis(); 105 | 106 | 107 | if ( (t - c > 5000) && !done) { 108 | done = true; 109 | Serial.println("DONE. Copy the line below and paste it into your projects sketch.);"); 110 | Serial.println(); 111 | 112 | Serial.print("compass.setCalibration("); 113 | Serial.print(calibrationData[0]); 114 | Serial.print(", "); 115 | Serial.print(calibrationData[1]); 116 | Serial.print(", "); 117 | Serial.print(calibrationData[2]); 118 | Serial.print(", "); 119 | Serial.print(calibrationData[3]); 120 | Serial.print(", "); 121 | Serial.print(calibrationData[4]); 122 | Serial.print(", "); 123 | Serial.print(calibrationData[5]); 124 | Serial.println(");"); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /examples/15_line_track_field_centric/qmc6310.h: -------------------------------------------------------------------------------- 1 | #ifndef __QMC6310_H__ 2 | #define __QMC6310_H__ 3 | 4 | #include 5 | #include 6 | 7 | /** @name Define I2C address of QMC6310 compass sensor */ 8 | #define QMC6310_ADDR 0x1C 9 | 10 | /** @name Define register address of QMC6310 compass sensor */ 11 | //@{ 12 | #define QMC6310_REG_DATA_START 0x01 13 | #define QMC6310_REG_STATUS 0x09 14 | #define QMC6310_REG_CONTROL_1 0x0A 15 | #define QMC6310_REG_CONTROL_2 0x0B 16 | //@} 17 | 18 | /** @name Define the register parameter configuration of the sensor */ 19 | //@{ 20 | #define QMC6310_VAL_MODE_SUSPEND 0 << 0 21 | #define QMC6310_VAL_MODE_NORMAL 1 << 0 22 | #define QMC6310_VAL_MODE_SINGLE 2 << 0 23 | #define QMC6310_VAL_MODE_CONTINUOUS 3 << 0 24 | 25 | #define QMC6310_VAL_ODR_10HZ 0 << 2 26 | #define QMC6310_VAL_ODR_50HZ 1 << 2 27 | #define QMC6310_VAL_ODR_100HZ 2 << 2 28 | #define QMC6310_VAL_ODR_200HZ 3 << 2 29 | 30 | #define QMC6310_VAL_OSR1_8 0 << 4 31 | #define QMC6310_VAL_OSR1_4 1 << 4 32 | #define QMC6310_VAL_OSR1_2 2 << 4 33 | #define QMC6310_VAL_OSR1_1 3 << 4 34 | 35 | #define QMC6310_VAL_OSR2_1 0 << 6 36 | #define QMC6310_VAL_OSR2_2 1 << 6 37 | #define QMC6310_VAL_OSR2_4 2 << 6 38 | #define QMC6310_VAL_OSR2_8 3 << 6 39 | 40 | #define QMC6310_VAL_MODE_SET_RESET_ON 0 << 0 41 | #define QMC6310_VAL_MODE_SET_ON 1 << 0 42 | #define QMC6310_VAL_MODE_SET_RESET_OFF 2 << 0 43 | 44 | #define QMC6310_VAL_RNG_30G 0 << 2 45 | #define QMC6310_VAL_RNG_12G 1 << 2 46 | #define QMC6310_VAL_RNG_8G 2 << 2 47 | #define QMC6310_VAL_RNG_2G 3 << 2 48 | 49 | #define QMC6310_VAL_SELF_TEST_ON 1 << 6 50 | #define QMC6310_VAL_SELF_TEST_OFF 0 << 6 51 | 52 | #define QMC6310_VAL_SOFT_RST_ON 1 << 7 53 | #define QMC6310_VAL_SOFT_RST_OFF 0 << 7 54 | //@} 55 | 56 | /** A class. Class of QMC6310 compass sensor */ 57 | class QMC6310{ 58 | public: 59 | /** Construct a new QMC6310 object */ 60 | QMC6310(); 61 | 62 | /** Initialize QMC6310 */ 63 | void init(); 64 | 65 | /** Read values of QMC6310 */ 66 | void read(); 67 | 68 | /** Get x-axis values of QMC6310 */ 69 | int16_t getX(); 70 | 71 | /** Get y-axis values of QMC6310 */ 72 | int16_t getY(); 73 | 74 | /** Get z-axis values of QMC6310 */ 75 | int16_t getZ(); 76 | 77 | /** Get azimuth of QMC6310 */ 78 | uint16_t getAzimuth(); 79 | 80 | /** Set calibration values */ 81 | void setCalibration(int16_t xMin, int16_t xMax, int16_t yMin, int16_t yMax, int16_t zMin, int16_t zMax); 82 | 83 | /** clear calibration values */ 84 | void clearCalibration(); 85 | 86 | private: 87 | /** i2c wite 88 | * 89 | * @param reg byte, register address 90 | * @param val byte, value to write 91 | * 92 | */ 93 | void _i2cWrite(byte reg, byte val); 94 | 95 | /** i2c read data 96 | * 97 | * @param reg byte, register address 98 | * @param num number of bytes to read 99 | * @param dest pointer to store read data 100 | * 101 | * @return Whether the execution is successful 102 | * - true succeed 103 | * - flase failed 104 | */ 105 | bool _i2cReadInto(byte reg, byte num, byte* dest); 106 | 107 | /** whether calibration is in progress */ 108 | bool _calibrated = false; 109 | }; 110 | 111 | #endif // __QMC6310_H__ 112 | -------------------------------------------------------------------------------- /examples/1_basic_move/1_basic_move.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | * basic_move 3 | 4 | Control the direction and speed of motors rotation by pwm, 5 | to make the car go forward, backward, left turn, right turn and stop. 6 | 7 | ******************************************************************/ 8 | #include 9 | #include 10 | 11 | /* 12 | * [0]--|||--[1] 13 | * | | 14 | * | | 15 | * | | 16 | * | | 17 | * [3]-------[2] 18 | */ 19 | /** Set the pins for the motors */ 20 | #define MOTOR_PINS \ 21 | (uint8_t[8]) { \ 22 | 3, 4, 5, 6, A3, A2, A1, A0 \ 23 | } 24 | /** Set the positive and negative directions for the motors */ 25 | #define MOTOR_DIRECTIONS \ 26 | (uint8_t[4]) { \ 27 | 1, 0, 0, 1 \ 28 | } 29 | 30 | #define MOTOR_POWER_MIN 28 // 28/255 31 | 32 | int8_t power = 80; 33 | 34 | void setup() { 35 | Serial.begin(115200); 36 | Serial.println("Zeus Car basic move"); 37 | SoftPWMBegin(); //init softpwm, before the motors initialization 38 | carBegin(); // init motors 39 | } 40 | 41 | void loop() { 42 | 43 | carForward(power); 44 | delay(1000); 45 | carBackward(power); 46 | delay(1000); 47 | carLeft(power); 48 | delay(1000); 49 | carRight(power); 50 | delay(1000); 51 | carLeftForward(power); 52 | delay(1000); 53 | carLeftBackward(power); 54 | delay(1000); 55 | carRightForward(power); 56 | delay(1000); 57 | carRightBackward(power); 58 | delay(1000); 59 | carTurnLeft(power); 60 | delay(1000); 61 | carTurnRight(power); 62 | delay(1000); 63 | carStop(); 64 | delay(2000); 65 | } 66 | 67 | 68 | void carBegin() { 69 | for (uint8_t i = 0; i < 8; i++) { 70 | SoftPWMSet(MOTOR_PINS[i], 0); 71 | SoftPWMSetFadeTime(MOTOR_PINS[i], 100, 100); 72 | } 73 | } 74 | 75 | void carSetMotors(int8_t power0, int8_t power1, int8_t power2, int8_t power3) { 76 | bool dir[4]; 77 | int8_t power[4] = { power0, power1, power2, power3 }; 78 | int8_t newPower[4]; 79 | 80 | for (uint8_t i = 0; i < 4; i++) { 81 | dir[i] = power[i] > 0; 82 | 83 | if (MOTOR_DIRECTIONS[i]) dir[i] = !dir[i]; 84 | 85 | if (power[i] == 0) { 86 | newPower[i] = 0; 87 | } else { 88 | newPower[i] = map(abs(power[i]), 0, 100, MOTOR_POWER_MIN, 255); 89 | } 90 | SoftPWMSet(MOTOR_PINS[i * 2], dir[i] * newPower[i]); 91 | SoftPWMSet(MOTOR_PINS[i * 2 + 1], !dir[i] * newPower[i]); 92 | } 93 | } 94 | 95 | void carForward(int8_t power) { 96 | carSetMotors(power, power, power, power); 97 | } 98 | 99 | void carBackward(int8_t power) { 100 | carSetMotors(-power, -power, -power, -power); 101 | } 102 | 103 | void carLeft(int8_t power) { 104 | carSetMotors(-power, power, -power, power); 105 | } 106 | 107 | void carRight(int8_t power) { 108 | carSetMotors(power, -power, power, -power); 109 | } 110 | 111 | void carLeftForward(int8_t power) { 112 | carSetMotors(0, power, 0, power); 113 | } 114 | 115 | void carLeftBackward(int8_t power) { 116 | carSetMotors(-power, 0, -power, 0); 117 | } 118 | 119 | void carRightForward(int8_t power) { 120 | carSetMotors(power, 0, power, 0); 121 | } 122 | 123 | void carRightBackward(int8_t power) { 124 | carSetMotors(0, -power, 0, -power); 125 | } 126 | 127 | void carTurnLeft(int8_t power) { 128 | carSetMotors(-power, power, power, -power); 129 | } 130 | 131 | void carTurnRight(int8_t power) { 132 | carSetMotors(power, -power, -power, power); 133 | } 134 | 135 | void carStop() { 136 | carSetMotors(0, 0, 0, 0); 137 | } -------------------------------------------------------------------------------- /Zeus_Car/qmc6310.cpp: -------------------------------------------------------------------------------- 1 | #include "qmc6310.h" 2 | 3 | int16_t _calibrationData[6]; 4 | 5 | int16_t _x; 6 | int16_t _y; 7 | int16_t _z; 8 | 9 | QMC6310::QMC6310() { 10 | } 11 | 12 | void QMC6310::init() { 13 | Wire.begin(); 14 | Wire.setWireTimeout(100000, true); // 100ms 15 | 16 | this->_i2cWrite(0x29, 0x06); 17 | this->_i2cWrite(QMC6310_REG_CONTROL_2, QMC6310_VAL_RNG_8G); 18 | this->_i2cWrite(QMC6310_REG_CONTROL_1, QMC6310_VAL_MODE_NORMAL | QMC6310_VAL_ODR_200HZ | QMC6310_VAL_OSR1_8 | QMC6310_VAL_OSR2_8); 19 | 20 | } 21 | 22 | void QMC6310::read() { 23 | byte datas[6]; 24 | bool result = this->_i2cReadInto(QMC6310_REG_DATA_START, 6, datas); 25 | if (result == false) return; 26 | 27 | _x = (int16_t)((datas[1] << 8) | datas[0]); 28 | _y = (int16_t)((datas[3] << 8) | datas[2]); 29 | _z = (int16_t)((datas[5] << 8) | datas[4]); 30 | 31 | // calibrate: 32 | if (this->_calibrated) { 33 | int x_offset = (_calibrationData[0] + _calibrationData[1]) / 2; 34 | int y_offset = (_calibrationData[2] + _calibrationData[3]) / 2; 35 | int z_offset = (_calibrationData[4] + _calibrationData[5]) / 2; 36 | float x_avg = (_calibrationData[1] - _calibrationData[0]) / 2.0; 37 | float y_avg = (_calibrationData[3] - _calibrationData[2]) / 2.0; 38 | float z_avg = (_calibrationData[5] - _calibrationData[4]) / 2.0; 39 | 40 | float avg = (x_avg + y_avg + z_avg) / 3; 41 | 42 | float x_scale = avg / x_avg; 43 | float y_scale = avg / y_avg; 44 | float z_scale = avg / z_avg; 45 | 46 | _x = (int16_t)((_x - x_offset) * x_scale); 47 | _y = (int16_t)((_y - y_offset) * y_scale); 48 | _z = (int16_t)((_z - z_offset) * z_scale); 49 | } 50 | } 51 | 52 | int16_t QMC6310::getX() {return _x;} 53 | int16_t QMC6310::getY() {return _y;} 54 | int16_t QMC6310::getZ() {return _z;} 55 | 56 | uint16_t QMC6310::getAzimuth() { 57 | // int16_t azimuth = atan2(_y, _x) * 180.0 / PI; 58 | int16_t azimuth = atan2(_y, _x) * RAD_TO_DEG; 59 | if (azimuth < 0) azimuth += 360; 60 | return azimuth; 61 | } 62 | 63 | void QMC6310::clearCalibration() { 64 | this->_calibrated = false; 65 | } 66 | 67 | void QMC6310::setCalibration(int xMin, int xMax, int yMin, int yMax, int zMin, int zMax) { 68 | this->_calibrated = true; 69 | _calibrationData[0] = xMin; 70 | _calibrationData[1] = xMax; 71 | _calibrationData[2] = yMin; 72 | _calibrationData[3] = yMax; 73 | _calibrationData[4] = zMin; 74 | _calibrationData[5] = zMax; 75 | } 76 | 77 | void QMC6310::_i2cWrite(byte reg, byte val) { 78 | Wire.beginTransmission(QMC6310_ADDR); 79 | Wire.write(reg); 80 | Wire.write(val); 81 | Wire.endTransmission(); 82 | } 83 | 84 | bool QMC6310::_i2cReadInto(byte reg, byte num, byte* dest) { 85 | Wire.beginTransmission(QMC6310_ADDR); 86 | Wire.write(reg); 87 | uint8_t result = Wire.endTransmission(true); 88 | /* 89 | Wire.endTransmission(); 90 | 0: success. 91 | 1: data too long to fit in transmit buffer. 92 | 2: received NACK on transmit of address. 93 | 3: received NACK on transmit of data. 94 | 4: other error. 95 | 5: timeout 96 | */ 97 | if (result != 0) { 98 | return false; 99 | } 100 | 101 | uint8_t rec_len = Wire.requestFrom(QMC6310_ADDR, num, true); 102 | if (rec_len != num) { 103 | return false; 104 | } 105 | 106 | int m = millis(); 107 | while(Wire.available() < num) { 108 | if (millis() - m > 200) { 109 | return false; 110 | } 111 | } 112 | 113 | for(int i = 0; i < num; i++) { 114 | dest[i] = Wire.read(); 115 | } 116 | 117 | return true; 118 | } 119 | 120 | -------------------------------------------------------------------------------- /examples/12_follow/qmc6310.cpp: -------------------------------------------------------------------------------- 1 | #include "qmc6310.h" 2 | 3 | int16_t _calibrationData[6]; 4 | 5 | int16_t _x; 6 | int16_t _y; 7 | int16_t _z; 8 | 9 | QMC6310::QMC6310() { 10 | } 11 | 12 | void QMC6310::init() { 13 | Wire.begin(); 14 | Wire.setWireTimeout(100000, true); // 100ms 15 | 16 | this->_i2cWrite(0x29, 0x06); 17 | this->_i2cWrite(QMC6310_REG_CONTROL_2, QMC6310_VAL_RNG_8G); 18 | this->_i2cWrite(QMC6310_REG_CONTROL_1, QMC6310_VAL_MODE_NORMAL | QMC6310_VAL_ODR_200HZ | QMC6310_VAL_OSR1_8 | QMC6310_VAL_OSR2_8); 19 | 20 | } 21 | 22 | void QMC6310::read() { 23 | byte datas[6]; 24 | bool result = this->_i2cReadInto(QMC6310_REG_DATA_START, 6, datas); 25 | if (result == false) return; 26 | 27 | _x = (int16_t)((datas[1] << 8) | datas[0]); 28 | _y = (int16_t)((datas[3] << 8) | datas[2]); 29 | _z = (int16_t)((datas[5] << 8) | datas[4]); 30 | 31 | // calibrate: 32 | if (this->_calibrated) { 33 | int x_offset = (_calibrationData[0] + _calibrationData[1]) / 2; 34 | int y_offset = (_calibrationData[2] + _calibrationData[3]) / 2; 35 | int z_offset = (_calibrationData[4] + _calibrationData[5]) / 2; 36 | float x_avg = (_calibrationData[1] - _calibrationData[0]) / 2.0; 37 | float y_avg = (_calibrationData[3] - _calibrationData[2]) / 2.0; 38 | float z_avg = (_calibrationData[5] - _calibrationData[4]) / 2.0; 39 | 40 | float avg = (x_avg + y_avg + z_avg) / 3; 41 | 42 | float x_scale = avg / x_avg; 43 | float y_scale = avg / y_avg; 44 | float z_scale = avg / z_avg; 45 | 46 | _x = (int16_t)((_x - x_offset) * x_scale); 47 | _y = (int16_t)((_y - y_offset) * y_scale); 48 | _z = (int16_t)((_z - z_offset) * z_scale); 49 | } 50 | } 51 | 52 | int16_t QMC6310::getX() {return _x;} 53 | int16_t QMC6310::getY() {return _y;} 54 | int16_t QMC6310::getZ() {return _z;} 55 | 56 | uint16_t QMC6310::getAzimuth() { 57 | // int16_t azimuth = atan2(_y, _x) * 180.0 / PI; 58 | int16_t azimuth = atan2(_y, _x) * RAD_TO_DEG; 59 | if (azimuth < 0) azimuth += 360; 60 | return azimuth; 61 | } 62 | 63 | void QMC6310::clearCalibration() { 64 | this->_calibrated = false; 65 | } 66 | 67 | void QMC6310::setCalibration(int xMin, int xMax, int yMin, int yMax, int zMin, int zMax) { 68 | this->_calibrated = true; 69 | _calibrationData[0] = xMin; 70 | _calibrationData[1] = xMax; 71 | _calibrationData[2] = yMin; 72 | _calibrationData[3] = yMax; 73 | _calibrationData[4] = zMin; 74 | _calibrationData[5] = zMax; 75 | } 76 | 77 | void QMC6310::_i2cWrite(byte reg, byte val) { 78 | Wire.beginTransmission(QMC6310_ADDR); 79 | Wire.write(reg); 80 | Wire.write(val); 81 | Wire.endTransmission(); 82 | } 83 | 84 | bool QMC6310::_i2cReadInto(byte reg, byte num, byte* dest) { 85 | Wire.beginTransmission(QMC6310_ADDR); 86 | Wire.write(reg); 87 | uint8_t result = Wire.endTransmission(true); 88 | /* 89 | Wire.endTransmission(); 90 | 0: success. 91 | 1: data too long to fit in transmit buffer. 92 | 2: received NACK on transmit of address. 93 | 3: received NACK on transmit of data. 94 | 4: other error. 95 | 5: timeout 96 | */ 97 | if (result != 0) { 98 | return false; 99 | } 100 | 101 | uint8_t rec_len = Wire.requestFrom(QMC6310_ADDR, num, true); 102 | if (rec_len != num) { 103 | return false; 104 | } 105 | 106 | int m = millis(); 107 | while(Wire.available() < num) { 108 | if (millis() - m > 200) { 109 | return false; 110 | } 111 | } 112 | 113 | for(int i = 0; i < num; i++) { 114 | dest[i] = Wire.read(); 115 | } 116 | 117 | return true; 118 | } 119 | -------------------------------------------------------------------------------- /examples/7_compass/qmc6310.cpp: -------------------------------------------------------------------------------- 1 | #include "qmc6310.h" 2 | 3 | int16_t _calibrationData[6]; 4 | 5 | int16_t _x; 6 | int16_t _y; 7 | int16_t _z; 8 | 9 | QMC6310::QMC6310() { 10 | } 11 | 12 | void QMC6310::init() { 13 | Wire.begin(); 14 | Wire.setWireTimeout(100000, true); // 100ms 15 | 16 | this->_i2cWrite(0x29, 0x06); 17 | this->_i2cWrite(QMC6310_REG_CONTROL_2, QMC6310_VAL_RNG_8G); 18 | this->_i2cWrite(QMC6310_REG_CONTROL_1, QMC6310_VAL_MODE_NORMAL | QMC6310_VAL_ODR_200HZ | QMC6310_VAL_OSR1_8 | QMC6310_VAL_OSR2_8); 19 | 20 | } 21 | 22 | void QMC6310::read() { 23 | byte datas[6]; 24 | bool result = this->_i2cReadInto(QMC6310_REG_DATA_START, 6, datas); 25 | if (result == false) return; 26 | 27 | _x = (int16_t)((datas[1] << 8) | datas[0]); 28 | _y = (int16_t)((datas[3] << 8) | datas[2]); 29 | _z = (int16_t)((datas[5] << 8) | datas[4]); 30 | 31 | // calibrate: 32 | if (this->_calibrated) { 33 | int x_offset = (_calibrationData[0] + _calibrationData[1]) / 2; 34 | int y_offset = (_calibrationData[2] + _calibrationData[3]) / 2; 35 | int z_offset = (_calibrationData[4] + _calibrationData[5]) / 2; 36 | float x_avg = (_calibrationData[1] - _calibrationData[0]) / 2.0; 37 | float y_avg = (_calibrationData[3] - _calibrationData[2]) / 2.0; 38 | float z_avg = (_calibrationData[5] - _calibrationData[4]) / 2.0; 39 | 40 | float avg = (x_avg + y_avg + z_avg) / 3; 41 | 42 | float x_scale = avg / x_avg; 43 | float y_scale = avg / y_avg; 44 | float z_scale = avg / z_avg; 45 | 46 | _x = (int16_t)((_x - x_offset) * x_scale); 47 | _y = (int16_t)((_y - y_offset) * y_scale); 48 | _z = (int16_t)((_z - z_offset) * z_scale); 49 | } 50 | } 51 | 52 | int16_t QMC6310::getX() {return _x;} 53 | int16_t QMC6310::getY() {return _y;} 54 | int16_t QMC6310::getZ() {return _z;} 55 | 56 | uint16_t QMC6310::getAzimuth() { 57 | // int16_t azimuth = atan2(_y, _x) * 180.0 / PI; 58 | int16_t azimuth = atan2(_y, _x) * RAD_TO_DEG; 59 | if (azimuth < 0) azimuth += 360; 60 | return azimuth; 61 | } 62 | 63 | void QMC6310::clearCalibration() { 64 | this->_calibrated = false; 65 | } 66 | 67 | void QMC6310::setCalibration(int xMin, int xMax, int yMin, int yMax, int zMin, int zMax) { 68 | this->_calibrated = true; 69 | _calibrationData[0] = xMin; 70 | _calibrationData[1] = xMax; 71 | _calibrationData[2] = yMin; 72 | _calibrationData[3] = yMax; 73 | _calibrationData[4] = zMin; 74 | _calibrationData[5] = zMax; 75 | } 76 | 77 | void QMC6310::_i2cWrite(byte reg, byte val) { 78 | Wire.beginTransmission(QMC6310_ADDR); 79 | Wire.write(reg); 80 | Wire.write(val); 81 | Wire.endTransmission(); 82 | } 83 | 84 | bool QMC6310::_i2cReadInto(byte reg, byte num, byte* dest) { 85 | Wire.beginTransmission(QMC6310_ADDR); 86 | Wire.write(reg); 87 | uint8_t result = Wire.endTransmission(true); 88 | /* 89 | Wire.endTransmission(); 90 | 0: success. 91 | 1: data too long to fit in transmit buffer. 92 | 2: received NACK on transmit of address. 93 | 3: received NACK on transmit of data. 94 | 4: other error. 95 | 5: timeout 96 | */ 97 | if (result != 0) { 98 | return false; 99 | } 100 | 101 | uint8_t rec_len = Wire.requestFrom(QMC6310_ADDR, num, true); 102 | if (rec_len != num) { 103 | return false; 104 | } 105 | 106 | int m = millis(); 107 | while(Wire.available() < num) { 108 | if (millis() - m > 200) { 109 | return false; 110 | } 111 | } 112 | 113 | for(int i = 0; i < num; i++) { 114 | dest[i] = Wire.read(); 115 | } 116 | 117 | return true; 118 | } 119 | -------------------------------------------------------------------------------- /examples/14_line_track/qmc6310.cpp: -------------------------------------------------------------------------------- 1 | #include "qmc6310.h" 2 | 3 | int16_t _calibrationData[6]; 4 | 5 | int16_t _x; 6 | int16_t _y; 7 | int16_t _z; 8 | 9 | QMC6310::QMC6310() { 10 | } 11 | 12 | void QMC6310::init() { 13 | Wire.begin(); 14 | Wire.setWireTimeout(100000, true); // 100ms 15 | 16 | this->_i2cWrite(0x29, 0x06); 17 | this->_i2cWrite(QMC6310_REG_CONTROL_2, QMC6310_VAL_RNG_8G); 18 | this->_i2cWrite(QMC6310_REG_CONTROL_1, QMC6310_VAL_MODE_NORMAL | QMC6310_VAL_ODR_200HZ | QMC6310_VAL_OSR1_8 | QMC6310_VAL_OSR2_8); 19 | 20 | } 21 | 22 | void QMC6310::read() { 23 | byte datas[6]; 24 | bool result = this->_i2cReadInto(QMC6310_REG_DATA_START, 6, datas); 25 | if (result == false) return; 26 | 27 | _x = (int16_t)((datas[1] << 8) | datas[0]); 28 | _y = (int16_t)((datas[3] << 8) | datas[2]); 29 | _z = (int16_t)((datas[5] << 8) | datas[4]); 30 | 31 | // calibrate: 32 | if (this->_calibrated) { 33 | int x_offset = (_calibrationData[0] + _calibrationData[1]) / 2; 34 | int y_offset = (_calibrationData[2] + _calibrationData[3]) / 2; 35 | int z_offset = (_calibrationData[4] + _calibrationData[5]) / 2; 36 | float x_avg = (_calibrationData[1] - _calibrationData[0]) / 2.0; 37 | float y_avg = (_calibrationData[3] - _calibrationData[2]) / 2.0; 38 | float z_avg = (_calibrationData[5] - _calibrationData[4]) / 2.0; 39 | 40 | float avg = (x_avg + y_avg + z_avg) / 3; 41 | 42 | float x_scale = avg / x_avg; 43 | float y_scale = avg / y_avg; 44 | float z_scale = avg / z_avg; 45 | 46 | _x = (int16_t)((_x - x_offset) * x_scale); 47 | _y = (int16_t)((_y - y_offset) * y_scale); 48 | _z = (int16_t)((_z - z_offset) * z_scale); 49 | } 50 | } 51 | 52 | int16_t QMC6310::getX() {return _x;} 53 | int16_t QMC6310::getY() {return _y;} 54 | int16_t QMC6310::getZ() {return _z;} 55 | 56 | uint16_t QMC6310::getAzimuth() { 57 | // int16_t azimuth = atan2(_y, _x) * 180.0 / PI; 58 | int16_t azimuth = atan2(_y, _x) * RAD_TO_DEG; 59 | if (azimuth < 0) azimuth += 360; 60 | return azimuth; 61 | } 62 | 63 | void QMC6310::clearCalibration() { 64 | this->_calibrated = false; 65 | } 66 | 67 | void QMC6310::setCalibration(int xMin, int xMax, int yMin, int yMax, int zMin, int zMax) { 68 | this->_calibrated = true; 69 | _calibrationData[0] = xMin; 70 | _calibrationData[1] = xMax; 71 | _calibrationData[2] = yMin; 72 | _calibrationData[3] = yMax; 73 | _calibrationData[4] = zMin; 74 | _calibrationData[5] = zMax; 75 | } 76 | 77 | void QMC6310::_i2cWrite(byte reg, byte val) { 78 | Wire.beginTransmission(QMC6310_ADDR); 79 | Wire.write(reg); 80 | Wire.write(val); 81 | Wire.endTransmission(); 82 | } 83 | 84 | bool QMC6310::_i2cReadInto(byte reg, byte num, byte* dest) { 85 | Wire.beginTransmission(QMC6310_ADDR); 86 | Wire.write(reg); 87 | uint8_t result = Wire.endTransmission(true); 88 | /* 89 | Wire.endTransmission(); 90 | 0: success. 91 | 1: data too long to fit in transmit buffer. 92 | 2: received NACK on transmit of address. 93 | 3: received NACK on transmit of data. 94 | 4: other error. 95 | 5: timeout 96 | */ 97 | if (result != 0) { 98 | return false; 99 | } 100 | 101 | uint8_t rec_len = Wire.requestFrom(QMC6310_ADDR, num, true); 102 | if (rec_len != num) { 103 | return false; 104 | } 105 | 106 | int m = millis(); 107 | while(Wire.available() < num) { 108 | if (millis() - m > 200) { 109 | return false; 110 | } 111 | } 112 | 113 | for(int i = 0; i < num; i++) { 114 | dest[i] = Wire.read(); 115 | } 116 | 117 | return true; 118 | } 119 | -------------------------------------------------------------------------------- /examples/17_app_control/qmc6310.cpp: -------------------------------------------------------------------------------- 1 | #include "qmc6310.h" 2 | 3 | int16_t _calibrationData[6]; 4 | 5 | int16_t _x; 6 | int16_t _y; 7 | int16_t _z; 8 | 9 | QMC6310::QMC6310() { 10 | } 11 | 12 | void QMC6310::init() { 13 | Wire.begin(); 14 | Wire.setWireTimeout(100000, true); // 100ms 15 | 16 | this->_i2cWrite(0x29, 0x06); 17 | this->_i2cWrite(QMC6310_REG_CONTROL_2, QMC6310_VAL_RNG_8G); 18 | this->_i2cWrite(QMC6310_REG_CONTROL_1, QMC6310_VAL_MODE_NORMAL | QMC6310_VAL_ODR_200HZ | QMC6310_VAL_OSR1_8 | QMC6310_VAL_OSR2_8); 19 | 20 | } 21 | 22 | void QMC6310::read() { 23 | byte datas[6]; 24 | bool result = this->_i2cReadInto(QMC6310_REG_DATA_START, 6, datas); 25 | if (result == false) return; 26 | 27 | _x = (int16_t)((datas[1] << 8) | datas[0]); 28 | _y = (int16_t)((datas[3] << 8) | datas[2]); 29 | _z = (int16_t)((datas[5] << 8) | datas[4]); 30 | 31 | // calibrate: 32 | if (this->_calibrated) { 33 | int x_offset = (_calibrationData[0] + _calibrationData[1]) / 2; 34 | int y_offset = (_calibrationData[2] + _calibrationData[3]) / 2; 35 | int z_offset = (_calibrationData[4] + _calibrationData[5]) / 2; 36 | float x_avg = (_calibrationData[1] - _calibrationData[0]) / 2.0; 37 | float y_avg = (_calibrationData[3] - _calibrationData[2]) / 2.0; 38 | float z_avg = (_calibrationData[5] - _calibrationData[4]) / 2.0; 39 | 40 | float avg = (x_avg + y_avg + z_avg) / 3; 41 | 42 | float x_scale = avg / x_avg; 43 | float y_scale = avg / y_avg; 44 | float z_scale = avg / z_avg; 45 | 46 | _x = (int16_t)((_x - x_offset) * x_scale); 47 | _y = (int16_t)((_y - y_offset) * y_scale); 48 | _z = (int16_t)((_z - z_offset) * z_scale); 49 | } 50 | } 51 | 52 | int16_t QMC6310::getX() {return _x;} 53 | int16_t QMC6310::getY() {return _y;} 54 | int16_t QMC6310::getZ() {return _z;} 55 | 56 | uint16_t QMC6310::getAzimuth() { 57 | // int16_t azimuth = atan2(_y, _x) * 180.0 / PI; 58 | int16_t azimuth = atan2(_y, _x) * RAD_TO_DEG; 59 | if (azimuth < 0) azimuth += 360; 60 | return azimuth; 61 | } 62 | 63 | void QMC6310::clearCalibration() { 64 | this->_calibrated = false; 65 | } 66 | 67 | void QMC6310::setCalibration(int xMin, int xMax, int yMin, int yMax, int zMin, int zMax) { 68 | this->_calibrated = true; 69 | _calibrationData[0] = xMin; 70 | _calibrationData[1] = xMax; 71 | _calibrationData[2] = yMin; 72 | _calibrationData[3] = yMax; 73 | _calibrationData[4] = zMin; 74 | _calibrationData[5] = zMax; 75 | } 76 | 77 | void QMC6310::_i2cWrite(byte reg, byte val) { 78 | Wire.beginTransmission(QMC6310_ADDR); 79 | Wire.write(reg); 80 | Wire.write(val); 81 | Wire.endTransmission(); 82 | } 83 | 84 | bool QMC6310::_i2cReadInto(byte reg, byte num, byte* dest) { 85 | Wire.beginTransmission(QMC6310_ADDR); 86 | Wire.write(reg); 87 | uint8_t result = Wire.endTransmission(true); 88 | /* 89 | Wire.endTransmission(); 90 | 0: success. 91 | 1: data too long to fit in transmit buffer. 92 | 2: received NACK on transmit of address. 93 | 3: received NACK on transmit of data. 94 | 4: other error. 95 | 5: timeout 96 | */ 97 | if (result != 0) { 98 | return false; 99 | } 100 | 101 | uint8_t rec_len = Wire.requestFrom(QMC6310_ADDR, num, true); 102 | if (rec_len != num) { 103 | return false; 104 | } 105 | 106 | int m = millis(); 107 | while(Wire.available() < num) { 108 | if (millis() - m > 200) { 109 | return false; 110 | } 111 | } 112 | 113 | for(int i = 0; i < num; i++) { 114 | dest[i] = Wire.read(); 115 | } 116 | 117 | return true; 118 | } 119 | -------------------------------------------------------------------------------- /examples/11_obstacle_avoid/qmc6310.cpp: -------------------------------------------------------------------------------- 1 | #include "qmc6310.h" 2 | 3 | int16_t _calibrationData[6]; 4 | 5 | int16_t _x; 6 | int16_t _y; 7 | int16_t _z; 8 | 9 | QMC6310::QMC6310() { 10 | } 11 | 12 | void QMC6310::init() { 13 | Wire.begin(); 14 | Wire.setWireTimeout(100000, true); // 100ms 15 | 16 | this->_i2cWrite(0x29, 0x06); 17 | this->_i2cWrite(QMC6310_REG_CONTROL_2, QMC6310_VAL_RNG_8G); 18 | this->_i2cWrite(QMC6310_REG_CONTROL_1, QMC6310_VAL_MODE_NORMAL | QMC6310_VAL_ODR_200HZ | QMC6310_VAL_OSR1_8 | QMC6310_VAL_OSR2_8); 19 | 20 | } 21 | 22 | void QMC6310::read() { 23 | byte datas[6]; 24 | bool result = this->_i2cReadInto(QMC6310_REG_DATA_START, 6, datas); 25 | if (result == false) return; 26 | 27 | _x = (int16_t)((datas[1] << 8) | datas[0]); 28 | _y = (int16_t)((datas[3] << 8) | datas[2]); 29 | _z = (int16_t)((datas[5] << 8) | datas[4]); 30 | 31 | // calibrate: 32 | if (this->_calibrated) { 33 | int x_offset = (_calibrationData[0] + _calibrationData[1]) / 2; 34 | int y_offset = (_calibrationData[2] + _calibrationData[3]) / 2; 35 | int z_offset = (_calibrationData[4] + _calibrationData[5]) / 2; 36 | float x_avg = (_calibrationData[1] - _calibrationData[0]) / 2.0; 37 | float y_avg = (_calibrationData[3] - _calibrationData[2]) / 2.0; 38 | float z_avg = (_calibrationData[5] - _calibrationData[4]) / 2.0; 39 | 40 | float avg = (x_avg + y_avg + z_avg) / 3; 41 | 42 | float x_scale = avg / x_avg; 43 | float y_scale = avg / y_avg; 44 | float z_scale = avg / z_avg; 45 | 46 | _x = (int16_t)((_x - x_offset) * x_scale); 47 | _y = (int16_t)((_y - y_offset) * y_scale); 48 | _z = (int16_t)((_z - z_offset) * z_scale); 49 | } 50 | } 51 | 52 | int16_t QMC6310::getX() {return _x;} 53 | int16_t QMC6310::getY() {return _y;} 54 | int16_t QMC6310::getZ() {return _z;} 55 | 56 | uint16_t QMC6310::getAzimuth() { 57 | // int16_t azimuth = atan2(_y, _x) * 180.0 / PI; 58 | int16_t azimuth = atan2(_y, _x) * RAD_TO_DEG; 59 | if (azimuth < 0) azimuth += 360; 60 | return azimuth; 61 | } 62 | 63 | void QMC6310::clearCalibration() { 64 | this->_calibrated = false; 65 | } 66 | 67 | void QMC6310::setCalibration(int xMin, int xMax, int yMin, int yMax, int zMin, int zMax) { 68 | this->_calibrated = true; 69 | _calibrationData[0] = xMin; 70 | _calibrationData[1] = xMax; 71 | _calibrationData[2] = yMin; 72 | _calibrationData[3] = yMax; 73 | _calibrationData[4] = zMin; 74 | _calibrationData[5] = zMax; 75 | } 76 | 77 | void QMC6310::_i2cWrite(byte reg, byte val) { 78 | Wire.beginTransmission(QMC6310_ADDR); 79 | Wire.write(reg); 80 | Wire.write(val); 81 | Wire.endTransmission(); 82 | } 83 | 84 | bool QMC6310::_i2cReadInto(byte reg, byte num, byte* dest) { 85 | Wire.beginTransmission(QMC6310_ADDR); 86 | Wire.write(reg); 87 | uint8_t result = Wire.endTransmission(true); 88 | /* 89 | Wire.endTransmission(); 90 | 0: success. 91 | 1: data too long to fit in transmit buffer. 92 | 2: received NACK on transmit of address. 93 | 3: received NACK on transmit of data. 94 | 4: other error. 95 | 5: timeout 96 | */ 97 | if (result != 0) { 98 | return false; 99 | } 100 | 101 | uint8_t rec_len = Wire.requestFrom(QMC6310_ADDR, num, true); 102 | if (rec_len != num) { 103 | return false; 104 | } 105 | 106 | int m = millis(); 107 | while(Wire.available() < num) { 108 | if (millis() - m > 200) { 109 | return false; 110 | } 111 | } 112 | 113 | for(int i = 0; i < num; i++) { 114 | dest[i] = Wire.read(); 115 | } 116 | 117 | return true; 118 | } 119 | -------------------------------------------------------------------------------- /examples/18_app_control_plus/qmc6310.cpp: -------------------------------------------------------------------------------- 1 | #include "qmc6310.h" 2 | 3 | int16_t _calibrationData[6]; 4 | 5 | int16_t _x; 6 | int16_t _y; 7 | int16_t _z; 8 | 9 | QMC6310::QMC6310() { 10 | } 11 | 12 | void QMC6310::init() { 13 | Wire.begin(); 14 | Wire.setWireTimeout(100000, true); // 100ms 15 | 16 | this->_i2cWrite(0x29, 0x06); 17 | this->_i2cWrite(QMC6310_REG_CONTROL_2, QMC6310_VAL_RNG_8G); 18 | this->_i2cWrite(QMC6310_REG_CONTROL_1, QMC6310_VAL_MODE_NORMAL | QMC6310_VAL_ODR_200HZ | QMC6310_VAL_OSR1_8 | QMC6310_VAL_OSR2_8); 19 | 20 | } 21 | 22 | void QMC6310::read() { 23 | byte datas[6]; 24 | bool result = this->_i2cReadInto(QMC6310_REG_DATA_START, 6, datas); 25 | if (result == false) return; 26 | 27 | _x = (int16_t)((datas[1] << 8) | datas[0]); 28 | _y = (int16_t)((datas[3] << 8) | datas[2]); 29 | _z = (int16_t)((datas[5] << 8) | datas[4]); 30 | 31 | // calibrate: 32 | if (this->_calibrated) { 33 | int x_offset = (_calibrationData[0] + _calibrationData[1]) / 2; 34 | int y_offset = (_calibrationData[2] + _calibrationData[3]) / 2; 35 | int z_offset = (_calibrationData[4] + _calibrationData[5]) / 2; 36 | float x_avg = (_calibrationData[1] - _calibrationData[0]) / 2.0; 37 | float y_avg = (_calibrationData[3] - _calibrationData[2]) / 2.0; 38 | float z_avg = (_calibrationData[5] - _calibrationData[4]) / 2.0; 39 | 40 | float avg = (x_avg + y_avg + z_avg) / 3; 41 | 42 | float x_scale = avg / x_avg; 43 | float y_scale = avg / y_avg; 44 | float z_scale = avg / z_avg; 45 | 46 | _x = (int16_t)((_x - x_offset) * x_scale); 47 | _y = (int16_t)((_y - y_offset) * y_scale); 48 | _z = (int16_t)((_z - z_offset) * z_scale); 49 | } 50 | } 51 | 52 | int16_t QMC6310::getX() {return _x;} 53 | int16_t QMC6310::getY() {return _y;} 54 | int16_t QMC6310::getZ() {return _z;} 55 | 56 | uint16_t QMC6310::getAzimuth() { 57 | // int16_t azimuth = atan2(_y, _x) * 180.0 / PI; 58 | int16_t azimuth = atan2(_y, _x) * RAD_TO_DEG; 59 | if (azimuth < 0) azimuth += 360; 60 | return azimuth; 61 | } 62 | 63 | void QMC6310::clearCalibration() { 64 | this->_calibrated = false; 65 | } 66 | 67 | void QMC6310::setCalibration(int xMin, int xMax, int yMin, int yMax, int zMin, int zMax) { 68 | this->_calibrated = true; 69 | _calibrationData[0] = xMin; 70 | _calibrationData[1] = xMax; 71 | _calibrationData[2] = yMin; 72 | _calibrationData[3] = yMax; 73 | _calibrationData[4] = zMin; 74 | _calibrationData[5] = zMax; 75 | } 76 | 77 | void QMC6310::_i2cWrite(byte reg, byte val) { 78 | Wire.beginTransmission(QMC6310_ADDR); 79 | Wire.write(reg); 80 | Wire.write(val); 81 | Wire.endTransmission(); 82 | } 83 | 84 | bool QMC6310::_i2cReadInto(byte reg, byte num, byte* dest) { 85 | Wire.beginTransmission(QMC6310_ADDR); 86 | Wire.write(reg); 87 | uint8_t result = Wire.endTransmission(true); 88 | /* 89 | Wire.endTransmission(); 90 | 0: success. 91 | 1: data too long to fit in transmit buffer. 92 | 2: received NACK on transmit of address. 93 | 3: received NACK on transmit of data. 94 | 4: other error. 95 | 5: timeout 96 | */ 97 | if (result != 0) { 98 | return false; 99 | } 100 | 101 | uint8_t rec_len = Wire.requestFrom(QMC6310_ADDR, num, true); 102 | if (rec_len != num) { 103 | return false; 104 | } 105 | 106 | int m = millis(); 107 | while(Wire.available() < num) { 108 | if (millis() - m > 200) { 109 | return false; 110 | } 111 | } 112 | 113 | for(int i = 0; i < num; i++) { 114 | dest[i] = Wire.read(); 115 | } 116 | 117 | return true; 118 | } 119 | -------------------------------------------------------------------------------- /examples/3_rotate_and_move/3_rotate_and_move.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | * rotate_and_move 3 | 4 | Add rotation based on omni move. 5 | carMove() function adds rotate parameter 6 | 7 | Go forward and turn in different radii. 8 | ******************************************************************/ 9 | #include 10 | #include 11 | 12 | /* 13 | * [0]--|||--[1] 14 | * | | 15 | * | | 16 | * | | 17 | * | | 18 | * [3]-------[2] 19 | */ 20 | /** Set the pins for the motors */ 21 | #define MOTOR_PINS \ 22 | (uint8_t[8]) { \ 23 | 3, 4, 5, 6, A3, A2, A1, A0 \ 24 | } 25 | /** Set the positive and negative directions for the motors */ 26 | #define MOTOR_DIRECTIONS \ 27 | (uint8_t[4]) { \ 28 | 1, 0, 0, 1 \ 29 | } 30 | 31 | #define MOTOR_POWER_MIN 28 // 28/255 32 | 33 | int8_t power = 80; 34 | int8_t rotate_power = 10; 35 | 36 | void setup() { 37 | Serial.begin(115200); 38 | Serial.println("Zeus Car omni-directional move"); 39 | SoftPWMBegin(); //init softpwm, before the motors initialization 40 | carBegin(); // init motors 41 | } 42 | 43 | void loop() { 44 | carMove(0, 0, rotate_power); // anticlockwise rotate 45 | delay(1000); 46 | carMove(0, 0, -rotate_power); // clockwise rotate 47 | delay(1000); 48 | carMove(0, 0, 0); 49 | delay(2000); 50 | for (uint8_t i = 0; i < 65; i += 5) { 51 | rotate_power = i; 52 | carMove(0, power, rotate_power); 53 | delay(1000); 54 | } 55 | carMove(0, 0, 0); 56 | delay(2000); 57 | } 58 | 59 | void carBegin() { 60 | for (uint8_t i = 0; i < 8; i++) { 61 | SoftPWMSet(MOTOR_PINS[i], 0); 62 | SoftPWMSetFadeTime(MOTOR_PINS[i], 100, 100); 63 | } 64 | } 65 | 66 | void carSetMotors(int8_t power0, int8_t power1, int8_t power2, int8_t power3) { 67 | bool dir[4]; 68 | int8_t power[4] = { power0, power1, power2, power3 }; 69 | int8_t newPower[4]; 70 | 71 | for (uint8_t i = 0; i < 4; i++) { 72 | dir[i] = power[i] > 0; 73 | 74 | if (MOTOR_DIRECTIONS[i]) dir[i] = !dir[i]; 75 | 76 | if (power[i] == 0) { 77 | newPower[i] = 0; 78 | } else { 79 | newPower[i] = map(abs(power[i]), 0, 100, MOTOR_POWER_MIN, 255); 80 | } 81 | SoftPWMSet(MOTOR_PINS[i * 2], dir[i] * newPower[i]); 82 | SoftPWMSet(MOTOR_PINS[i * 2 + 1], !dir[i] * newPower[i]); 83 | } 84 | } 85 | 86 | /** 87 | * Control the car to move 88 | * 89 | * @code {.cpp} 90 | * carMove(-90, 80, 0); 91 | * @endcode 92 | * 93 | * @param angle the direction you want the car to move 94 | * @param power moving speed 95 | * @param rot the car fixed rotation angle during the movement 96 | */ 97 | void carMove(int16_t angle, int8_t power, int8_t rot) { 98 | int8_t power_0, power_1, power_2, power_3; 99 | float speed; 100 | // Make forward 0 101 | angle += 90; 102 | // Offset angle as 0 to the front 103 | float rad = angle * PI / 180; 104 | 105 | if (rot == 0) speed = 1; // limit power value over 100 106 | else speed = 0.5; 107 | 108 | power /= sqrt(2); // limit power value over 100 109 | 110 | power_0 = (power * sin(rad) - power * cos(rad)) * speed - rot * speed; 111 | power_1 = (power * sin(rad) + power * cos(rad)) * speed + rot * speed; 112 | power_2 = (power * sin(rad) - power * cos(rad)) * speed + rot * speed; 113 | power_3 = (power * sin(rad) + power * cos(rad)) * speed - rot * speed; 114 | 115 | carSetMotors(power_0, power_1, power_2, power_3); 116 | } 117 | 118 | void carStop() { 119 | carSetMotors(0, 0, 0, 0); 120 | } -------------------------------------------------------------------------------- /examples/8_move_field_centric/qmc6310.cpp: -------------------------------------------------------------------------------- 1 | #include "qmc6310.h" 2 | 3 | int16_t _calibrationData[6]; 4 | 5 | int16_t _x; 6 | int16_t _y; 7 | int16_t _z; 8 | 9 | QMC6310::QMC6310() { 10 | } 11 | 12 | void QMC6310::init() { 13 | Wire.begin(); 14 | Wire.setWireTimeout(100000, true); // 100ms 15 | 16 | this->_i2cWrite(0x29, 0x06); 17 | this->_i2cWrite(QMC6310_REG_CONTROL_2, QMC6310_VAL_RNG_8G); 18 | this->_i2cWrite(QMC6310_REG_CONTROL_1, QMC6310_VAL_MODE_NORMAL | QMC6310_VAL_ODR_200HZ | QMC6310_VAL_OSR1_8 | QMC6310_VAL_OSR2_8); 19 | 20 | } 21 | 22 | void QMC6310::read() { 23 | byte datas[6]; 24 | bool result = this->_i2cReadInto(QMC6310_REG_DATA_START, 6, datas); 25 | if (result == false) return; 26 | 27 | _x = (int16_t)((datas[1] << 8) | datas[0]); 28 | _y = (int16_t)((datas[3] << 8) | datas[2]); 29 | _z = (int16_t)((datas[5] << 8) | datas[4]); 30 | 31 | // calibrate: 32 | if (this->_calibrated) { 33 | int x_offset = (_calibrationData[0] + _calibrationData[1]) / 2; 34 | int y_offset = (_calibrationData[2] + _calibrationData[3]) / 2; 35 | int z_offset = (_calibrationData[4] + _calibrationData[5]) / 2; 36 | float x_avg = (_calibrationData[1] - _calibrationData[0]) / 2.0; 37 | float y_avg = (_calibrationData[3] - _calibrationData[2]) / 2.0; 38 | float z_avg = (_calibrationData[5] - _calibrationData[4]) / 2.0; 39 | 40 | float avg = (x_avg + y_avg + z_avg) / 3; 41 | 42 | float x_scale = avg / x_avg; 43 | float y_scale = avg / y_avg; 44 | float z_scale = avg / z_avg; 45 | 46 | _x = (int16_t)((_x - x_offset) * x_scale); 47 | _y = (int16_t)((_y - y_offset) * y_scale); 48 | _z = (int16_t)((_z - z_offset) * z_scale); 49 | } 50 | } 51 | 52 | int16_t QMC6310::getX() {return _x;} 53 | int16_t QMC6310::getY() {return _y;} 54 | int16_t QMC6310::getZ() {return _z;} 55 | 56 | uint16_t QMC6310::getAzimuth() { 57 | // int16_t azimuth = atan2(_y, _x) * 180.0 / PI; 58 | int16_t azimuth = atan2(_y, _x) * RAD_TO_DEG; 59 | if (azimuth < 0) azimuth += 360; 60 | return azimuth; 61 | } 62 | 63 | void QMC6310::clearCalibration() { 64 | this->_calibrated = false; 65 | } 66 | 67 | void QMC6310::setCalibration(int xMin, int xMax, int yMin, int yMax, int zMin, int zMax) { 68 | this->_calibrated = true; 69 | _calibrationData[0] = xMin; 70 | _calibrationData[1] = xMax; 71 | _calibrationData[2] = yMin; 72 | _calibrationData[3] = yMax; 73 | _calibrationData[4] = zMin; 74 | _calibrationData[5] = zMax; 75 | } 76 | 77 | void QMC6310::_i2cWrite(byte reg, byte val) { 78 | Wire.beginTransmission(QMC6310_ADDR); 79 | Wire.write(reg); 80 | Wire.write(val); 81 | Wire.endTransmission(); 82 | } 83 | 84 | bool QMC6310::_i2cReadInto(byte reg, byte num, byte* dest) { 85 | Wire.beginTransmission(QMC6310_ADDR); 86 | Wire.write(reg); 87 | uint8_t result = Wire.endTransmission(true); 88 | /* 89 | Wire.endTransmission(); 90 | 0: success. 91 | 1: data too long to fit in transmit buffer. 92 | 2: received NACK on transmit of address. 93 | 3: received NACK on transmit of data. 94 | 4: other error. 95 | 5: timeout 96 | */ 97 | if (result != 0) { 98 | return false; 99 | } 100 | 101 | uint8_t rec_len = Wire.requestFrom(QMC6310_ADDR, num, true); 102 | if (rec_len != num) { 103 | return false; 104 | } 105 | 106 | int m = millis(); 107 | while(Wire.available() < num) { 108 | if (millis() - m > 200) { 109 | return false; 110 | } 111 | } 112 | 113 | for(int i = 0; i < num; i++) { 114 | dest[i] = Wire.read(); 115 | } 116 | 117 | return true; 118 | } 119 | -------------------------------------------------------------------------------- /examples/15_line_track_field_centric/qmc6310.cpp: -------------------------------------------------------------------------------- 1 | #include "qmc6310.h" 2 | 3 | int16_t _calibrationData[6]; 4 | 5 | int16_t _x; 6 | int16_t _y; 7 | int16_t _z; 8 | 9 | QMC6310::QMC6310() { 10 | } 11 | 12 | void QMC6310::init() { 13 | Wire.begin(); 14 | Wire.setWireTimeout(100000, true); // 100ms 15 | 16 | this->_i2cWrite(0x29, 0x06); 17 | this->_i2cWrite(QMC6310_REG_CONTROL_2, QMC6310_VAL_RNG_8G); 18 | this->_i2cWrite(QMC6310_REG_CONTROL_1, QMC6310_VAL_MODE_NORMAL | QMC6310_VAL_ODR_200HZ | QMC6310_VAL_OSR1_8 | QMC6310_VAL_OSR2_8); 19 | 20 | } 21 | 22 | void QMC6310::read() { 23 | byte datas[6]; 24 | bool result = this->_i2cReadInto(QMC6310_REG_DATA_START, 6, datas); 25 | if (result == false) return; 26 | 27 | _x = (int16_t)((datas[1] << 8) | datas[0]); 28 | _y = (int16_t)((datas[3] << 8) | datas[2]); 29 | _z = (int16_t)((datas[5] << 8) | datas[4]); 30 | 31 | // calibrate: 32 | if (this->_calibrated) { 33 | int x_offset = (_calibrationData[0] + _calibrationData[1]) / 2; 34 | int y_offset = (_calibrationData[2] + _calibrationData[3]) / 2; 35 | int z_offset = (_calibrationData[4] + _calibrationData[5]) / 2; 36 | float x_avg = (_calibrationData[1] - _calibrationData[0]) / 2.0; 37 | float y_avg = (_calibrationData[3] - _calibrationData[2]) / 2.0; 38 | float z_avg = (_calibrationData[5] - _calibrationData[4]) / 2.0; 39 | 40 | float avg = (x_avg + y_avg + z_avg) / 3; 41 | 42 | float x_scale = avg / x_avg; 43 | float y_scale = avg / y_avg; 44 | float z_scale = avg / z_avg; 45 | 46 | _x = (int16_t)((_x - x_offset) * x_scale); 47 | _y = (int16_t)((_y - y_offset) * y_scale); 48 | _z = (int16_t)((_z - z_offset) * z_scale); 49 | } 50 | } 51 | 52 | int16_t QMC6310::getX() {return _x;} 53 | int16_t QMC6310::getY() {return _y;} 54 | int16_t QMC6310::getZ() {return _z;} 55 | 56 | uint16_t QMC6310::getAzimuth() { 57 | // int16_t azimuth = atan2(_y, _x) * 180.0 / PI; 58 | int16_t azimuth = atan2(_y, _x) * RAD_TO_DEG; 59 | if (azimuth < 0) azimuth += 360; 60 | return azimuth; 61 | } 62 | 63 | void QMC6310::clearCalibration() { 64 | this->_calibrated = false; 65 | } 66 | 67 | void QMC6310::setCalibration(int xMin, int xMax, int yMin, int yMax, int zMin, int zMax) { 68 | this->_calibrated = true; 69 | _calibrationData[0] = xMin; 70 | _calibrationData[1] = xMax; 71 | _calibrationData[2] = yMin; 72 | _calibrationData[3] = yMax; 73 | _calibrationData[4] = zMin; 74 | _calibrationData[5] = zMax; 75 | } 76 | 77 | void QMC6310::_i2cWrite(byte reg, byte val) { 78 | Wire.beginTransmission(QMC6310_ADDR); 79 | Wire.write(reg); 80 | Wire.write(val); 81 | Wire.endTransmission(); 82 | } 83 | 84 | bool QMC6310::_i2cReadInto(byte reg, byte num, byte* dest) { 85 | Wire.beginTransmission(QMC6310_ADDR); 86 | Wire.write(reg); 87 | uint8_t result = Wire.endTransmission(true); 88 | /* 89 | Wire.endTransmission(); 90 | 0: success. 91 | 1: data too long to fit in transmit buffer. 92 | 2: received NACK on transmit of address. 93 | 3: received NACK on transmit of data. 94 | 4: other error. 95 | 5: timeout 96 | */ 97 | if (result != 0) { 98 | return false; 99 | } 100 | 101 | uint8_t rec_len = Wire.requestFrom(QMC6310_ADDR, num, true); 102 | if (rec_len != num) { 103 | return false; 104 | } 105 | 106 | int m = millis(); 107 | while(Wire.available() < num) { 108 | if (millis() - m > 200) { 109 | return false; 110 | } 111 | } 112 | 113 | for(int i = 0; i < num; i++) { 114 | dest[i] = Wire.read(); 115 | } 116 | 117 | return true; 118 | } 119 | -------------------------------------------------------------------------------- /examples/4_drift/4_drift.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | * drift 3 | 4 | Add drift based on rotate_and_move. 5 | carMove() function adds drift parameter 6 | 7 | Drift left and right. 8 | 9 | ******************************************************************/ 10 | #include 11 | #include 12 | 13 | /* 14 | * [0]--|||--[1] 15 | * | | 16 | * | | 17 | * | | 18 | * | | 19 | * [3]-------[2] 20 | */ 21 | /** Set the pins for the motors */ 22 | #define MOTOR_PINS (uint8_t[8]){3, 4, 5, 6, A3, A2, A1, A0} 23 | /** Set the positive and negative directions for the motors */ 24 | #define MOTOR_DIRECTIONS (uint8_t[4]){1, 0, 0, 1} 25 | 26 | #define MOTOR_POWER_MIN 28 // 28/255 27 | 28 | int8_t power = 80; 29 | 30 | void setup() { 31 | Serial.begin(115200); 32 | Serial.println("Zeus Car drift test"); 33 | SoftPWMBegin(); //init softpwm, before the motors initialization 34 | carBegin(); // init motors 35 | } 36 | 37 | void loop() { 38 | carMove(0, power, 0, 0); 39 | delay(500); 40 | carMove(0, power, 45, true); 41 | delay(600); 42 | } 43 | 44 | void carBegin() { 45 | for (uint8_t i = 0; i < 8; i++) { 46 | SoftPWMSet(MOTOR_PINS[i], 0); 47 | SoftPWMSetFadeTime(MOTOR_PINS[i], 100, 100); 48 | } 49 | } 50 | 51 | void carSetMotors(int8_t power0, int8_t power1, int8_t power2, int8_t power3) { 52 | bool dir[4]; 53 | int8_t power[4] = {power0, power1, power2, power3}; 54 | int8_t newPower[4]; 55 | 56 | for (uint8_t i = 0; i < 4; i++) { 57 | dir[i] = power[i] > 0; 58 | 59 | if (MOTOR_DIRECTIONS[i]) dir[i] = !dir[i]; 60 | 61 | if (power[i] == 0) { 62 | newPower[i] = 0; 63 | } else { 64 | newPower[i] = map(abs(power[i]), 0, 100, MOTOR_POWER_MIN, 255); 65 | } 66 | SoftPWMSet(MOTOR_PINS[i*2], dir[i] * newPower[i]); 67 | SoftPWMSet(MOTOR_PINS[i*2+1], !dir[i] * newPower[i]); 68 | } 69 | } 70 | 71 | /** 72 | * Control the car to move 73 | * 74 | * @code {.cpp} 75 | * carMove(-90, 80, 0); 76 | * @endcode 77 | * 78 | * @param angle the direction you want the car to move 79 | * @param power moving speed 80 | * @param rot the car fixed rotation angle during the movement 81 | * @param drift Whether it is a drift mode, default flase 82 | * true, drift mode, the car body will return to square 83 | * flase, drift mode, the car body will not return to square 84 | */ 85 | void carMove(int16_t angle, int8_t power, int8_t rot, bool drift) { 86 | int8_t power_0, power_1, power_2, power_3; 87 | float speed; 88 | // Make forward 0 89 | angle += 90; 90 | // Offset angle as 0 to the front 91 | float rad = angle * PI / 180; 92 | 93 | if (rot == 0) speed = 1; 94 | else speed = 0.5; 95 | 96 | power /= sqrt(2); 97 | // Calculate 4 wheel 98 | if (drift) { 99 | power_0 = (power * sin(rad) - power * cos(rad)) * speed; 100 | power_1 = (power * sin(rad) + power * cos(rad)) * speed; 101 | power_2 = (power * sin(rad) - power * cos(rad)) * speed + rot * speed * 2; 102 | power_3 = (power * sin(rad) + power * cos(rad)) * speed - rot * speed * 2; 103 | } else { 104 | power_0 = (power * sin(rad) - power * cos(rad)) * speed - rot * speed; 105 | power_1 = (power * sin(rad) + power * cos(rad)) * speed + rot * speed; 106 | power_2 = (power * sin(rad) - power * cos(rad)) * speed + rot * speed; 107 | power_3 = (power * sin(rad) + power * cos(rad)) * speed - rot * speed; 108 | } 109 | 110 | carSetMotors(power_0, power_1, power_2, power_3); 111 | 112 | } 113 | -------------------------------------------------------------------------------- /examples/16_ai_detection_from_app/ai_camera.h: -------------------------------------------------------------------------------- 1 | #ifndef __AI_CAMERA_H__ 2 | #define __AI_CAMERA_H__ 3 | 4 | #include 5 | #include 6 | 7 | 8 | /** 9 | * @name Set the print level of information received by esp32-cam 10 | * 11 | * @code {.cpp} 12 | * #define CAM_DEBUG_LEVEL CAM_DEBUG_LEVEL_INFO 13 | * @endcode 14 | * 15 | */ 16 | #define CAM_DEBUG_LEVEL CAM_DEBUG_LEVEL_INFO 17 | #define CAM_DEBUG_LEVEL_OFF 0 18 | #define CAM_DEBUG_LEVEL_ERROR 1 19 | #define CAM_DEBUG_LEVEL_INFO 2 20 | #define CAM_DEBUG_LEVEL_DEBUG 3 21 | #define CAM_DEBUG_LEVEL_ALL 4 22 | 23 | #define CAM_DEBUG_HEAD_ALL "[CAM_A]" 24 | #define CAM_DEBUG_HEAD_ERROR "[CAM_E]" 25 | #define CAM_DEBUG_HEAD_INFO "[CAM_I]" 26 | #define CAM_DEBUG_HEAD_DEBUG "[CAM_D]" 27 | 28 | /** 29 | * @name Define component-related values 30 | */ 31 | #define DPAD_STOP 0 32 | #define DPAD_FORWARD 1 33 | #define DPAD_BACKWARD 2 34 | #define DPAD_LEFT 3 35 | #define DPAD_RIGHT 4 36 | 37 | #define JOYSTICK_X 0 38 | #define JOYSTICK_Y 1 39 | #define JOYSTICK_ANGLE 2 40 | #define JOYSTICK_RADIUS 3 41 | 42 | #define WIFI_MODE_NONE "0" 43 | #define WIFI_MODE_STA "1" 44 | #define WIFI_MODE_AP "2" 45 | 46 | #define REGION_A 0 47 | #define REGION_B 1 48 | #define REGION_C 2 49 | #define REGION_D 3 50 | #define REGION_E 4 51 | #define REGION_F 5 52 | #define REGION_G 6 53 | #define REGION_H 7 54 | #define REGION_I 8 55 | #define REGION_J 9 56 | #define REGION_K 10 57 | #define REGION_L 11 58 | #define REGION_M 12 59 | #define REGION_N 13 60 | #define REGION_O 14 61 | #define REGION_P 15 62 | #define REGION_Q 16 63 | #define REGION_R 17 64 | #define REGION_S 18 65 | #define REGION_T 19 66 | #define REGION_U 20 67 | #define REGION_V 21 68 | #define REGION_W 22 69 | #define REGION_X 23 70 | #define REGION_Y 24 71 | #define REGION_Z 25 72 | 73 | 74 | class AiCamera { 75 | public: 76 | AiCamera(const char* name, const char* type); 77 | 78 | void begin(const char* ssid, const char* password, const char* wifiMode, const char* wsPort); 79 | void debug(char* msg); 80 | void readInto(char* buffer); 81 | void sendData(char* buf); 82 | void command(const char* command, const char* value, char* result) ; 83 | void set(const char* command); 84 | void set(const char* command, const char* value); 85 | void get(const char* command, char* result); 86 | void get(const char* command, const char* value, char* result); 87 | void setOnReceived(void (*func)(char*, char*)); 88 | void loop(); 89 | 90 | int16_t getSlider(char* buf, uint8_t region); 91 | bool getButton(char* buf, uint8_t region); 92 | bool getSwitch(char* buf, uint8_t region); 93 | int16_t getJoystick(char* buf, uint8_t region, uint8_t axis); 94 | uint8_t getDPad(char* buf, uint8_t region); 95 | int16_t getThrottle(char* buf, uint8_t region); 96 | void setMeter(char* buf, uint8_t region, double value); 97 | void setRadar(char* buf, uint8_t region, int16_t angle, double distance); 98 | void setGreyscale(char* buf, uint8_t region, uint16_t value1, uint16_t value2, uint16_t value3); 99 | void setValue(char* buf, uint8_t region, double value); 100 | void getSpeech(char* buf, uint8_t region, char* result); 101 | 102 | private: 103 | void subString(char* str, int16_t start, int16_t end=-1); 104 | void getStrOf(char* str, uint8_t index, char* result, char divider); 105 | void setStrOf(char* str, uint8_t index, String value, char divider=';'); 106 | int16_t getIntOf(char* str, uint8_t index, char divider=';'); 107 | bool getBoolOf(char* str, uint8_t index); 108 | double getDoubleOf(char* str, uint8_t index); 109 | }; 110 | 111 | #endif // __AI_CAMERA_H__ 112 | -------------------------------------------------------------------------------- /examples/5_remote_control/car_control.cpp: -------------------------------------------------------------------------------- 1 | #include "car_control.h" 2 | 3 | #include 4 | #include 5 | 6 | #define MOTOR_POWER_MIN 28 // 28/255 7 | 8 | /** 9 | * @brief Initialize the motor, and (block) the initialization compass 10 | */ 11 | void carBegin() { 12 | for (uint8_t i = 0; i < 8; i++) { 13 | SoftPWMSet(MOTOR_PINS[i], 0); 14 | SoftPWMSetFadeTime(MOTOR_PINS[i], 100, 100); 15 | } 16 | } 17 | 18 | /** 19 | * @name simple move functions with CAR_DEFAULT_POWER 20 | */ 21 | void carForward(int8_t power) { carMove( 0, power, 0); } 22 | void carBackward(int8_t power) { carMove( 180, power, 0); } 23 | void carLeft(int8_t power) { carMove( -90, power, 0); } 24 | void carRight(int8_t power) { carMove( 90, power, 0); } 25 | void carTurnLeft(int8_t power) { carMove( 0, 0, power); } 26 | void carTurnRight(int8_t power) { carMove( 0, 0, -power); } 27 | void carLeftForward(int8_t power) { carMove( -45, power, 0); } 28 | void carRightForward(int8_t power) { carMove( 45, power, 0); } 29 | void carLeftBackward(int8_t power) { carMove(-135, power, 0); } 30 | void carRightBackward(int8_t power) { carMove( 135, power, 0); } 31 | void carStop() { carMove( 0, 0, 0); } 32 | 33 | /** 34 | * @brief Set speed for 4 motors 35 | * 36 | * @param power0 0 ~ 100 37 | * @param power1 0 ~ 100 38 | * @param power2 0 ~ 100 39 | * @param power3 0 ~ 100 40 | */ 41 | void carSetMotors(int8_t power0, int8_t power1, int8_t power2, int8_t power3) { 42 | bool dir[4]; 43 | int8_t power[4] = {power0, power1, power2, power3}; 44 | int8_t newPower[4]; 45 | 46 | for (uint8_t i = 0; i < 4; i++) { 47 | dir[i] = power[i] > 0; 48 | 49 | if (MOTOR_DIRECTIONS[i]) dir[i] = !dir[i]; 50 | 51 | if (power[i] == 0) { 52 | newPower[i] = 0; 53 | } else { 54 | newPower[i] = map(abs(power[i]), 0, 100, MOTOR_POWER_MIN, 255); 55 | } 56 | SoftPWMSet(MOTOR_PINS[i*2], dir[i] * newPower[i]); 57 | SoftPWMSet(MOTOR_PINS[i*2+1], !dir[i] * newPower[i]); 58 | } 59 | } 60 | 61 | /** 62 | * Control the car to move 63 | * 64 | * @code {.cpp} 65 | * carMove(-90, 80, 0); 66 | * @endcode 67 | * 68 | * @param angle the direction you want the car to move 69 | * @param power moving speed 70 | * @param rot the car fixed rotation angle during the movement 71 | * @param drift Whether it is a drift mode, default flase 72 | * true, drift mode, the car body will return to square 73 | * flase, drift mode, the car body will not return to square 74 | */ 75 | void carMove(int16_t angle, int8_t power, int8_t rot, bool drift) { 76 | int8_t power_0, power_1, power_2, power_3; 77 | float speed; 78 | // Make forward 0 79 | angle += 90; 80 | // Offset angle as 0 to the front 81 | float rad = angle * PI / 180; 82 | 83 | if (rot == 0) speed = 1; 84 | else speed = 0.5; 85 | 86 | power /= sqrt(2); 87 | // Calculate 4 wheel 88 | if (drift) { 89 | power_0 = (power * sin(rad) - power * cos(rad)) * speed; 90 | power_1 = (power * sin(rad) + power * cos(rad)) * speed; 91 | power_2 = (power * sin(rad) - power * cos(rad)) * speed + rot * speed * 2; 92 | power_3 = (power * sin(rad) + power * cos(rad)) * speed - rot * speed * 2; 93 | } else { 94 | power_0 = (power * sin(rad) - power * cos(rad)) * speed - rot * speed; 95 | power_1 = (power * sin(rad) + power * cos(rad)) * speed + rot * speed; 96 | power_2 = (power * sin(rad) - power * cos(rad)) * speed + rot * speed; 97 | power_3 = (power * sin(rad) + power * cos(rad)) * speed - rot * speed; 98 | } 99 | 100 | carSetMotors(power_0, power_1, power_2, power_3); 101 | 102 | } 103 | -------------------------------------------------------------------------------- /examples/17_app_control/17_app_control.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | * APP control 3 | 4 | Use esp32-cam to communicate with the app via wifi to control the car 5 | 6 | 1. Note: 7 | when downloading the code, you need to set the switch on the expansion board to upload, 8 | and when running, you need to set the switch to cam. 9 | 2. Firstly, set the wifi, name, etc., send the service command to esp32-cam, 10 | esp32-cam will open the websocket server and communicate with app after 11 | screensuccessfully connect to the wifi, and also open the webcam 12 | 3. use the left stick to control the direction of movement, 13 | the right stick to control the direction of the front of the car, 14 | switch to control enable drift 15 | 16 | ******************************************************************/ 17 | #include 18 | #include "rgb.h" 19 | #include "car_control.h" 20 | #include "ai_camera.h" 21 | 22 | /** Configure Wifi AP mode,SSID, password*/ 23 | #define WIFI_MODE WIFI_MODE_AP 24 | #define SSID "Zeus_Car" 25 | #define PASSWORD "12345678" 26 | 27 | /** Configure Wifi STA mode,SSID, password*/ 28 | // #define WIFI_MODE WIFI_MODE_STA 29 | // #define SSID "xxxxxxxxxx" 30 | // #define PASSWORD "xxxxxxxxxx" 31 | 32 | /** Configure product name and type*/ 33 | #define NAME "Zeus_Car" 34 | #define TYPE "Zeus_Car" 35 | 36 | /* Configure websockets port 37 | * - Sunfounder Controller APP fixed using port 8765 38 | */ 39 | #define PORT "8765" 40 | 41 | /** Instantiate aicamera, a class for serial communication with ESP32-CAM */ 42 | AiCamera aiCam = AiCamera(NAME, TYPE); 43 | 44 | /*********************** Global variables ****************************/ 45 | int16_t remoteAngle; 46 | int16_t remotePower; 47 | int16_t remoteHeading; 48 | int16_t remoteHeadingR; 49 | bool remoteDriftEnable; 50 | 51 | /*********************** setup() & loop() ************************/ 52 | void setup() { 53 | int m = millis(); 54 | Serial.begin(115200); 55 | rgbBegin(); 56 | rgbWrite(0xFF2500); // orange 57 | carBegin(); 58 | 59 | aiCam.begin(SSID, PASSWORD, WIFI_MODE, PORT); 60 | aiCam.setOnReceived(onReceive); 61 | 62 | while (millis() - m < 500) { // Wait for peripherals to be ready 63 | delay(1); 64 | } 65 | 66 | Serial.println(F("Okie!")); 67 | rgbWrite(0x0AFF0A); // green 68 | 69 | } 70 | 71 | void loop() { 72 | aiCam.loop(); 73 | carMoveFieldCentric(remoteAngle, remotePower, remoteHeading, remoteDriftEnable); 74 | 75 | } 76 | 77 | /***************************** Functions ******************************/ 78 | /** 79 | * websocket received data processing 80 | */ 81 | void onReceive(char* recvBuf, char* sendBuf) { 82 | 83 | //Joystick [K] 84 | uint16_t angle = aiCam.getJoystick(recvBuf, REGION_K, JOYSTICK_ANGLE); 85 | uint8_t power = aiCam.getJoystick(recvBuf, REGION_K, JOYSTICK_RADIUS); 86 | power = map(power, 0, 100, 0, CAR_DEFAULT_POWER); 87 | if (remoteAngle != angle) { 88 | remoteAngle = angle; 89 | } 90 | if (remotePower != power) { 91 | remotePower = power; 92 | } 93 | 94 | // Drift [J] 95 | // Serial.print("Drift:");Serial.println(remoteDriftEnable); 96 | if (remoteDriftEnable != aiCam.getSwitch(recvBuf, REGION_J)) { 97 | remoteDriftEnable = !remoteDriftEnable; 98 | } 99 | 100 | // MoveHead [Q] 101 | int moveHeadingA = aiCam.getJoystick(recvBuf, REGION_Q, JOYSTICK_ANGLE); 102 | int16_t moveHeadingR = aiCam.getJoystick(recvBuf, REGION_Q, JOYSTICK_RADIUS); 103 | if ((remoteHeading != moveHeadingA) || (remoteHeadingR != moveHeadingR)){ 104 | remoteHeading = moveHeadingA; 105 | remoteHeadingR = moveHeadingR; 106 | if (remoteDriftEnable && moveHeadingR == 0) { // Drift mode 107 | carResetHeading(); 108 | remoteHeading = 0; 109 | } 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # Zeus Car 2 | The control program of the Ardunio Mecanum wheel car for Ardunio UNO. 3 | 4 | Zeur Car is a omnidirectional moving car with Macnum wheels.It is controlled by Ardunio UNO and ESP32-CAM, with FPV controller, line patrol, obstacle avoidance and many other interesting functions.You can buy it on [our website](https://www.sunfounder.com/), or search sunfounder in Amazon. 5 | 6 | - [Zeus Car](#zeus-car) 7 | - [Development test environment](#development-test-environment) 8 | - [Dependency libraries](#dependency-libraries) 9 | - [ESP32-CAM firmware](#esp32-cam-firmware) 10 | - [Docs](#docs) 11 | - [Project Tree](#project-tree) 12 | - [About SunFounder](#about-sunfounder) 13 | - [Contact us](#contact-us) 14 | ## Development test environment 15 | - Board: Ardunio UNO 16 | - IDE: Arduino IDE 1.8.19 17 | - Compiler Tools: Arduino AVR Boards 1.8.3 18 | 19 | ## Dependency libraries 20 | - IRLremote 21 | - SoftPWM 22 | - ArduinoJson 23 | 24 | ## ESP32-CAM firmware 25 | https://github.com/sunfounder/ai-camera-firmware 26 | ## Docs 27 | https://docs.sunfounder.com 28 | 29 | ## Project Tree 30 | ``` 31 | zeus-car 32 | ├─ Zeus_Car // 33 | │ ├─ Zeus_Car.h // macro definition of some variables 34 | │ ├─ Zeus_Car.ino // Arduino main program 35 | │ ├─ ai_camera.cpp // functions for communicating with ESP32-CAM 36 | │ ├─ ai_camera.h // 37 | │ ├─ car_control.cpp // functions for controll motors 38 | │ ├─ car_control.h // 39 | │ ├─ cmd_code_config.hpp // the command table for voice control and IR control 40 | │ ├─ compass.cpp // functions for compass sensor 41 | │ ├─ compass.h // 42 | │ ├─ grayscale.cpp // functions for grayscale line patrol module 43 | │ ├─ grayscale.h // 44 | │ ├─ hc165.cpp // functions for HC165 - IO expansion chip 45 | │ ├─ hc165.h // 46 | │ ├─ ir_obstacle.cpp // functions for IR obstacle avoidance module 47 | │ ├─ ir_obstacle.h // 48 | │ ├─ ir_remote.cpp // functions for IR remote 49 | │ ├─ ir_remote.h // 50 | │ ├─ qmc6310.cpp // functions for compass sensor 51 | │ ├─ qmc6310.h // 52 | │ ├─ rgb.cpp // functions for rgb led strip 53 | │ ├─ rgb.h // 54 | │ ├─ test.h // functions for testing all modules 55 | │ ├─ ultrasonic.cpp // functions for ultrasonic module 56 | │ └─ ultrasonic.h // 57 | ├─ test 58 | │ ├─ grayscale_pattern_classifier.py // status enumeration tool for 8-way line patrol module 59 | │ ├─ qmc6310test // 60 | │ │ ├─ qmc6310.cpp // 61 | │ │ ├─ qmc6310.h // 62 | │ │ └─ qmc6310test.ino // 63 | │ └─ test.ino // 64 | ├─ .gitignore // 65 | ├─ LICENSE // 66 | └─ Readme.md 67 | ``` 68 | ## About SunFounder 69 | SunFounder is a company focused on STEAM education with products like open source robots, development boards, STEAM kit, modules, tools and other smart devices distributed globally. In SunFounder, we strive to help elementary and middle school students as well as hobbyists, through STEAM education, strengthen their hands-on practices and problem-solving abilities. In this way, we hope to disseminate knowledge and provide skill training in a full-of-joy way, thus fostering your interest in programming and making, and exposing you to a fascinating world of science and engineering. To embrace the future of artificial intelligence, it is urgent and meaningful to learn abundant STEAM knowledge. 70 | 71 | ## Contact us 72 | website: 73 | www.sunfounder.com 74 | 75 | E-mail: 76 | service@sunfounder.com 77 | -------------------------------------------------------------------------------- /Zeus_Car/ai_camera.h: -------------------------------------------------------------------------------- 1 | #ifndef __AI_CAMERA_H__ 2 | #define __AI_CAMERA_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | /** 9 | * Use custom serial port 10 | */ 11 | // #define AI_CAM_DEBUG_CUSTOM 12 | #ifdef AI_CAM_DEBUG_CUSTOM 13 | #include 14 | SoftwareSerial dSerial(10, 11); // RX, TX 15 | #define DateSerial dSerial 16 | #define DebugSerial Serial 17 | #else 18 | #define DateSerial Serial 19 | #define DebugSerial Serial 20 | #endif 21 | 22 | /** 23 | * Set SERIAL_TIMEOUT & WS_BUFFER_SIZE 24 | */ 25 | #define SERIAL_TIMEOUT 100 26 | #define WS_BUFFER_SIZE 200 27 | #define CHAR_TIMEOUT 50 28 | 29 | /** 30 | * Some keywords for communication with ESP32-CAM 31 | */ 32 | #define CHECK "SC" 33 | #define OK_FLAG "[OK]" 34 | #define ERROR_FLAG "[ERR]" 35 | #define WS_HEADER "WS+" 36 | #define CAM_INIT "[Init]" 37 | #define WS_CONNECT "[CONNECTED]" 38 | #define WS_DISCONNECT "[DISCONNECTED]" 39 | #define APP_STOP "[APPSTOP]" 40 | 41 | /** 42 | * @name Set the print level of information received by esp32-cam 43 | * 44 | * @code {.cpp} 45 | * #define CAM_DEBUG_LEVEL CAM_DEBUG_LEVEL_INFO 46 | * @endcode 47 | * 48 | */ 49 | #define CAM_DEBUG_LEVEL CAM_DEBUG_LEVEL_INFO 50 | #define CAM_DEBUG_LEVEL_OFF 0 51 | #define CAM_DEBUG_LEVEL_ERROR 1 52 | #define CAM_DEBUG_LEVEL_INFO 2 53 | #define CAM_DEBUG_LEVEL_DEBUG 3 54 | #define CAM_DEBUG_LEVEL_ALL 4 55 | 56 | #define CAM_DEBUG_HEAD_ALL "[CAM_A]" 57 | #define CAM_DEBUG_HEAD_ERROR "[CAM_E]" 58 | #define CAM_DEBUG_HEAD_INFO "[CAM_I]" 59 | #define CAM_DEBUG_HEAD_DEBUG "[CAM_D]" 60 | 61 | /** 62 | * @name Define component-related values 63 | */ 64 | #define DPAD_STOP 0 65 | #define DPAD_FORWARD 1 66 | #define DPAD_BACKWARD 2 67 | #define DPAD_LEFT 3 68 | #define DPAD_RIGHT 4 69 | 70 | #define JOYSTICK_X 0 71 | #define JOYSTICK_Y 1 72 | #define JOYSTICK_ANGLE 2 73 | #define JOYSTICK_RADIUS 3 74 | 75 | #define WIFI_MODE_NONE "0" 76 | #define WIFI_MODE_STA "1" 77 | #define WIFI_MODE_AP "2" 78 | 79 | #define REGION_A 0 80 | #define REGION_B 1 81 | #define REGION_C 2 82 | #define REGION_D 3 83 | #define REGION_E 4 84 | #define REGION_F 5 85 | #define REGION_G 6 86 | #define REGION_H 7 87 | #define REGION_I 8 88 | #define REGION_J 9 89 | #define REGION_K 10 90 | #define REGION_L 11 91 | #define REGION_M 12 92 | #define REGION_N 13 93 | #define REGION_O 14 94 | #define REGION_P 15 95 | #define REGION_Q 16 96 | #define REGION_R 17 97 | #define REGION_S 18 98 | #define REGION_T 19 99 | #define REGION_U 20 100 | #define REGION_V 21 101 | #define REGION_W 22 102 | #define REGION_X 23 103 | #define REGION_Y 24 104 | #define REGION_Z 25 105 | 106 | class AiCamera 107 | { 108 | public: 109 | bool ws_connected = false; 110 | char recvBuffer[WS_BUFFER_SIZE]; 111 | StaticJsonDocument<200> send_doc; 112 | 113 | AiCamera(const char *name, const char *type); 114 | void begin(const char *ssid, const char *password, const char *wifiMode, const char *wsPort); 115 | void setOnReceived(void (*func)(char *, char *)); 116 | 117 | void set_command_timeout(uint32_t _timeout); 118 | void readInto(char *buffer); 119 | void loop(); 120 | void sendData(); 121 | 122 | void debug(char *msg); 123 | 124 | void set(const char *command, bool wait = true); 125 | void set(const char *command, const char *value, bool wait = true); 126 | void get(const char *command, char *result); 127 | void get(const char *command, const char *value, char *result); 128 | 129 | int16_t getSlider(uint8_t region); 130 | bool getButton(uint8_t region); 131 | bool getSwitch(uint8_t region); 132 | int16_t getJoystick(uint8_t region, uint8_t axis); 133 | uint8_t getDPad(uint8_t region); 134 | int16_t getThrottle(uint8_t region); 135 | void setMeter(uint8_t region, double value); 136 | void setRadar(uint8_t region, int16_t angle, double distance); 137 | void setGreyscale(uint8_t region, uint16_t value1, uint16_t value2, uint16_t value3); 138 | void setValue(uint8_t region, double value); 139 | void getSpeech(uint8_t region, char *result); 140 | 141 | void lamp_on(uint8_t level = 5); 142 | void lamp_off(void); 143 | 144 | private: 145 | void command(const char *command, const char *value, char *result, bool wait = true); 146 | void subString(char *str, int16_t start, int16_t end = -1); 147 | 148 | void getStrOf(char *str, uint8_t index, char *result, char divider); 149 | void setStrOf(char *str, uint8_t index, String value, char divider = ';'); 150 | int16_t getIntOf(char *str, uint8_t index, char divider = ';'); 151 | bool getBoolOf(char *str, uint8_t index); 152 | double getDoubleOf(char *str, uint8_t index); 153 | }; 154 | 155 | #endif // __AI_CAMERA_H__ 156 | -------------------------------------------------------------------------------- /examples/17_app_control/ai_camera.h: -------------------------------------------------------------------------------- 1 | #ifndef __AI_CAMERA_H__ 2 | #define __AI_CAMERA_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | /** 9 | * Use custom serial port 10 | */ 11 | // #define AI_CAM_DEBUG_CUSTOM 12 | #ifdef AI_CAM_DEBUG_CUSTOM 13 | #include 14 | SoftwareSerial dSerial(10, 11); // RX, TX 15 | #define DateSerial dSerial 16 | #define DebugSerial Serial 17 | #else 18 | #define DateSerial Serial 19 | #define DebugSerial Serial 20 | #endif 21 | 22 | /** 23 | * Set SERIAL_TIMEOUT & WS_BUFFER_SIZE 24 | */ 25 | #define SERIAL_TIMEOUT 100 26 | #define WS_BUFFER_SIZE 200 27 | #define CHAR_TIMEOUT 50 28 | 29 | /** 30 | * Some keywords for communication with ESP32-CAM 31 | */ 32 | #define CHECK "SC" 33 | #define OK_FLAG "[OK]" 34 | #define ERROR_FLAG "[ERR]" 35 | #define WS_HEADER "WS+" 36 | #define CAM_INIT "[Init]" 37 | #define WS_CONNECT "[CONNECTED]" 38 | #define WS_DISCONNECT "[DISCONNECTED]" 39 | #define APP_STOP "[APPSTOP]" 40 | 41 | /** 42 | * @name Set the print level of information received by esp32-cam 43 | * 44 | * @code {.cpp} 45 | * #define CAM_DEBUG_LEVEL CAM_DEBUG_LEVEL_INFO 46 | * @endcode 47 | * 48 | */ 49 | #define CAM_DEBUG_LEVEL CAM_DEBUG_LEVEL_INFO 50 | #define CAM_DEBUG_LEVEL_OFF 0 51 | #define CAM_DEBUG_LEVEL_ERROR 1 52 | #define CAM_DEBUG_LEVEL_INFO 2 53 | #define CAM_DEBUG_LEVEL_DEBUG 3 54 | #define CAM_DEBUG_LEVEL_ALL 4 55 | 56 | #define CAM_DEBUG_HEAD_ALL "[CAM_A]" 57 | #define CAM_DEBUG_HEAD_ERROR "[CAM_E]" 58 | #define CAM_DEBUG_HEAD_INFO "[CAM_I]" 59 | #define CAM_DEBUG_HEAD_DEBUG "[CAM_D]" 60 | 61 | /** 62 | * @name Define component-related values 63 | */ 64 | #define DPAD_STOP 0 65 | #define DPAD_FORWARD 1 66 | #define DPAD_BACKWARD 2 67 | #define DPAD_LEFT 3 68 | #define DPAD_RIGHT 4 69 | 70 | #define JOYSTICK_X 0 71 | #define JOYSTICK_Y 1 72 | #define JOYSTICK_ANGLE 2 73 | #define JOYSTICK_RADIUS 3 74 | 75 | #define WIFI_MODE_NONE "0" 76 | #define WIFI_MODE_STA "1" 77 | #define WIFI_MODE_AP "2" 78 | 79 | #define REGION_A 0 80 | #define REGION_B 1 81 | #define REGION_C 2 82 | #define REGION_D 3 83 | #define REGION_E 4 84 | #define REGION_F 5 85 | #define REGION_G 6 86 | #define REGION_H 7 87 | #define REGION_I 8 88 | #define REGION_J 9 89 | #define REGION_K 10 90 | #define REGION_L 11 91 | #define REGION_M 12 92 | #define REGION_N 13 93 | #define REGION_O 14 94 | #define REGION_P 15 95 | #define REGION_Q 16 96 | #define REGION_R 17 97 | #define REGION_S 18 98 | #define REGION_T 19 99 | #define REGION_U 20 100 | #define REGION_V 21 101 | #define REGION_W 22 102 | #define REGION_X 23 103 | #define REGION_Y 24 104 | #define REGION_Z 25 105 | 106 | class AiCamera 107 | { 108 | public: 109 | bool ws_connected = false; 110 | char recvBuffer[WS_BUFFER_SIZE]; 111 | StaticJsonDocument<200> send_doc; 112 | 113 | AiCamera(const char *name, const char *type); 114 | void begin(const char *ssid, const char *password, const char *wifiMode, const char *wsPort); 115 | void setOnReceived(void (*func)(char *, char *)); 116 | 117 | void set_command_timeout(uint32_t _timeout); 118 | void readInto(char *buffer); 119 | void loop(); 120 | void sendData(); 121 | 122 | void debug(char *msg); 123 | 124 | void set(const char *command, bool wait = true); 125 | void set(const char *command, const char *value, bool wait = true); 126 | void get(const char *command, char *result); 127 | void get(const char *command, const char *value, char *result); 128 | 129 | int16_t getSlider(uint8_t region); 130 | bool getButton(uint8_t region); 131 | bool getSwitch(uint8_t region); 132 | int16_t getJoystick(uint8_t region, uint8_t axis); 133 | uint8_t getDPad(uint8_t region); 134 | int16_t getThrottle(uint8_t region); 135 | void setMeter(uint8_t region, double value); 136 | void setRadar(uint8_t region, int16_t angle, double distance); 137 | void setGreyscale(uint8_t region, uint16_t value1, uint16_t value2, uint16_t value3); 138 | void setValue(uint8_t region, double value); 139 | void getSpeech(uint8_t region, char *result); 140 | 141 | void lamp_on(uint8_t level = 5); 142 | void lamp_off(void); 143 | 144 | private: 145 | void command(const char *command, const char *value, char *result, bool wait = true); 146 | void subString(char *str, int16_t start, int16_t end = -1); 147 | 148 | void getStrOf(char *str, uint8_t index, char *result, char divider); 149 | void setStrOf(char *str, uint8_t index, String value, char divider = ';'); 150 | int16_t getIntOf(char *str, uint8_t index, char divider = ';'); 151 | bool getBoolOf(char *str, uint8_t index); 152 | double getDoubleOf(char *str, uint8_t index); 153 | }; 154 | 155 | #endif // __AI_CAMERA_H__ 156 | -------------------------------------------------------------------------------- /examples/18_app_control_plus/ai_camera.h: -------------------------------------------------------------------------------- 1 | #ifndef __AI_CAMERA_H__ 2 | #define __AI_CAMERA_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | /** 9 | * Use custom serial port 10 | */ 11 | // #define AI_CAM_DEBUG_CUSTOM 12 | #ifdef AI_CAM_DEBUG_CUSTOM 13 | #include 14 | SoftwareSerial dSerial(10, 11); // RX, TX 15 | #define DateSerial dSerial 16 | #define DebugSerial Serial 17 | #else 18 | #define DateSerial Serial 19 | #define DebugSerial Serial 20 | #endif 21 | 22 | /** 23 | * Set SERIAL_TIMEOUT & WS_BUFFER_SIZE 24 | */ 25 | #define SERIAL_TIMEOUT 100 26 | #define WS_BUFFER_SIZE 200 27 | #define CHAR_TIMEOUT 50 28 | 29 | /** 30 | * Some keywords for communication with ESP32-CAM 31 | */ 32 | #define CHECK "SC" 33 | #define OK_FLAG "[OK]" 34 | #define ERROR_FLAG "[ERR]" 35 | #define WS_HEADER "WS+" 36 | #define CAM_INIT "[Init]" 37 | #define WS_CONNECT "[CONNECTED]" 38 | #define WS_DISCONNECT "[DISCONNECTED]" 39 | #define APP_STOP "[APPSTOP]" 40 | 41 | /** 42 | * @name Set the print level of information received by esp32-cam 43 | * 44 | * @code {.cpp} 45 | * #define CAM_DEBUG_LEVEL CAM_DEBUG_LEVEL_INFO 46 | * @endcode 47 | * 48 | */ 49 | #define CAM_DEBUG_LEVEL CAM_DEBUG_LEVEL_INFO 50 | #define CAM_DEBUG_LEVEL_OFF 0 51 | #define CAM_DEBUG_LEVEL_ERROR 1 52 | #define CAM_DEBUG_LEVEL_INFO 2 53 | #define CAM_DEBUG_LEVEL_DEBUG 3 54 | #define CAM_DEBUG_LEVEL_ALL 4 55 | 56 | #define CAM_DEBUG_HEAD_ALL "[CAM_A]" 57 | #define CAM_DEBUG_HEAD_ERROR "[CAM_E]" 58 | #define CAM_DEBUG_HEAD_INFO "[CAM_I]" 59 | #define CAM_DEBUG_HEAD_DEBUG "[CAM_D]" 60 | 61 | /** 62 | * @name Define component-related values 63 | */ 64 | #define DPAD_STOP 0 65 | #define DPAD_FORWARD 1 66 | #define DPAD_BACKWARD 2 67 | #define DPAD_LEFT 3 68 | #define DPAD_RIGHT 4 69 | 70 | #define JOYSTICK_X 0 71 | #define JOYSTICK_Y 1 72 | #define JOYSTICK_ANGLE 2 73 | #define JOYSTICK_RADIUS 3 74 | 75 | #define WIFI_MODE_NONE "0" 76 | #define WIFI_MODE_STA "1" 77 | #define WIFI_MODE_AP "2" 78 | 79 | #define REGION_A 0 80 | #define REGION_B 1 81 | #define REGION_C 2 82 | #define REGION_D 3 83 | #define REGION_E 4 84 | #define REGION_F 5 85 | #define REGION_G 6 86 | #define REGION_H 7 87 | #define REGION_I 8 88 | #define REGION_J 9 89 | #define REGION_K 10 90 | #define REGION_L 11 91 | #define REGION_M 12 92 | #define REGION_N 13 93 | #define REGION_O 14 94 | #define REGION_P 15 95 | #define REGION_Q 16 96 | #define REGION_R 17 97 | #define REGION_S 18 98 | #define REGION_T 19 99 | #define REGION_U 20 100 | #define REGION_V 21 101 | #define REGION_W 22 102 | #define REGION_X 23 103 | #define REGION_Y 24 104 | #define REGION_Z 25 105 | 106 | class AiCamera 107 | { 108 | public: 109 | bool ws_connected = false; 110 | char recvBuffer[WS_BUFFER_SIZE]; 111 | StaticJsonDocument<200> send_doc; 112 | 113 | AiCamera(const char *name, const char *type); 114 | void begin(const char *ssid, const char *password, const char *wifiMode, const char *wsPort); 115 | void setOnReceived(void (*func)(char *, char *)); 116 | 117 | void set_command_timeout(uint32_t _timeout); 118 | void readInto(char *buffer); 119 | void loop(); 120 | void sendData(); 121 | 122 | void debug(char *msg); 123 | 124 | void set(const char *command, bool wait = true); 125 | void set(const char *command, const char *value, bool wait = true); 126 | void get(const char *command, char *result); 127 | void get(const char *command, const char *value, char *result); 128 | 129 | int16_t getSlider(uint8_t region); 130 | bool getButton(uint8_t region); 131 | bool getSwitch(uint8_t region); 132 | int16_t getJoystick(uint8_t region, uint8_t axis); 133 | uint8_t getDPad(uint8_t region); 134 | int16_t getThrottle(uint8_t region); 135 | void setMeter(uint8_t region, double value); 136 | void setRadar(uint8_t region, int16_t angle, double distance); 137 | void setGreyscale(uint8_t region, uint16_t value1, uint16_t value2, uint16_t value3); 138 | void setValue(uint8_t region, double value); 139 | void getSpeech(uint8_t region, char *result); 140 | 141 | void lamp_on(uint8_t level = 5); 142 | void lamp_off(void); 143 | 144 | private: 145 | void command(const char *command, const char *value, char *result, bool wait = true); 146 | void subString(char *str, int16_t start, int16_t end = -1); 147 | 148 | void getStrOf(char *str, uint8_t index, char *result, char divider); 149 | void setStrOf(char *str, uint8_t index, String value, char divider = ';'); 150 | int16_t getIntOf(char *str, uint8_t index, char divider = ';'); 151 | bool getBoolOf(char *str, uint8_t index); 152 | double getDoubleOf(char *str, uint8_t index); 153 | }; 154 | 155 | #endif // __AI_CAMERA_H__ 156 | -------------------------------------------------------------------------------- /examples/6_car_light/6_car_light.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | * car_light 3 | 4 | Control the color of the rgb light bars via the remote. 5 | - key 1 to 9 :red, orange, yellow, green, cyan, blue, purple, pink, white 6 | - key 0 : turn off 7 | - key CYCLE : color gradient 8 | ******************************************************************/ 9 | #include 10 | #include 11 | #include "ir_remote.h" 12 | 13 | /** Indicate whether RGB leds are common-anodes or not 14 | * - 0 common cathode 15 | * - 1 common anode 16 | */ 17 | #define COMMON_ANODE 0 18 | 19 | /** Set the pins of RGB leds, the order is R,G,B */ 20 | #define RGB_PINS (uint8_t[3]){12, 13, 11} 21 | 22 | /* Define the color of the response for different keys */ 23 | const uint8_t key_color_array[9][3] { 24 | {255, 0, 0}, // red 25 | {255, 165, 0}, // orange 26 | {255, 255, 0}, // yellow 27 | {0, 255, 0}, // green 28 | {0, 127, 255}, // cyan 29 | {0, 0, 255}, // blue 30 | {139, 0, 255}, // purple 31 | {255, 128, 255}, // pink 32 | {255, 255, 255}, // white 33 | }; 34 | 35 | void rgbBegin(); 36 | void rgbWrite(uint32_t color); 37 | void rgbWrite(uint8_t r, uint8_t g, uint8_t b); 38 | void rgbOff(); 39 | void color_gradient(); 40 | 41 | 42 | void setup() { 43 | Serial.begin(115200); 44 | irBegin(); 45 | SoftPWMBegin(); //init softpwm, before the rgb LEDs initialization 46 | rgbBegin(); // init rgb LEDs 47 | Serial.println("Init OK"); 48 | } 49 | 50 | void loop() { 51 | uint8_t key = irRead(); 52 | if (key != IR_KEY_ERROR) { 53 | if (key < 16) { 54 | Serial.print("0x0");Serial.println(key, HEX); 55 | } else { 56 | Serial.print("0x");Serial.println(key, HEX); 57 | } 58 | } 59 | 60 | switch (key) { 61 | case IR_KEY_ERROR: 62 | break; 63 | case IR_KEY_1: 64 | color_show(0); 65 | break; 66 | case IR_KEY_2: 67 | color_show(1); 68 | break; 69 | case IR_KEY_3: 70 | color_show(2); 71 | break; 72 | case IR_KEY_4: 73 | color_show(3); 74 | break; 75 | case IR_KEY_5: 76 | color_show(4); 77 | break; 78 | case IR_KEY_6: 79 | color_show(5); 80 | break; 81 | case IR_KEY_7: 82 | color_show(6); 83 | break; 84 | case IR_KEY_8: 85 | color_show(7); 86 | break; 87 | case IR_KEY_9: 88 | color_show(8); 89 | break; 90 | case IR_KEY_0: 91 | rgbOff(); 92 | break; 93 | case IR_KEY_CYCLE: 94 | color_gradient(); 95 | break; 96 | default: 97 | break; 98 | } 99 | } 100 | 101 | /** Initialize RGB leds */ 102 | void rgbBegin() { 103 | for (uint8_t i = 0; i < 3; i++) { 104 | SoftPWMSet(RGB_PINS[i], 0); 105 | SoftPWMSetFadeTime(RGB_PINS[i], 100, 100); 106 | } 107 | } 108 | 109 | /** Set LED color in HEX */ 110 | void rgbWrite(uint32_t color) { 111 | uint8_t r = (color >> 16) & 0xFF; 112 | uint8_t g = (color >> 8) & 0xFF; 113 | uint8_t b = (color >> 0) & 0xFF; 114 | rgbWrite(r, g, b); 115 | } 116 | 117 | 118 | /** Set LED color in 8bit R,G,B (0 ~ 255)*/ 119 | void rgbWrite(uint8_t r, uint8_t g, uint8_t b) { 120 | // calibrate brightness 121 | r = int(r * 1); 122 | g = int(g * 0.16); 123 | b = int(b * 0.30); 124 | // COMMON_ANODE reverse 125 | #if COMMON_ANODE 126 | r = 255 - r; 127 | g = 255 - g; 128 | b = 255 - b; 129 | #endif 130 | // set volatge 131 | SoftPWMSet(RGB_PINS[0], r); 132 | SoftPWMSet(RGB_PINS[1], g); 133 | SoftPWMSet(RGB_PINS[2], b); 134 | } 135 | 136 | /** Turn odd RGB LEDs*/ 137 | void rgbOff() { 138 | rgbWrite(0, 0, 0); 139 | } 140 | 141 | void color_show(uint8_t index) { 142 | uint8_t r = key_color_array[index][0]; 143 | uint8_t g = key_color_array[index][1]; 144 | uint8_t b = key_color_array[index][2]; 145 | 146 | Serial.print("r:"); Serial.print(r); 147 | Serial.print(" ,g:"); Serial.print(g); 148 | Serial.print(" ,b:"); Serial.println(b); 149 | 150 | rgbWrite(r, g, b); 151 | delay(20); 152 | } 153 | 154 | /* color_gradient 155 | * Gradient of RGB LEDs, 156 | * [255, 0, 255·to·0] 157 | * [255, 0·to·255, 0] 158 | * [255·to·0, 255, 0] 159 | * [0, 255, 0·to·255] 160 | * [0, 255·to·0, 255] 161 | * [0·to·255, 0, 255] 162 | * 163 | */ 164 | void color_gradient() { 165 | uint8_t rgb[3] = {0, 0, 0}; 166 | Serial.println("color_gradient"); 167 | 168 | for (uint8_t i = 0; i < 3; i++) { 169 | // Note that "j" needs to use int16_t 170 | for (int16_t j = 255; j >= 0; j--) { 171 | rgb[i] = 255; 172 | rgb[(i+2)%3] = j; 173 | Serial.print("r:"); Serial.print(rgb[0]); 174 | Serial.print(" ,g:"); Serial.print(rgb[1]); 175 | Serial.print(" ,b:"); Serial.println(rgb[2]); 176 | rgbWrite(rgb[0], rgb[1], rgb[2]); 177 | delay(5); 178 | } 179 | for (int16_t j = 0; j <= 255; j++) { 180 | rgb[i] = 255; 181 | rgb[(i+1)%3] = j; 182 | Serial.print("r:"); Serial.print(rgb[0]); 183 | Serial.print(" ,g:"); Serial.print(rgb[1]); 184 | Serial.print(" ,b:"); Serial.println(rgb[2]); 185 | rgbWrite(rgb[0], rgb[1], rgb[2]); 186 | delay(5); 187 | } 188 | } 189 | } 190 | 191 | 192 | -------------------------------------------------------------------------------- /test/test.ino: -------------------------------------------------------------------------------- 1 | 2 | char testString[] = "3;5;10,30;forward;false;true;4;-100;40.4;50,60;-45.5;backward;50564,33630,333"; 3 | char testString2[200] = ";;;;;;;;;;;;;;;;;;;;;;;;;"; 4 | 5 | void getStrOf(char* str, uint8_t index, char* result, char divider=';') { 6 | uint8_t start, end; 7 | uint8_t length = strlen(str); 8 | uint8_t i, j; 9 | // Get start index 10 | if (index == 0) { 11 | start = 0; 12 | } else { 13 | for (start = 0, j = 1; start < length; start++) { 14 | if (str[start] == divider) { 15 | if (index == j) { 16 | start++; 17 | break; 18 | } 19 | j++; 20 | } 21 | } 22 | } 23 | // Get end index 24 | for (end = start, j = 0; end < length; end++) { 25 | // Serial.println((int)str[end]); 26 | if (str[end] == divider) { 27 | break; 28 | } 29 | } 30 | // Copy result 31 | for (i = start, j = 0; i < end; i++, j++) { 32 | result[j] = str[i]; 33 | } 34 | result[j] = '\0'; 35 | } 36 | 37 | void setStrOf(char* str, uint8_t index, String value, char divider) { 38 | uint8_t start, end; 39 | uint8_t length = strlen(str); 40 | uint8_t i, j; 41 | // Get start index 42 | if (index == 0) { 43 | start = 0; 44 | } else { 45 | for (start = 0, j = 1; start < length; start++) { 46 | if (str[start] == divider) { 47 | if (index == j) { 48 | start++; 49 | break; 50 | } 51 | j++; 52 | } 53 | } 54 | } 55 | // Get end index 56 | for (end = start, j = 0; end < length; end++) { 57 | // Serial.println((int)str[end]); 58 | if (str[end] == divider) { 59 | break; 60 | } 61 | } 62 | // Set value result 63 | String strValue = String(str).substring(0, start) + value + String(str).substring(end); 64 | strcpy(str, strValue.c_str()); 65 | Serial.println(str); 66 | } 67 | 68 | int16_t getIntOf(char* str, uint8_t index) { 69 | int16_t result; 70 | char strResult[20]; 71 | getStrOf(str, index, strResult); 72 | result = String(strResult).toInt(); 73 | return result; 74 | } 75 | 76 | bool getBoolOf(char* str, uint8_t index) { 77 | char strResult[20]; 78 | getStrOf(str, index, strResult); 79 | return String(strResult) == "true"; 80 | } 81 | 82 | double getDoubleOf(char* str, uint8_t index) { 83 | double result; 84 | char strResult[20]; 85 | getStrOf(str, index, strResult); 86 | result = String(strResult).toDouble(); 87 | return result; 88 | } 89 | 90 | 91 | void setup() { 92 | Serial.begin(115200); 93 | 94 | Serial.println("Start!"); 95 | 96 | // setStrOf(testString2, 0, "3", ';'); 97 | // setStrOf(testString2, 1, "5", ';'); 98 | // setStrOf(testString2, 2, "10,30", ';'); 99 | // setStrOf(testString2, 3, "forward", ';'); 100 | // setStrOf(testString2, 4, "false", ';'); 101 | // setStrOf(testString2, 5, "true", ';'); 102 | // setStrOf(testString2, 6, "4", ';'); 103 | // setStrOf(testString2, 7, "-100", ';'); 104 | // setStrOf(testString2, 8, "40.4", ';'); 105 | // setStrOf(testString2, 9, "50,60", ';'); 106 | // setStrOf(testString2, 10, "-45.5", ';'); 107 | // setStrOf(testString2, 11, "backward", ';'); 108 | setStrOf(testString2, 12, "50564,33630,333", ';'); 109 | 110 | int16_t resultA; 111 | int16_t resultB; 112 | char resultC[10]; 113 | char resultD[10]; 114 | bool resultE; 115 | bool resultF; 116 | int16_t resultG; 117 | int16_t resultH; 118 | double resultI; 119 | char resultJ[10]; 120 | double resultK; 121 | char resultL[10]; 122 | char resultM[10]; 123 | char resultN[10]; 124 | char resultO[10]; 125 | char resultP[10]; 126 | char resultQ[10]; 127 | resultA = getIntOf(testString2, 0); 128 | resultB = getIntOf(testString2, 1); 129 | getStrOf(testString2, 2, resultC); 130 | getStrOf(testString2, 3, resultD); 131 | resultE = getBoolOf(testString2, 4); 132 | resultF = getBoolOf(testString2, 5); 133 | resultG = getIntOf(testString2, 6); 134 | resultH = getIntOf(testString2, 7); 135 | resultI = getDoubleOf(testString2, 8); 136 | getStrOf(testString2, 9, resultJ); 137 | resultK = getDoubleOf(testString2, 10); 138 | getStrOf(testString2, 11, resultL); 139 | getStrOf(testString2, 12, resultM); 140 | getStrOf(testString2, 13, resultN); 141 | getStrOf(testString2, 14, resultO); 142 | getStrOf(testString2, 15, resultP); 143 | getStrOf(testString2, 16, resultQ); 144 | Serial.print("A: "); 145 | Serial.println(resultA); 146 | Serial.print("B: "); 147 | Serial.println(resultB); 148 | Serial.print("C: "); 149 | Serial.println(resultC); 150 | Serial.print("D: "); 151 | Serial.println(resultD); 152 | Serial.print("E: "); 153 | Serial.println(resultE); 154 | Serial.print("F: "); 155 | Serial.println(resultF); 156 | Serial.print("G: "); 157 | Serial.println(resultG); 158 | Serial.print("H: "); 159 | Serial.println(resultH); 160 | Serial.print("I: "); 161 | Serial.println(resultI); 162 | Serial.print("J: "); 163 | Serial.println(resultJ); 164 | Serial.print("K: "); 165 | Serial.println(resultK); 166 | Serial.print("L: "); 167 | Serial.println(resultL); 168 | Serial.print("M: "); 169 | Serial.println(resultM); 170 | Serial.print("N: "); 171 | Serial.println(resultN); 172 | Serial.print("O: "); 173 | Serial.println(resultO); 174 | Serial.print("P: "); 175 | Serial.println(resultP); 176 | Serial.print("Q: "); 177 | Serial.println(resultQ); 178 | } 179 | 180 | void loop() {} -------------------------------------------------------------------------------- /examples/8_move_field_centric/8_move_field_centric.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | move_field_centric 3 | 4 | Use the IR remote control to control the car 5 | to move or rotate in different directions. 6 | 7 | - Change the carMove of 5_remote_control to carMoveFieldCentric 8 | - Note that carMoveFieldCentric needs to run continuously in the loop to 9 | adjust the head direction 10 | ******************************************************************/ 11 | #include 12 | #include 13 | 14 | #include "compass.h" 15 | #include "car_control.h" 16 | #include "ir_remote.h" 17 | #include "rgb.h" 18 | 19 | #define CAR_CALIBRATION_POWER 80 20 | #define IR_REMOTE_POWER 50 21 | 22 | #define MODE_NONE 0 23 | #define MODE_REMOTE_CONTROL 1 24 | #define MODE_COMPASS_CALIBRATION 2 25 | 26 | uint8_t currentMode = MODE_NONE; 27 | 28 | //int16_t currentAngle = 0; 29 | int16_t remoteAngle = 0; 30 | int8_t remotePower = 0; 31 | //int8_t lastRemotePower = 0; 32 | int16_t remoteHeading = 0; 33 | bool remoteDriftEnable = false; 34 | 35 | extern int16_t originHeading; 36 | 37 | void setup() { 38 | Serial.begin(115200); 39 | SoftPWMBegin(); // init softpwm, before the motors initialization and the rgb LEDs initialization 40 | rgbBegin(); 41 | irBegin(); 42 | carBegin(); 43 | } 44 | 45 | void loop() { 46 | /* read IR key */ 47 | uint8_t key = irRead(); 48 | 49 | /* IR key handle */ 50 | if (key == IR_KEY_POWER) { 51 | remoteAngle = 0; 52 | remotePower = 0; 53 | remoteHeading = 0; 54 | remoteDriftEnable = false; 55 | currentMode = MODE_NONE; 56 | } else if (key == IR_KEY_MUTE) { // compass calibration 57 | Serial.println("Start compass calibration ..."); 58 | currentMode = MODE_COMPASS_CALIBRATION; 59 | compassCalibrateStart(); 60 | } 61 | else if (key != IR_KEY_ERROR) { 62 | currentMode = MODE_REMOTE_CONTROL; 63 | carResetHeading(); 64 | switch (key) { 65 | case IR_KEY_5: // pause 66 | remoteAngle = 0; 67 | remotePower = 0; 68 | remoteHeading = 0; 69 | remoteDriftEnable = false; 70 | break; 71 | case IR_KEY_2: // move towards 0 degrees 72 | remoteAngle = 0; 73 | remotePower = IR_REMOTE_POWER; 74 | remoteHeading = 0; 75 | remoteDriftEnable = false; 76 | break; 77 | case IR_KEY_3: // move towards 45 degrees 78 | remoteAngle = 45; 79 | remotePower = IR_REMOTE_POWER; 80 | remoteHeading = 0; 81 | remoteDriftEnable = false; 82 | break; 83 | case IR_KEY_6: // move towards 90 degrees 84 | remoteAngle = 90; 85 | remotePower = IR_REMOTE_POWER; 86 | remoteHeading = 0; 87 | remoteDriftEnable = false; 88 | break; 89 | case IR_KEY_9: // move towards 135 degrees 90 | remoteAngle = 135; 91 | remotePower = IR_REMOTE_POWER; 92 | remoteHeading = 0; 93 | remoteDriftEnable = false; 94 | break; 95 | case IR_KEY_8: // move towards 180 degrees 96 | remoteAngle = 180; 97 | remotePower = IR_REMOTE_POWER; 98 | remoteHeading = 0; 99 | remoteDriftEnable = false; 100 | break; 101 | case IR_KEY_7: // move towards 225 degrees 102 | remoteAngle = 225; 103 | remotePower = IR_REMOTE_POWER; 104 | remoteHeading = 0; 105 | remoteDriftEnable = false; 106 | break; 107 | case IR_KEY_4: // move towards 270 degrees 108 | remoteAngle = 270; 109 | remotePower = IR_REMOTE_POWER; 110 | remoteHeading = 0; 111 | remoteDriftEnable = false; 112 | break; 113 | case IR_KEY_1: // move towards 315 degrees 114 | remoteAngle = 315; 115 | remotePower = IR_REMOTE_POWER; 116 | remoteHeading = 0; 117 | remoteDriftEnable = false; 118 | break; 119 | case IR_KEY_CYCLE: // turn left 120 | remoteHeading = -45; 121 | remoteDriftEnable = false; 122 | break; 123 | case IR_KEY_U_SD: // turn right 124 | remoteHeading = 45; 125 | remoteDriftEnable = false; 126 | break; 127 | case IR_KEY_MINUS: // drift left 128 | remoteHeading = -90; 129 | remoteDriftEnable = true; 130 | break; 131 | case IR_KEY_PLUS: // drift right 132 | remoteHeading = 90; 133 | remoteDriftEnable = true; 134 | break; 135 | default: 136 | break; 137 | } 138 | } 139 | 140 | /* motors move */ 141 | switch (currentMode) { 142 | case MODE_REMOTE_CONTROL: 143 | carMoveFieldCentric(remoteAngle, remotePower, remoteHeading, remoteDriftEnable); 144 | break; 145 | case MODE_COMPASS_CALIBRATION: 146 | carMove(0, 0, CAR_CALIBRATION_POWER); 147 | compass_calibrating(); 148 | break; 149 | case MODE_NONE: 150 | carStop(); 151 | break; 152 | } 153 | } 154 | 155 | /* compasee calibrate */ 156 | void compass_calibrating() { 157 | bool changed = compassCalibrateLoop(); 158 | if (changed) { 159 | rgbWrite(0, 255, 0); 160 | delay(20); 161 | rgbOff(); 162 | Serial.println("Compass calibrating..."); 163 | } 164 | if (compassCalibrateDone()) { 165 | currentMode = MODE_NONE; 166 | rgbWrite(0, 0, 255); 167 | delay(50); 168 | rgbOff(); 169 | Serial.println("Compass calibration done!"); 170 | } 171 | } 172 | --------------------------------------------------------------------------------