├── .gitignore ├── EXP_1 ├── README.md └── sketch_BreathLED │ └── sketch_BreathLED.ino ├── EXP_2 ├── EXP_2_1 │ ├── README.md │ └── sketch_ControlLED │ │ └── sketch_ControlLED.ino └── EXP_2_2 │ ├── README.md │ └── sketch_Motor │ └── sketch_Motor.ino ├── EXP_3 ├── README.md ├── sketch_distance │ └── sketch_distance.ino └── sketch_ultrasonic │ └── sketch_ultrasonic.ino ├── EXP_4 ├── README.md └── sketch_oled │ ├── define.h │ └── sketch_oled.ino ├── EXP_5 ├── sketch_alongwall │ ├── define.h │ ├── sensor.h │ └── sketch_alongwall.ino └── sketch_alongwall_old │ ├── define.h │ ├── sensor.h │ └── sketch_alongwall_old.ino ├── EXP_6 └── sketch_pid │ ├── define.h │ └── sketch_pid.ino ├── EXP_7 ├── EXP_7_1 │ └── sketch_following │ │ ├── define.h │ │ ├── sensor.h │ │ └── sketch_following.ino └── EXP_7_2 │ └── sketch_linetracking │ ├── define.h │ └── sketch_linetracking.ino ├── EXP_8 ├── cv │ └── linetracking_cv.py └── sketch_code4car │ ├── define.h │ └── sketch_code4car.ino ├── LICENSE ├── README.md └── libraries ├── Adafruit_Circuit_Playground ├── Adafruit_CircuitPlayground.cpp ├── Adafruit_CircuitPlayground.h ├── Adafruit_Circuit_Playground.h ├── Doxyfile ├── README.md ├── examples │ ├── CircuitPlaygroundFirmata │ │ └── CircuitPlaygroundFirmata.ino │ ├── CircuitPlaygroundFirmata_Express_CodeOrg │ │ └── CircuitPlaygroundFirmata_Express_CodeOrg.ino │ ├── FidgetSpinner │ │ ├── FidgetSpinner.h │ │ ├── FidgetSpinner.ino │ │ └── PeakDetector.h │ ├── Hello_CircuitPlayground │ │ ├── Hello_Accelerometer │ │ │ └── Hello_Accelerometer.ino │ │ ├── Hello_Blink │ │ │ └── Hello_Blink.ino │ │ ├── Hello_Buttons │ │ │ └── Hello_Buttons.ino │ │ ├── Hello_LightSensor │ │ │ └── Hello_LightSensor.ino │ │ ├── Hello_NeoPixels │ │ │ └── Hello_NeoPixels.ino │ │ ├── Hello_SlideSwitch │ │ │ └── Hello_SlideSwitch.ino │ │ ├── Hello_SoundSensor │ │ │ └── Hello_SoundSensor.ino │ │ ├── Hello_Speaker │ │ │ └── Hello_Speaker.ino │ │ ├── Hello_Temperature │ │ │ └── Hello_Temperature.ino │ │ └── README.md │ ├── Infrared_Demos │ │ ├── Infrared_NeoPixel │ │ │ ├── Infrared_NeoPixel.ino │ │ │ └── adafruit_mini_codes.h │ │ ├── Infrared_Read │ │ │ └── Infrared_Read.ino │ │ ├── Infrared_Record │ │ │ └── Infrared_Record.ino │ │ ├── Infrared_Send │ │ │ └── Infrared_Send.ino │ │ └── Infrared_Testpattern │ │ │ └── Infrared_Testpattern.ino │ ├── Microphone_Demos │ │ ├── Birthday_Candles │ │ │ └── Birthday_Candles.ino │ │ ├── mic_FFT_classic │ │ │ └── mic_FFT_classic.ino │ │ ├── mic_FFT_express │ │ │ └── mic_FFT_express.ino │ │ ├── pretty_meter │ │ │ └── pretty_meter.ino │ │ ├── soundPressureLevel │ │ │ └── soundPressureLevel.ino │ │ └── vu_meter │ │ │ └── vu_meter.ino │ ├── ScratchSensorBoard │ │ └── ScratchSensorBoard.ino │ ├── Speech_Demos │ │ ├── Talk_UK_Acorn │ │ │ └── Talk_UK_Acorn.ino │ │ ├── Talk_US_Clock │ │ │ └── Talk_US_Clock.ino │ │ ├── Talk_US_Large │ │ │ └── Talk_US_Large.ino │ │ ├── Talk_US_Male │ │ │ └── Talk_US_Male.ino │ │ └── Talk_US_TI99 │ │ │ └── Talk_US_TI99.ino │ ├── accelTap │ │ └── accelTap.ino │ ├── accel_mouse │ │ └── accel_mouse.ino │ ├── analog_sensors │ │ └── analog_sensors.ino │ ├── color_sense │ │ └── color_sense.ino │ ├── comm_badge │ │ ├── coin.h │ │ ├── comm_badge.ino │ │ └── trek.h │ ├── demo │ │ └── demo.ino │ ├── mega_demo │ │ ├── CapTouchDemo.h │ │ ├── Demo.h │ │ ├── RainbowCycleDemo.h │ │ ├── SensorDemo.h │ │ ├── TiltDemo.h │ │ ├── VUMeterDemo.h │ │ └── mega_demo.ino │ ├── tachometer │ │ └── tachometer.ino │ └── tachometer_led_display │ │ └── tachometer_led_display.ino ├── library.properties └── utility │ ├── Adafruit_CPlay_FreeTouch.cpp │ ├── Adafruit_CPlay_FreeTouch.h │ ├── Adafruit_CPlay_LIS3DH.cpp │ ├── Adafruit_CPlay_LIS3DH.h │ ├── Adafruit_CPlay_Mic.cpp │ ├── Adafruit_CPlay_Mic.h │ ├── Adafruit_CPlay_NeoPixel.cpp │ ├── Adafruit_CPlay_NeoPixel.h │ ├── Adafruit_CPlay_Sensor.h │ ├── Adafruit_CPlay_Speaker.cpp │ ├── Adafruit_CPlay_Speaker.h │ ├── Adafruit_ZeroPDM.cpp │ ├── Adafruit_ZeroPDM.h │ ├── CP_Boards.h │ ├── CP_Firmata.cpp │ ├── CP_Firmata.h │ ├── CPlay_CapacitiveSensor.cpp │ ├── CPlay_CapacitiveSensor.h │ ├── IRLibCPE.h │ ├── IRLibCombo.h │ ├── IRLibDecodeBase.cpp │ ├── IRLibDecodeBase.h │ ├── IRLibGlobals.h │ ├── IRLibHardware.cpp │ ├── IRLibHardware.h │ ├── IRLibProtocols.cpp │ ├── IRLibProtocols.h │ ├── IRLibRecvBase.cpp │ ├── IRLibRecvBase.h │ ├── IRLibRecvPCI.cpp │ ├── IRLibRecvPCI.h │ ├── IRLibSAMD21.cpp │ ├── IRLibSAMD21.h │ ├── IRLibSendBase.cpp │ ├── IRLibSendBase.h │ ├── IRLib_COPYRIGHT.txt │ ├── IRLib_HashRaw.h │ ├── IRLib_P01_NEC.h │ ├── IRLib_P02_Sony.h │ ├── IRLib_P03_RC5.h │ ├── IRLib_P04_RC6.h │ ├── IRLib_P05_Panasonic_Old.h │ ├── IRLib_P06_JVC.h │ ├── IRLib_P07_NECx.h │ ├── IRLib_P08_Samsung36.h │ ├── IRLib_P09_GICable.h │ ├── IRLib_P10_DirecTV.h │ ├── IRLib_P11_RCMM.h │ ├── IRLib_P12_CYKM.h │ ├── IRLib_P99_Additional.h │ ├── IRLib_readme.md │ ├── README.md │ ├── ffft.S │ └── talkie.cpp ├── MsTimer2 ├── MsTimer2.cpp ├── MsTimer2.h └── examples │ └── FlashLed │ └── FlashLed.pde ├── PS2X_lib ├── PS2X_lib.cpp ├── PS2X_lib.h ├── examples │ ├── PS2XMouse │ │ └── PS2XMouse.ino │ └── PS2X_Example │ │ └── PS2X_Example.ino └── keywords.txt ├── PinChangeInt ├── Examples │ ├── ByteBuffer │ │ ├── ByteBuffer.cpp │ │ └── ByteBuffer.h │ ├── GetPSTR │ │ └── GetPSTR.h │ ├── PinChangeIntDebug │ │ └── PinChangeIntDebug.ino │ ├── PinChangeIntExample2560 │ │ └── PinChangeIntExample2560.ino │ ├── PinChangeIntExample328 │ │ └── PinChangeIntExample328.ino │ ├── PinChangeIntSpeedTest │ │ └── PinChangeIntSpeedTest.pde │ ├── PinChangeIntTest │ │ └── PinChangeIntTest.ino │ ├── PinChangeIntTest2 │ │ └── PinChangeIntTest2.ino │ └── SimpleExample328 │ │ └── SimpleExample328.ino ├── LICENSE ├── NOTICE ├── PinChangeInt.h ├── README ├── RELEASE_NOTES ├── Technical_Notes └── keywords.txt ├── SSD1306 ├── SSD1306.cpp ├── SSD1306.h ├── __Previews │ └── glcdfont.cPreview └── glcdfont.c ├── Servo ├── README.adoc ├── examples │ ├── Knob │ │ └── Knob.ino │ └── Sweep │ │ └── Sweep.ino ├── keywords.txt ├── library.properties └── src │ ├── Servo.h │ ├── avr │ ├── Servo.cpp │ └── ServoTimers.h │ ├── megaavr │ ├── Servo.cpp │ └── ServoTimers.h │ ├── nrf52 │ ├── Servo.cpp │ └── ServoTimers.h │ ├── sam │ ├── Servo.cpp │ └── ServoTimers.h │ ├── samd │ ├── Servo.cpp │ └── ServoTimers.h │ └── stm32f4 │ ├── Servo.cpp │ └── ServoTimers.h └── readme.txt /.gitignore: -------------------------------------------------------------------------------- 1 | videos/ 2 | -------------------------------------------------------------------------------- /EXP_1/README.md: -------------------------------------------------------------------------------- 1 | # 实验 1:呼吸灯 2 | 3 | ## 预备知识 4 | 5 | 观察 Blink 源码,其有两个主要的函数: 6 | 7 | * `setup()` 为只在开机时执行一次的函数; 8 | * `loop()` 为执行完 `setup()` 后无限循环的函数。 9 | 10 | 以及部分功能函数: 11 | 12 | * `pinMode()`用来初始化单片机上的 GPIO 功能; 13 | * `digitalWrite()`为输出电平到某个端口,前提是其已经初始化为该功能; 14 | * `Delay()`,顾名思义,让程序暂停一段时间,单位为 ms。 15 | 16 | 17 | 18 | ## 任务 19 | 20 | 修改程序,让板载的 LED 做出呼吸灯的效果。原理请参考 PWM 的思想,有其他思路更好。 21 | 22 | 该实验并不需要使用其它功能函数,仅需要添加一些控制逻辑即可。 23 | 24 | 25 | 26 | ## 程序说明 27 | 28 | 该项目只有一个文件 `sketch_BreathLED.ino`,仅使用了 Arduino 的内置函函数,未使用任何外部库,也未做任何函数封装。 29 | 30 | 在后面的项目中,为了更加方便地使用一些常用功能,我们会封装部分函数。 -------------------------------------------------------------------------------- /EXP_1/sketch_BreathLED/sketch_BreathLED.ino: -------------------------------------------------------------------------------- 1 | void setup() { 2 | pinMode(LED_BUILTIN, OUTPUT); 3 | } 4 | 5 | void loop() { 6 | // strengthening 7 | for (int i = 0; i < 10; i++) { 8 | // PWM 9 | for (int j = 0; j < 5; j++) { 10 | digitalWrite(LED_BUILTIN, HIGH); 11 | delay(i); 12 | digitalWrite(LED_BUILTIN, LOW); 13 | delay(10 - i); 14 | } 15 | } 16 | 17 | // weakening 18 | for (int i = 10; i > 0; i--) { 19 | // PWM 20 | for (int j = 0; j < 10; j++) { 21 | digitalWrite(LED_BUILTIN, HIGH); 22 | delay(i); 23 | digitalWrite(LED_BUILTIN, LOW); 24 | delay(10 - i); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /EXP_2/EXP_2_1/README.md: -------------------------------------------------------------------------------- 1 | # 实验 2_1:亮度可调的 LED 2 | 3 | ## 预备知识 4 | 5 | ### 串口 6 | 7 | * 串口和 IO 口一样,需要初始化,参数为波特率 `Serial.begin(9600)` 8 | 9 | * 然后串口从板子上发送数据为 `Serial.print(msg)` 10 | 11 | * 或发送后再发一个回车的 `Serial.println(msg)` 12 | 13 | * 接受信息为 `Serial.read()`,返回 int 14 | 15 | * 或者使用 `Serial.readString()`,返回 String 16 | 17 | 更多功能请参阅[串口](https://www.arduino.cc/reference/en/language/functions/communication/serial/) 18 | 19 | 20 | 21 | ### EEPROM 22 | 23 | * EEPROM 为非易失性储存器,当开发板断电后其数据仍可以保存在里面,我们使用的 UNO 其 EEPROM 有 1 K Byte,详细用法请看示例中的 EEPROM。 24 | 25 | * 操作基本为读写 26 | 27 | ```cpp 28 | #include 29 | EEPROM.write(addr, val); 30 | EEPROM.read(addr, val); 31 | ``` 32 | 33 | 34 | 35 | ## 任务 36 | 37 | 实现一套简单的通讯协议,实现通过串口可以在电脑上输入指令后使得板载 LED 输出指定亮度。并且保存该亮度数值在 EEPROM 中,能断电后重新加载数值。 -------------------------------------------------------------------------------- /EXP_2/EXP_2_1/sketch_ControlLED/sketch_ControlLED.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | long read_int = 0; 4 | long brightness = 0; 5 | 6 | void myPwm(int pin, unsigned long value, unsigned long duration=1, unsigned long max_val=10); 7 | 8 | 9 | void setup() { 10 | // init 11 | pinMode(LED_BUILTIN, OUTPUT); 12 | Serial.begin(9600); 13 | Serial.setTimeout(50); 14 | 15 | brightness = EEPROM.read(0); // load brightness value from EEPROM 16 | Serial.println("[+] Brightness is an integer between 0 and 10."); 17 | Serial.print("Brightness: "); 18 | Serial.println(brightness, DEC); 19 | } 20 | 21 | 22 | void loop() { 23 | while (Serial.available() > 0) { 24 | read_int = Serial.parseInt(); 25 | if(read_int >= 0 && read_int <= 10) { 26 | brightness = read_int; 27 | Serial.print("Brightness: "); 28 | Serial.println(brightness, DEC); 29 | EEPROM.write(0, read_int); // save brightness value to EEPROM 30 | } 31 | else { 32 | Serial.println("[-] Invalid value!"); 33 | } 34 | } 35 | myPwm(13, brightness, 100); 36 | } 37 | 38 | 39 | /* A simple PWM function implemented by Group 10. 40 | * Parameters: 41 | * pin: the Arduino pin to write to 42 | * value: number of time units with a HIGH value 43 | * duration: milliseconds that PWN signal lasts 44 | * max_val: total number of time units in a cycle 45 | */ 46 | void myPwm(int pin, unsigned long value, unsigned long duration, unsigned long max_val) { 47 | unsigned long end_time = millis() + duration; 48 | while(millis() < end_time) { 49 | // 0 means only LOW, so there's no need to write HIGH 50 | if (value > 0) { 51 | digitalWrite(pin, HIGH); 52 | delayMicroseconds(value); 53 | } 54 | // max_val means only HIGH, so there's no need to write LOW 55 | if (value < max_val) { 56 | digitalWrite(pin, LOW); 57 | delayMicroseconds(max_val - value); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /EXP_2/EXP_2_2/README.md: -------------------------------------------------------------------------------- 1 | # 实验 2_2:让小车直线行驶 2 | 3 | ## 预备知识 4 | 5 | ### 舵机 6 | 7 | 舵机基本的功能为接收 PWM 信号,然后使其摇臂转动到指定角度的位置。 8 | 9 | 使用方式基本为: 10 | 11 | ```cpp 12 | #include 13 | Servo myservo; //新建一个对象 14 | myservo.attach(pin); 15 | myservo.write(deg); //令舵机转向到指定角度 16 | ``` 17 | 18 | 19 | 20 | ### 电机控制 21 | 22 | 每边电机分为使能与速度控制,使能控制电机旋转方向。 23 | 24 | 电机使能采用数字信号(`digitalWrite`) ,输出 0 为正转,反之反转; 25 | 26 | 电机速度采用模拟信号(`analogWrite`) ,输出 0 为不动,输出255为最快。 27 | 28 | 左边电机使能为 11,速度控制为 5; 29 | 30 | 右边电机使能为 3,速度控制为 6。 31 | 32 | 33 | 34 | ## 任务 35 | 36 | 仔细观察车辆结构,写出简单的控制程序,目标是让其能够直线行驶。 37 | 38 | * Hint1: 舵机零点似乎是 95; 39 | * Hint2: 不要让车子跑这么快; 40 | * Hint3: 可以使用 EEPROM 储存速度和舵机零点,不用每次都修改程序烧写。 41 | -------------------------------------------------------------------------------- /EXP_2/EXP_2_2/sketch_Motor/sketch_Motor.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | const int LEFT_EN = 11; // 左边电机使能 5 | const int LEFT_SPDCTR = 5; // 左边电机速度控制 6 | const int RIGHT_EN = 3; // 右边电机使能 7 | const int RIGHT_SPDCTR = 6; // 右边电机速度控制 8 | 9 | Servo myservo; 10 | 11 | void setup() { 12 | pinMode(LEFT_EN, OUTPUT); 13 | pinMode(RIGHT_EN, OUTPUT); 14 | pinMode(LEFT_SPDCTR, OUTPUT); 15 | pinMode(RIGHT_SPDCTR, OUTPUT); 16 | digitalWrite(LEFT_EN, LOW); 17 | analogWrite(LEFT_SPDCTR, 96); 18 | digitalWrite(RIGHT_EN, LOW); 19 | analogWrite(RIGHT_SPDCTR, 96); 20 | 21 | myservo.attach(9); 22 | myservo.write(94); 23 | } 24 | 25 | void loop() { 26 | myservo.write(91); 27 | delay(100); 28 | myservo.write(96); 29 | delay(100); 30 | } 31 | -------------------------------------------------------------------------------- /EXP_3/README.md: -------------------------------------------------------------------------------- 1 | # 实验 3:传感器的基本使用 2 | 3 | ## Arduino Cheat Sheet 4 | 5 | * [函数速查](https://www.arduino.cc/reference/en/#functions) 6 | * [串口](https://www.arduino.cc/reference/en/language/functions/communication/serial/) 7 | * [中文函数速查](http://wiki.dfrobot.com.cn/index.php/Arduino%E7%BC%96%E7%A8%8B%E5%8F%82%E8%80%83%E6%89%8B%E5%86%8C) 8 | * [某个做得挺好的商家的 Wiki](http://wiki.dfrobot.com.cn/) 9 | * [我们使用的套件 Wiki](http://openjumper.cn/product-manuals/) 10 | 11 | ## 任务 12 | 13 | 使用基本的传感器,熟悉并接上线,测试一下,如: 14 | 15 | * 写出基本的超声的使用程序; 16 | * 测试手上的传感器是否工作和阈值是否异常; 17 | * 使用库把 MPU6050 的数据读出来; 18 | * 写出计算轮子速度的程序,可能需要中断与。 19 | -------------------------------------------------------------------------------- /EXP_3/sketch_distance/sketch_distance.ino: -------------------------------------------------------------------------------- 1 | /* 2 | 红外传感器和巡线传感器通用此代码。 3 | */ 4 | #define RED_PIN 4 5 | 6 | int read_int; 7 | void setup() { 8 | Serial.begin(9600); 9 | pinMode(RED_PIN, INPUT); 10 | } 11 | 12 | void loop() { 13 | read_int = digitalRead(RED_PIN); 14 | if (read_int == HIGH) { 15 | Serial.println("HIGH"); 16 | } 17 | else if (read_int == LOW) { 18 | Serial.println("LOW"); 19 | } 20 | delay(100); 21 | } 22 | -------------------------------------------------------------------------------- /EXP_3/sketch_ultrasonic/sketch_ultrasonic.ino: -------------------------------------------------------------------------------- 1 | #define TRIG_PIN 8 2 | #define ECHO_PIN 9 3 | const int SOUND_SPEED = 340; // sound speed in m/s 4 | 5 | unsigned long interval; // time interval in microseconds 6 | unsigned long distance; // distance in centimeters 7 | 8 | void setup() { 9 | Serial.begin(9600); 10 | pinMode(TRIG_PIN, OUTPUT); 11 | pinMode(ECHO_PIN, INPUT); 12 | } 13 | 14 | void loop() { 15 | /* send a 10us HIGH pulse to trigger */ 16 | digitalWrite(TRIG_PIN, LOW); 17 | delayMicroseconds(2); 18 | digitalWrite(TRIG_PIN, HIGH); 19 | delayMicroseconds(10); 20 | digitalWrite(TRIG_PIN, LOW); 21 | 22 | /* measure and convert */ 23 | interval = float(pulseIn(ECHO_PIN, HIGH)); // microseconds 24 | distance = interval * SOUND_SPEED / 20000; // centimeters 25 | 26 | /* feedback */ 27 | Serial.print("Interval = "); 28 | Serial.print(interval); //串口输出等待时间的原始数据 29 | Serial.print("; Distance = "); 30 | Serial.print(distance); //串口输出距离换算成cm的结果 31 | Serial.println("cm"); 32 | 33 | delay(500); 34 | } 35 | -------------------------------------------------------------------------------- /EXP_4/README.md: -------------------------------------------------------------------------------- 1 | # 实验 4:高级控制 2 | 3 | ## 预备知识 4 | 5 | ### OLED 6 | 7 | * 车上搭载的 OLED 为 0.96 寸,128×64 分辨率,使用 I2C 总线进行通讯。 8 | 9 | * 我们使用库 SSD1306 来进行驱动。先新建一个对象: 10 | 11 | ```c 12 | SSD1306 oled(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, 0); 13 | ``` 14 | 15 | * 然后基本的操作为清除显示数据和将缓冲区的数据显示出来: 16 | 17 | ```c 18 | oled.clear(); 19 | oled.display(); 20 | ``` 21 | 22 | * 将字符串写入缓冲区的操作为: 23 | 24 | ```c 25 | oled.drawstring(char_num, line_num, "motor"); 26 | ``` 27 | 28 | 第一个参数为从该行第几位开始显示,第二个参数为在第几行显示。 29 | 30 | ### 电压 31 | 32 | * 锂电池标准电压为 3.7 V,当电池充满电时为 4.2 V,最低允许放电到 3.6 V,建议放电到 3.7 V 时进行充电(以上均为无负荷时测量值),车上使用的电池为两节串联,也就是充满电理论值为 8.4 V,放电到 7.4 V 时建议进行充电。 33 | 34 | * 因为该电池无保护板进行电池管理,故请同学认真对待电压问题。 35 | 36 | * 电压采集是使用 A0 口,转换函数为: 37 | $$ 38 | V=\frac{5.371\times D}{100}\ \ \ \ \text{(V单位为伏特)} 39 | $$ 40 | 41 | ## 任务 42 | 43 | * 实现 OLED 显示的驱动,将电压值输出到屏幕上,然后改进显示方式将其它调试参数也一并打印到上面。 44 | * 当电压低于 7.4 V 时停止使用大功率用电器,如电机与舵机,提醒去充电。 45 | * 整理代码,理清小车的基本控制思路。 46 | 47 | -------------------------------------------------------------------------------- /EXP_4/sketch_oled/define.h: -------------------------------------------------------------------------------- 1 | // OLED 2 | #include 3 | #define OLED_DC 10 4 | #define OLED_CLK 19 5 | #define OLED_MOSI 13 6 | #define OLED_RESET 12 7 | 8 | // SERVO pin 9 | #define SERVO 9 10 | 11 | // Motor 12 | #define Ldirection 11 13 | #define Lspeed 5 14 | #define Rspeed 6 15 | #define Rdirection 3 16 | -------------------------------------------------------------------------------- /EXP_4/sketch_oled/sketch_oled.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include "define.h" 3 | 4 | SSD1306 oled(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, 0); 5 | int read_int; 6 | double voltage; 7 | 8 | const int LEFT_EN = 11; // 左边电机使能 9 | const int LEFT_SPDCTR = 5; // 左边电机速度控制 10 | const int RIGHT_EN = 3; // 右边电机使能 11 | const int RIGHT_SPDCTR = 6; // 右边电机速度控制 12 | 13 | Servo myservo; 14 | int left_speed = 96; 15 | int right_speed = 96; 16 | int servo_degree = 94; 17 | 18 | void setup() { 19 | pinMode(A0, INPUT); 20 | oled.ssd1306_init(SSD1306_SWITCHCAPVCC); 21 | oled.clear(); // clears the screen and buffer 22 | 23 | // init motor and servo 24 | pinMode(LEFT_EN, OUTPUT); 25 | pinMode(RIGHT_EN, OUTPUT); 26 | pinMode(LEFT_SPDCTR, OUTPUT); 27 | pinMode(RIGHT_SPDCTR, OUTPUT); 28 | digitalWrite(LEFT_EN, LOW); 29 | analogWrite(LEFT_SPDCTR, left_speed); 30 | digitalWrite(RIGHT_EN, LOW); 31 | analogWrite(RIGHT_SPDCTR, right_speed); 32 | 33 | myservo.attach(9); 34 | myservo.write(servo_degree); 35 | } 36 | 37 | void loop() { 38 | oled.clear(); // clears the screen and buffer 39 | oled.clear(); 40 | read_int = analogRead(A0); 41 | voltage = read_int * 5.371 / 100.0; 42 | 43 | // show voltage 44 | String read_str(voltage); 45 | read_str += " V."; 46 | oled.drawstring(0, 0, (char*)read_str.c_str()); 47 | 48 | // show speed and degree information 49 | oled.drawstring(0, 3, (char*)(String("Left speed: ") + String(left_speed)).c_str()); 50 | oled.drawstring(0, 4, (char*)(String("Right speed: ") + String(right_speed)).c_str()); 51 | oled.drawstring(0, 5, (char*)(String("Servo degree: ") + String(servo_degree)).c_str()); 52 | 53 | // if battery is low, give warning 54 | if (voltage < 7.4) { 55 | oled.drawstring(0, 1, (char*)"Low battery!"); 56 | left_speed = 0; 57 | right_speed = 0; 58 | myservo.detach(); 59 | } else { 60 | left_speed = 96; 61 | right_speed = 96; 62 | } 63 | 64 | // refresh motor and display 65 | analogWrite(LEFT_SPDCTR, left_speed); 66 | analogWrite(RIGHT_SPDCTR, right_speed); 67 | oled.display(); // display the buffer 68 | delay(1000); 69 | } 70 | -------------------------------------------------------------------------------- /EXP_5/sketch_alongwall/define.h: -------------------------------------------------------------------------------- 1 | #ifndef _DEFINE_H_ 2 | #define _DEFINE_H_ 3 | 4 | // OLED 5 | #include 6 | #define OLED_DC 10 7 | #define OLED_CLK 19 8 | #define OLED_MOSI 13 9 | #define OLED_RESET 12 10 | 11 | // Encoder 12 | #define ENCODER_L 8 13 | #define DIRECTION_L 4 14 | #define ENCODER_R 7 15 | #define DIRECTION_R 2 16 | 17 | 18 | // SERVO 19 | #define SERVO_PIN 9 20 | 21 | // Motor 22 | #define LDIRECTION_PIN 11 23 | #define RDIRECTION_PIN 3 24 | #define LSPEED_PIN 5 25 | #define RSPEED_PIN 6 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /EXP_5/sketch_alongwall/sensor.h: -------------------------------------------------------------------------------- 1 | /* 电源电压 */ 2 | double getVoltage() { 3 | int read_int = analogRead(A0); // 读电压原始值 4 | double voltage = read_int * 5.371 / 100.0; // 换算为伏特 5 | return voltage; 6 | } 7 | 8 | /* 红外传感器:探测前方是否有障碍物(bool) */ 9 | bool getBarrier(int RED_PIN=12) { 10 | static bool is_inited = false; 11 | if(!is_inited) { 12 | pinMode(RED_PIN, INPUT); 13 | is_inited = true; 14 | } 15 | 16 | // 返回true代表有障碍物 17 | return digitalRead(RED_PIN) == LOW; 18 | } 19 | 20 | /* 超声传感器:获取距离(厘米) */ 21 | unsigned long getDistance(int TRIG_PIN=A1, int ECHO_PIN=A2) { 22 | static bool is_inited = false; 23 | if(!is_inited) { 24 | pinMode(TRIG_PIN, OUTPUT); 25 | pinMode(ECHO_PIN, INPUT); 26 | is_inited = true; 27 | } 28 | 29 | const int SOUND_SPEED = 340; // 音速 30 | 31 | /* send a 10us HIGH pulse to trigger */ 32 | digitalWrite(TRIG_PIN, LOW); 33 | delayMicroseconds(2); 34 | digitalWrite(TRIG_PIN, HIGH); 35 | delayMicroseconds(10); 36 | digitalWrite(TRIG_PIN, LOW); 37 | 38 | /* measure and convert */ 39 | unsigned long interval = float(pulseIn(ECHO_PIN, HIGH)); // 微秒 40 | unsigned long distance = interval * SOUND_SPEED / 20000; // 厘米 41 | 42 | return distance > 1000 ? 9999 : distance; // 太大则认为无效 43 | } 44 | -------------------------------------------------------------------------------- /EXP_5/sketch_alongwall/sketch_alongwall.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include "define.h" 3 | #include "sensor.h" 4 | 5 | /* 用全局变量保存小车的状态 */ 6 | // SSD1306 oled(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, 0); 7 | Servo myservo; 8 | 9 | int left_direction, right_direction; 10 | int left_speed, right_speed; // 真实转速,不用考虑方向 11 | int servo_degree; 12 | 13 | /* 同时改变两个车轮的转速,参数为期望的真实转速 */ 14 | void setSpeed(int speed) { 15 | int left_velocity = left_direction==LOW ? speed : 255-speed; 16 | int right_velocity = right_direction==LOW ? speed : 255-speed; 17 | analogWrite(LSPEED_PIN, left_velocity); 18 | analogWrite(RSPEED_PIN, right_velocity); 19 | 20 | // 更新状态 21 | left_speed = speed; 22 | right_speed = speed; 23 | } 24 | 25 | 26 | /* 同时改变两个车轮的方向:LOW-前进,HIGH-后退 */ 27 | void setDirection(int direction) { 28 | digitalWrite(LDIRECTION_PIN, direction); 29 | digitalWrite(RDIRECTION_PIN, direction); 30 | 31 | // 更新状态 32 | left_direction = direction; 33 | right_direction = direction; 34 | } 35 | 36 | 37 | /* 改变舵机角度 */ 38 | void setServo(int degree) { 39 | myservo.write(degree); 40 | } 41 | 42 | 43 | void setup() { 44 | pinMode(A0, INPUT); // 初始化电压口 45 | // oled.ssd1306_init(SSD1306_SWITCHCAPVCC); // 初始化显示屏 46 | // oled.clear(); 47 | 48 | // 初始化电机 49 | pinMode(LDIRECTION_PIN, OUTPUT); 50 | pinMode(RDIRECTION_PIN, OUTPUT); 51 | pinMode(LSPEED_PIN, OUTPUT); 52 | pinMode(RSPEED_PIN, OUTPUT); 53 | 54 | setDirection(LOW); 55 | setSpeed(70); 56 | 57 | // 初始化舵机 58 | myservo.attach(SERVO_PIN); 59 | setServo(94); 60 | } 61 | 62 | 63 | void loop() { 64 | // oled.clear(); 65 | 66 | // 显示电压 67 | // oled.drawstring(0, 0, (char*)(String(getVoltage()) + " V.").c_str()); 68 | 69 | // 显示左右电机速度以及舵机角度 70 | // oled.drawstring(0, 2, (char*)( String("Movement:") + String(left_speed) + String(",") + 71 | // String(right_speed) + String(",") + String(servo_degree) 72 | // ).c_str()); 73 | 74 | // 若电压低则显示警告,并停止电机 75 | // int cache_left_speed, cache_right_speed, cache_servo_degree; 76 | // bool battery_refresh = false; 77 | // if(voltage < 7.4 and battery_refresh) { 78 | // battery_refresh = true; 79 | // cache_left_speed = left_speed; 80 | // cache_right_speed = right_speed; 81 | // cache_servo_degree = servo_degree; 82 | // oled.drawstring(48, 0, (char*)"Low battery!"); 83 | // left_speed = 0; 84 | // right_speed = 0; 85 | // } 86 | // else { // 电压恢复,重新开始运转 87 | // battery_refresh = false; 88 | // left_speed = cache_left_speed; 89 | // right_speed = cache_right_speed; 90 | // servo_degree = cache_servo_degree; 91 | // } 92 | 93 | int distance = getDistance(); 94 | if(distance < 10) { 95 | setServo(102); 96 | } 97 | else if(distance > 20) { 98 | setServo(86); 99 | } 100 | else { 101 | setServo(94); 102 | } 103 | 104 | // 显示传感器 105 | bool barrier = getBarrier(); 106 | // oled.drawstring(0, 4, (char*)String(barrier ? "True" : "False").c_str()); 107 | // oled.drawstring(0, 5, (char*)(String(distance) + String(" cm.")).c_str()); 108 | 109 | if(barrier) { 110 | setDirection(HIGH); 111 | setSpeed(70); 112 | delay(1000); 113 | setDirection(LOW); 114 | setSpeed(0); 115 | delay(1000); 116 | setServo(180); 117 | delay(500); 118 | setSpeed(70); 119 | delay(2500 * 1.25); 120 | setSpeed(0); 121 | delay(500); 122 | setServo(94); 123 | delay(500); 124 | setSpeed(70); 125 | } 126 | 127 | if(distance > 60) { 128 | setSpeed(0); 129 | setServo(25); 130 | delay(500); 131 | setSpeed(70); 132 | delay(1000); 133 | setSpeed(0); 134 | delay(500); 135 | setServo(94); 136 | delay(500); 137 | setSpeed(70); 138 | } 139 | 140 | 141 | // oled.display(); 142 | // delay(200); 143 | } 144 | -------------------------------------------------------------------------------- /EXP_5/sketch_alongwall_old/define.h: -------------------------------------------------------------------------------- 1 | #ifndef _DEFINE_H_ 2 | #define _DEFINE_H_ 3 | 4 | // OLED 5 | #include 6 | #define OLED_DC 10 7 | #define OLED_CLK 19 8 | #define OLED_MOSI 13 9 | #define OLED_RESET 12 10 | 11 | // SERVO pin 12 | #define SERVO 9 13 | //Encoder 14 | #define ENCODER_L 8 15 | #define DIRECTION_L 4 16 | #define ENCODER_R 7 17 | #define DIRECTION_R 2 18 | // Motor 19 | #define Ldirection 11 20 | #define Lspeed 5 21 | #define Rspeed 6 22 | #define Rdirection 3 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /EXP_5/sketch_alongwall_old/sensor.h: -------------------------------------------------------------------------------- 1 | /* 用红外传感器探测前方是否有障碍物(bool) */ 2 | bool getBarrier(int RED_PIN=12) { 3 | static bool is_inited = false; 4 | if(!is_inited) { 5 | pinMode(RED_PIN, INPUT); 6 | is_inited = true; 7 | } 8 | 9 | // 返回true代表有障碍物 10 | return digitalRead(RED_PIN) == LOW; 11 | } 12 | 13 | /* 从超声传感器获取距离(厘米) */ 14 | unsigned long getDistance(int TRIG_PIN=8, int ECHO_PIN=10) { 15 | static bool is_inited = false; 16 | if(!is_inited) { 17 | pinMode(TRIG_PIN, OUTPUT); 18 | pinMode(ECHO_PIN, INPUT); 19 | is_inited = true; 20 | } 21 | 22 | const int SOUND_SPEED = 340; 23 | 24 | /* send a 10us HIGH pulse to trigger */ 25 | digitalWrite(TRIG_PIN, LOW); 26 | delayMicroseconds(2); 27 | digitalWrite(TRIG_PIN, HIGH); 28 | delayMicroseconds(10); 29 | digitalWrite(TRIG_PIN, LOW); 30 | 31 | /* measure and convert */ 32 | unsigned long interval = float(pulseIn(ECHO_PIN, HIGH)); // microseconds 33 | unsigned long distance = interval * SOUND_SPEED / 20000; // centimeters 34 | 35 | return distance > 1000 ? 9999 : distance; // 太大则认为无效 36 | } 37 | -------------------------------------------------------------------------------- /EXP_5/sketch_alongwall_old/sketch_alongwall_old.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include "define.h" 3 | #include "sensor.h" 4 | 5 | /* 常量 */ 6 | const int LEFT_EN = 11; // 左边电机使能 7 | const int LEFT_SPDCTR = 5; // 左边电机速度控制 8 | const int RIGHT_EN = 3; // 右边电机使能 9 | const int RIGHT_SPDCTR = 6; // 右边电机速度控制 10 | 11 | /* 全局变量 */ 12 | SSD1306 oled(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, 0); 13 | Servo myservo; 14 | int left_speed = 70; 15 | int right_speed = 70; 16 | int servo_degree = 94; 17 | int read_int; 18 | double voltage; 19 | int state = 0; 20 | 21 | void setup() { 22 | pinMode(A0, INPUT); // 初始化电压口 23 | oled.ssd1306_init(SSD1306_SWITCHCAPVCC); // 初始化显示屏 24 | oled.clear(); 25 | 26 | // 初始化电机 27 | pinMode(LEFT_EN, OUTPUT); 28 | pinMode(RIGHT_EN, OUTPUT); 29 | pinMode(LEFT_SPDCTR, OUTPUT); 30 | pinMode(RIGHT_SPDCTR, OUTPUT); 31 | digitalWrite(LEFT_EN, LOW); 32 | analogWrite(LEFT_SPDCTR, left_speed); 33 | digitalWrite(RIGHT_EN, LOW); 34 | analogWrite(RIGHT_SPDCTR, right_speed); 35 | 36 | // 初始化舵机 37 | myservo.attach(9); 38 | myservo.write(servo_degree); 39 | 40 | // 初始化串口(可选) 41 | Serial.begin(9600); 42 | } 43 | 44 | void loop() { 45 | oled.clear(); 46 | 47 | read_int = analogRead(A0); // 读电压原始值 48 | voltage = read_int * 5.371 / 100.0; // 换算为伏特 49 | 50 | // 显示电压 51 | String read_str(voltage); 52 | read_str += " V."; 53 | oled.drawstring(0, 0, (char*)read_str.c_str()); 54 | 55 | // 显示左右电机速度以及舵机角度 56 | oled.drawstring(0, 2, (char*)( String("Movement:") + String(left_speed) + String(",") + 57 | String(right_speed) + String(",") + String(servo_degree) 58 | ).c_str()); 59 | 60 | // 若电压低则显示警告,并停止电机 61 | // int cache_left_speed, cache_right_speed, cache_servo_degree; 62 | // bool battery_refresh = false; 63 | // if(voltage < 7.4 and battery_refresh) { 64 | // battery_refresh = true; 65 | // cache_left_speed = left_speed; 66 | // cache_right_speed = right_speed; 67 | // cache_servo_degree = servo_degree; 68 | // oled.drawstring(48, 0, (char*)"Low battery!"); 69 | // left_speed = 0; 70 | // right_speed = 0; 71 | // } 72 | // else { // 电压恢复,重新开始运转 73 | // battery_refresh = false; 74 | // left_speed = cache_left_speed; 75 | // right_speed = cache_right_speed; 76 | // servo_degree = cache_servo_degree; 77 | // } 78 | 79 | int distance = getDistance(); 80 | if(distance < 10) { 81 | myservo.write(102); 82 | } 83 | else if(distance > 20) { 84 | myservo.write(86); 85 | } 86 | else { 87 | myservo.write(94); 88 | } 89 | 90 | // 显示传感器 91 | bool barrier = getBarrier(); 92 | oled.drawstring(0, 4, (char*)String(barrier ? "True" : "False").c_str()); 93 | oled.drawstring(0, 5, (char*)(String(distance) + String(" cm.")).c_str()); 94 | 95 | if(barrier) { 96 | digitalWrite(LEFT_EN, HIGH); 97 | digitalWrite(RIGHT_EN, HIGH); 98 | analogWrite(LEFT_SPDCTR, 255-70); 99 | analogWrite(RIGHT_SPDCTR, 255-70); 100 | delay(1000); 101 | digitalWrite(LEFT_EN, LOW); 102 | digitalWrite(RIGHT_EN, LOW); 103 | analogWrite(LEFT_SPDCTR, 0); 104 | analogWrite(RIGHT_SPDCTR, 0); 105 | delay(1000); 106 | servo_degree = 180; 107 | myservo.write(servo_degree); 108 | delay(500); 109 | analogWrite(LEFT_SPDCTR, 70); 110 | analogWrite(RIGHT_SPDCTR, 70); 111 | delay(2500 * 1.25); 112 | analogWrite(LEFT_SPDCTR, 0); 113 | analogWrite(RIGHT_SPDCTR, 0); 114 | delay(500); 115 | myservo.write(94); 116 | delay(500); 117 | analogWrite(LEFT_SPDCTR, 70); 118 | analogWrite(RIGHT_SPDCTR, 70); 119 | } 120 | 121 | if(distance > 60) { 122 | analogWrite(LEFT_SPDCTR, 0); 123 | analogWrite(RIGHT_SPDCTR, 0); 124 | servo_degree = 25; 125 | myservo.write(servo_degree); 126 | delay(500); 127 | analogWrite(LEFT_SPDCTR, 70); 128 | analogWrite(RIGHT_SPDCTR, 70); 129 | delay(1000); 130 | analogWrite(LEFT_SPDCTR, 0); 131 | analogWrite(RIGHT_SPDCTR, 0); 132 | delay(500); 133 | myservo.write(94); 134 | delay(500); 135 | analogWrite(LEFT_SPDCTR, 70); 136 | analogWrite(RIGHT_SPDCTR, 70); 137 | } 138 | 139 | 140 | oled.display(); 141 | // delay(200); 142 | } 143 | -------------------------------------------------------------------------------- /EXP_6/sketch_pid/define.h: -------------------------------------------------------------------------------- 1 | #ifndef _DEFINE_H_ 2 | #define _DEFINE_H_ 3 | 4 | // OLED 5 | #include 6 | #define OLED_DC 10 7 | #define OLED_CLK 19 8 | #define OLED_MOSI 13 9 | #define OLED_RESET 12 10 | 11 | // Encoder 12 | #define ENCODER_L 8 13 | #define DIRECTION_L 4 14 | #define ENCODER_R 7 15 | #define DIRECTION_R 2 16 | 17 | // SERVO 18 | #define SERVO_PIN 9 19 | 20 | // Motor 21 | #define LDIRECTION_PIN 11 22 | #define RDIRECTION_PIN 3 23 | #define LSPEED_PIN 5 24 | #define RSPEED_PIN 6 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /EXP_6/sketch_pid/sketch_pid.ino: -------------------------------------------------------------------------------- 1 | #include "define.h" 2 | #include 3 | #include 4 | #include 5 | 6 | Servo myservo; 7 | int left_direction, right_direction; 8 | int left_speed, right_speed; // 设置的真实转速,不用考虑方向 9 | int servo_degree; 10 | int wheel_degree = 0; 11 | 12 | 13 | /* 同时改变两个车轮的转速,参数为期望的真实转速 */ 14 | void setSpeed(int speed) { 15 | int left_velocity = left_direction==LOW ? speed : 255-speed; 16 | int right_velocity = right_direction==LOW ? speed : 255-speed; 17 | analogWrite(LSPEED_PIN, left_velocity); 18 | analogWrite(RSPEED_PIN, right_velocity); 19 | 20 | // 更新状态 21 | left_speed = speed; 22 | right_speed = speed; 23 | } 24 | 25 | 26 | /* 同时改变两个车轮的方向:LOW-前进,HIGH-后退 */ 27 | void setDirection(int direction) { 28 | digitalWrite(LDIRECTION_PIN, direction); 29 | digitalWrite(RDIRECTION_PIN, direction); 30 | 31 | // 更新状态 32 | left_direction = direction; 33 | right_direction = direction; 34 | } 35 | 36 | 37 | /* 改变舵机角度 */ 38 | void setServo(int degree) { 39 | myservo.write(degree); 40 | servo_degree = degree; 41 | } 42 | 43 | 44 | void handlerR() { 45 | if (digitalRead(ENCODER_R) == LOW) //如果是下降沿触发的中断 46 | { 47 | if (digitalRead(DIRECTION_R) == LOW) 48 | wheel_degree++; //根据另外一相电平判定方向 49 | else 50 | wheel_degree--; 51 | } 52 | else //如果是上升沿触发的中断 53 | { 54 | if (digitalRead(DIRECTION_R) == LOW) 55 | wheel_degree--; //根据另外一相电平判定方向 56 | else 57 | wheel_degree++; 58 | } 59 | } 60 | 61 | 62 | void setup() { 63 | // 初始化编码器引脚,获取轮子转过的角度 64 | pinMode(ENCODER_L, INPUT); 65 | pinMode(DIRECTION_L, INPUT); 66 | pinMode(ENCODER_R, INPUT); 67 | pinMode(DIRECTION_R, INPUT); 68 | attachInterrupt(0, handlerR, CHANGE); //开启外部中断 编码器接口1 69 | attachPinChangeInterrupt(DIRECTION_R, handlerR, CHANGE); //开启外部中断 编码器接口2 70 | 71 | Serial.begin(9600); 72 | Serial.setTimeout(50); 73 | 74 | // 初始化电机 75 | pinMode(LDIRECTION_PIN, OUTPUT); 76 | pinMode(RDIRECTION_PIN, OUTPUT); 77 | pinMode(LSPEED_PIN, OUTPUT); 78 | pinMode(RSPEED_PIN, OUTPUT); 79 | setDirection(LOW); 80 | setSpeed(70); 81 | 82 | // 定时器 83 | MsTimer2::set(10, getWheelDegree); 84 | MsTimer2::start(); 85 | } 86 | 87 | /* 88 | pwm+=Kp[e(k)-e(k-1)]+Ki*e(k)+Kd[e(k)-2e(k-1)+e(k-2)] 89 | e(k)代表本次偏差 90 | e(k-1)代表上一次的偏差 以此类推 91 | pwm代表增量输出 92 | 在我们的速度控制闭环系统里面,只使用PI控制 93 | pwm+=Kp[e(k)-e(k-1)]+Ki*e(k) 94 | */ 95 | 96 | float Bias, Last_bias, Pwm; 97 | int Incremental_PI_A(int Encoder, int Target) { 98 | float Velocity_KP = 1.0; 99 | float Velocity_KI = 1.0; 100 | Bias = Encoder - Target; //计算偏差 101 | Pwm += Velocity_KP * (Bias - Last_bias) + Velocity_KI * Bias; //增量式PI控制器 102 | if (Pwm > 255) Pwm = 255; //限幅 103 | if (Pwm < -255) Pwm = -255; //限幅 104 | Last_bias = Bias; // 保存上一次偏差 105 | return Pwm; // 增量输出 106 | } 107 | 108 | 109 | int real_speed; // 通过编码器计算出的车轮实际速度 110 | void getWheelDegree() { 111 | static int old_wheel_degree = 0; 112 | real_speed = wheel_degree - old_wheel_degree; 113 | old_wheel_degree = wheel_degree; 114 | } 115 | 116 | 117 | void loop () { 118 | delay(100); 119 | Serial.println(real_speed, DEC); // 可用串口绘图器观察 120 | setSpeed(Incremental_PI_A(real_speed, 70)); 121 | } 122 | -------------------------------------------------------------------------------- /EXP_7/EXP_7_1/sketch_following/define.h: -------------------------------------------------------------------------------- 1 | #ifndef _DEFINE_H_ 2 | #define _DEFINE_H_ 3 | 4 | // OLED 5 | #include 6 | #define OLED_DC 10 7 | #define OLED_CLK 19 8 | #define OLED_MOSI 13 9 | #define OLED_RESET 12 10 | 11 | // Encoder 12 | #define ENCODER_L 8 13 | #define DIRECTION_L 4 14 | #define ENCODER_R 7 15 | #define DIRECTION_R 2 16 | 17 | 18 | // SERVO 19 | #define SERVO_PIN 9 20 | 21 | // Motor 22 | #define LDIRECTION_PIN 11 23 | #define RDIRECTION_PIN 3 24 | #define LSPEED_PIN 5 25 | #define RSPEED_PIN 6 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /EXP_7/EXP_7_1/sketch_following/sensor.h: -------------------------------------------------------------------------------- 1 | /* 电源电压 */ 2 | double getVoltage() { 3 | int read_int = analogRead(A0); // 读电压原始值 4 | double voltage = read_int * 5.371 / 100.0; // 换算为伏特 5 | return voltage; 6 | } 7 | 8 | /* 红外传感器:探测前方是否有障碍物(bool) */ 9 | bool getBarrier(int RED_PIN=12) { 10 | static bool is_inited = false; 11 | if(!is_inited) { 12 | pinMode(RED_PIN, INPUT); 13 | is_inited = true; 14 | } 15 | 16 | // 返回true代表有障碍物 17 | return digitalRead(RED_PIN) == LOW; 18 | } 19 | 20 | /* 超声传感器:获取距离(厘米) */ 21 | unsigned long getDistance(int TRIG_PIN=A1, int ECHO_PIN=A2) { 22 | static bool is_inited = false; 23 | if(!is_inited) { 24 | pinMode(TRIG_PIN, OUTPUT); 25 | pinMode(ECHO_PIN, INPUT); 26 | is_inited = true; 27 | } 28 | 29 | const int SOUND_SPEED = 340; // 音速 30 | 31 | /* send a 10us HIGH pulse to trigger */ 32 | digitalWrite(TRIG_PIN, LOW); 33 | delayMicroseconds(2); 34 | digitalWrite(TRIG_PIN, HIGH); 35 | delayMicroseconds(10); 36 | digitalWrite(TRIG_PIN, LOW); 37 | 38 | /* measure and convert */ 39 | unsigned long interval = float(pulseIn(ECHO_PIN, HIGH)); // 微秒 40 | unsigned long distance = interval * SOUND_SPEED / 20000; // 厘米 41 | 42 | return distance > 1000 ? 9999 : distance; // 太大则认为无效 43 | } 44 | -------------------------------------------------------------------------------- /EXP_7/EXP_7_1/sketch_following/sketch_following.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include "define.h" 3 | #include "sensor.h" 4 | 5 | /* 用全局变量保存小车的状态 */ 6 | Servo myservo; 7 | 8 | int left_direction, right_direction; 9 | int left_speed, right_speed; // 真实转速,不用考虑方向 10 | int servo_degree; 11 | 12 | /* 同时改变两个车轮的转速,参数为期望的真实转速 */ 13 | void setSpeed(int speed) { 14 | int left_velocity = left_direction==LOW ? speed : 255-speed; 15 | int right_velocity = right_direction==LOW ? speed : 255-speed; 16 | analogWrite(LSPEED_PIN, left_velocity); 17 | analogWrite(RSPEED_PIN, right_velocity); 18 | 19 | // 更新状态 20 | left_speed = speed; 21 | right_speed = speed; 22 | } 23 | 24 | 25 | /* 同时改变两个车轮的方向:LOW-前进,HIGH-后退 */ 26 | void setDirection(int direction) { 27 | digitalWrite(LDIRECTION_PIN, direction); 28 | digitalWrite(RDIRECTION_PIN, direction); 29 | 30 | // 更新状态 31 | left_direction = direction; 32 | right_direction = direction; 33 | } 34 | 35 | 36 | /* 改变舵机角度 */ 37 | void setServo(int degree) { 38 | myservo.write(degree); 39 | } 40 | 41 | 42 | void setup() { 43 | pinMode(A0, INPUT); // 初始化电压口 44 | 45 | // 初始化电机 46 | pinMode(LDIRECTION_PIN, OUTPUT); 47 | pinMode(RDIRECTION_PIN, OUTPUT); 48 | pinMode(LSPEED_PIN, OUTPUT); 49 | pinMode(RSPEED_PIN, OUTPUT); 50 | 51 | setDirection(LOW); 52 | setSpeed(70); 53 | 54 | // 初始化舵机 55 | myservo.attach(SERVO_PIN); 56 | setServo(94); 57 | 58 | Serial.begin(9600); 59 | } 60 | 61 | 62 | void loop() { 63 | int distance = getDistance(); 64 | if(distance > 35) { 65 | setDirection(LOW); 66 | setSpeed(80); 67 | } 68 | else if(distance > 25) { 69 | setDirection(LOW); 70 | setSpeed(60); 71 | } 72 | else if(distance > 15) { 73 | setDirection(LOW); 74 | setSpeed(0); 75 | } 76 | else { 77 | setDirection(HIGH); 78 | setSpeed(70); 79 | } 80 | 81 | Serial.println(distance, DEC); 82 | } 83 | -------------------------------------------------------------------------------- /EXP_7/EXP_7_2/sketch_linetracking/define.h: -------------------------------------------------------------------------------- 1 | #ifndef _DEFINE_H_ 2 | #define _DEFINE_H_ 3 | 4 | // Encoder 5 | #define ENCODER_L 8 6 | #define DIRECTION_L 4 7 | #define ENCODER_R 7 8 | #define DIRECTION_R 2 9 | 10 | 11 | // SERVO 12 | #define SERVO_PIN 9 13 | 14 | // Motor 15 | #define LDIRECTION_PIN 11 16 | #define RDIRECTION_PIN 3 17 | #define LSPEED_PIN 5 18 | #define RSPEED_PIN 6 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /EXP_7/EXP_7_2/sketch_linetracking/sketch_linetracking.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include "define.h" 3 | 4 | #define BLACK LOW 5 | #define WHITE HIGH 6 | 7 | /* 用全局变量保存小车的状态 */ 8 | Servo myservo; 9 | 10 | int left_direction, right_direction; 11 | int servo_degree; 12 | 13 | void setSpeed(int right, int left) { 14 | // 左轮 15 | if(left<=0) { 16 | digitalWrite(LDIRECTION_PIN, LOW); 17 | analogWrite(LSPEED_PIN, -left); 18 | } 19 | else { 20 | digitalWrite(LDIRECTION_PIN, HIGH); 21 | analogWrite(LSPEED_PIN, -left); 22 | } 23 | 24 | // 右轮 25 | if(right<=0) { 26 | digitalWrite(RDIRECTION_PIN, LOW); 27 | analogWrite(RSPEED_PIN, -right); 28 | } 29 | else { 30 | digitalWrite(RDIRECTION_PIN, HIGH); 31 | analogWrite(RSPEED_PIN, -right); 32 | } 33 | } 34 | 35 | 36 | /* 同时改变两个车轮的方向:LOW-前进,HIGH-后退 */ 37 | void setDirection(int direction) { 38 | digitalWrite(LDIRECTION_PIN, direction); 39 | digitalWrite(RDIRECTION_PIN, direction); 40 | 41 | // 更新状态 42 | left_direction = direction; 43 | right_direction = direction; 44 | } 45 | 46 | 47 | /* 改变舵机角度 */ 48 | void setServo(int degree) { 49 | myservo.write(degree); 50 | } 51 | 52 | 53 | int privious = 0; // 记录原来的运动方向:左、中、右分别表示为-1、0、1 54 | int speed_norm = 200; 55 | int speed_fast = 150, speed_slow = -150; 56 | int servo_left = 120, servo_right = 60; 57 | 58 | void setup() { 59 | // 初始化三个巡线传感器 60 | pinMode(10, INPUT); 61 | pinMode(12, INPUT); 62 | pinMode(13, INPUT); 63 | 64 | // 初始化电机 65 | pinMode(LDIRECTION_PIN, OUTPUT); 66 | pinMode(RDIRECTION_PIN, OUTPUT); 67 | pinMode(LSPEED_PIN, OUTPUT); 68 | pinMode(RSPEED_PIN, OUTPUT); 69 | 70 | // 初始化舵机 71 | myservo.attach(SERVO_PIN); 72 | setServo(94); 73 | myservo.write(94); 74 | 75 | // 设定初始运动模式 76 | setDirection(HIGH); // 倒车 77 | setSpeed(speed_norm, speed_norm); // 初始速度 78 | } 79 | 80 | 81 | void loop() { 82 | int L = digitalRead(13); 83 | int M = digitalRead(12); 84 | int R = digitalRead(10); 85 | 86 | if(L==WHITE && M==BLACK && R==WHITE) { // 直走 87 | setServo(94); 88 | setSpeed(speed_norm, speed_norm); 89 | } 90 | else if(L==WHITE && M==WHITE && R==BLACK) { // 右转 91 | privious = 1; 92 | setServo(servo_right); 93 | setSpeed(speed_fast, speed_slow); 94 | } 95 | else if(L==BLACK && M==WHITE && R==WHITE) { // 左转 96 | privious = -1; 97 | setServo(servo_left); 98 | setSpeed(speed_slow, speed_fast); 99 | } 100 | else if(L==WHITE && M==WHITE && R==WHITE) { // 偏离轨道后修正 101 | if(privious<=0) { 102 | setServo(servo_left); 103 | setSpeed(speed_slow, speed_fast); 104 | } 105 | else { 106 | setServo(servo_right); 107 | setSpeed(speed_fast, speed_slow); 108 | } 109 | } 110 | else if(L==BLACK && M==BLACK && R==BLACK) { // 反向 111 | if(privious>0) { 112 | setServo(servo_left); // 向左回轨道 113 | } 114 | else { 115 | setServo(servo_right); // 向右回轨道 116 | } 117 | } 118 | else{ 119 | setServo(94); 120 | setSpeed(speed_norm, speed_norm); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /EXP_8/cv/linetracking_cv.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | import cv2 as cv 3 | import numpy as np 4 | import serial 5 | import os 6 | import math 7 | import time 8 | 9 | def gogogo(servo_degree, left, right, debug=True): 10 | """ 11 | 向串口发送舵机、电机速度消息。 12 | """ 13 | info="{},{},{}\n".format(servo_degree, left, right).encode() 14 | if debug: 15 | print(info) 16 | ser.write(info) 17 | 18 | 19 | print(cv.__version__) 20 | cam = cv.VideoCapture(0) 21 | 22 | # open serial port 23 | ser=serial.Serial('/dev/ttyUSB0', 115200) 24 | # ser.open() 25 | 26 | print(cam.set(cv.CAP_PROP_FRAME_WIDTH, 1920)) 27 | print(cam.set(cv.CAP_PROP_FRAME_HEIGHT, 1080)) 28 | if not cam.isOpened(): 29 | print("Cannot open camera") 30 | exit() 31 | 32 | while True: 33 | # time.sleep(0.2) 34 | #Read the frame 35 | ret,frame = cam.read() 36 | 37 | # info=ser.read(100) 38 | 39 | #Down scale 40 | frame=cv.resize(frame, (480,270)) 41 | 42 | if not ret: 43 | print("Can't receive frame (stream end?). Exiting ...") 44 | break 45 | 46 | #Change to gray 47 | gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY) 48 | rows,cols = gray.shape 49 | 50 | #Rotate 51 | # M=cv.getRotationMatrix2D((cols/2,rows/2),180,1) 52 | # gray=cv.warpAffine(gray,M,(cols,rows)) 53 | 54 | # Crop the img (y,x) 55 | # gray=gray[180:540,210:700] 56 | gray = gray[90:270,105:350] 57 | 58 | # Binarization 59 | ret, gray=cv.threshold(gray,60,255,cv.THRESH_BINARY) 60 | 61 | #Show the img 62 | cv.imshow('img', gray) 63 | 64 | left_matrix=gray[160-5:160+5,92-5:92+5] 65 | # print(left_matrix) 66 | left= (1 if left_matrix.sum()//255>50 else 0) 67 | 68 | mid_matrix=gray[160-5:160+5,128-5:128+5] 69 | mid= (1 if mid_matrix.sum()//255>50 else 0) 70 | 71 | right_matrix=gray[160-5:160+5,160-5:160+5] 72 | right= (1 if right_matrix.sum()//255>50 else 0) 73 | 74 | ################################################ 75 | L, M, R = left, mid, right 76 | print(L, M, R) 77 | BLACK, WHITE = 0, 1 78 | 79 | privious = 0 80 | speed_norm = 75 81 | speed_fast = 100 82 | speed_slow = -100 83 | servo_left = 120 84 | servo_right = 60 85 | 86 | if(L==WHITE and M==BLACK and R==WHITE): 87 | gogogo(94, speed_norm, speed_norm) 88 | elif (L==WHITE and M==WHITE and R==BLACK): # 右转 89 | privious = 1 90 | gogogo(servo_right, speed_fast, speed_slow) 91 | elif (L==BLACK and M==WHITE and R==WHITE): # 左转 92 | privious = -1 93 | gogogo(servo_left, speed_slow, speed_fast) 94 | elif (L==WHITE and M==WHITE and R==WHITE): # 偏离轨道后修正 95 | if(privious<=0): 96 | gogogo(servo_left,speed_slow,speed_fast) 97 | else: 98 | gogogo(servo_right,speed_fast,speed_slow) 99 | elif (L==BLACK and M==BLACK and R==BLACK): # 反向 100 | if(privious>0): 101 | gogogo(servo_left,-speed_slow,-speed_slow) 102 | else: 103 | gogogo(servo_right,-speed_slow,-speed_slow) 104 | else: 105 | gogogo(94,speed_norm,speed_norm) 106 | 107 | 108 | ################################################ 109 | 110 | cv.destroyAllWindows() -------------------------------------------------------------------------------- /EXP_8/sketch_code4car/define.h: -------------------------------------------------------------------------------- 1 | #ifndef _DEFINE_H_ 2 | #define _DEFINE_H_ 3 | 4 | #define AIN1 11 5 | #define AIN2 5 6 | #define BIN1 6 7 | #define BIN2 3 8 | #define SERVO 9 9 | 10 | //Encoder 11 | #define ENCODER_L 8 //编码器采集引脚 每路2个 共4个 12 | #define DIRECTION_L 4 13 | #define ENCODER_R 7 14 | #define DIRECTION_R 2 15 | 16 | // OLED 17 | #define OLED_DC 10 18 | #define OLED_CLK 19 19 | #define OLED_MOSI 13 20 | #define OLED_RESET 12 21 | 22 | 23 | 24 | // SERVO 25 | #define SERVO_PIN 9 26 | 27 | // Motor 28 | #define LDIRECTION_PIN 11 29 | #define RDIRECTION_PIN 3 30 | #define LSPEED_PIN 5 31 | #define RSPEED_PIN 6 32 | #endif 33 | -------------------------------------------------------------------------------- /EXP_8/sketch_code4car/sketch_code4car.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "define.h" 5 | 6 | SSD1306 oled(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, 0); 7 | Servo myservo; 8 | 9 | String input_str = ""; 10 | String input_strBuffer = ""; // a String to hold incoming data 11 | 12 | // 在OLED上显示内容,通过函数重载支持字符串和数字 13 | void oledShow(uint8_t row, uint8_t col, String str) { 14 | oled.drawstring(col, row, (char *)str.c_str()); 15 | } 16 | void oledShow(uint8_t row, uint8_t col, int num) { 17 | String str(num); 18 | oled.drawstring(col, row, (char *)str.c_str()); 19 | } 20 | void oledShow(uint8_t row, uint8_t col, double num) { 21 | String str(num); 22 | oled.drawstring(col, row, (char *)str.c_str()); 23 | } 24 | 25 | 26 | /* 改变舵机角度 */ 27 | int servo_degree = 94; 28 | void setServo(uint8_t degree) { 29 | myservo.write(degree); 30 | servo_degree = degree; 31 | } 32 | 33 | int left_speed = 0, right_speed = 0; 34 | /* 改变电机速度,电机前轮,舵机后轮 */ 35 | void setSpeed(int left, int right) { 36 | // 左轮 37 | if(left<=0) { 38 | digitalWrite(RDIRECTION_PIN, LOW); 39 | analogWrite(RSPEED_PIN, -left); 40 | } 41 | else { 42 | digitalWrite(RDIRECTION_PIN, HIGH); 43 | analogWrite(RSPEED_PIN, 255-left); 44 | } 45 | left_speed = left; 46 | 47 | // 右轮 48 | if(right<=0) { 49 | digitalWrite(LDIRECTION_PIN, LOW); 50 | analogWrite(LSPEED_PIN, -right); 51 | } 52 | else { 53 | digitalWrite(LDIRECTION_PIN, HIGH); 54 | analogWrite(LSPEED_PIN, 255-right); 55 | } 56 | right_speed = right; 57 | } 58 | 59 | void serialEvent() { 60 | while (Serial.available()) { 61 | char inChar = (char)Serial.read(); 62 | if (inChar == '\n' || inChar == '\r') { 63 | input_str = input_strBuffer; 64 | input_strBuffer = ""; 65 | break; 66 | } 67 | input_strBuffer += inChar; 68 | } 69 | } 70 | 71 | 72 | volatile long Velocity_L, Velocity_R; 73 | void READ_ENCODER_L() { 74 | if (digitalRead(ENCODER_L) == LOW) { 75 | if (digitalRead(DIRECTION_L) == LOW) 76 | Velocity_L--; 77 | else 78 | Velocity_L++; 79 | } else { 80 | if (digitalRead(DIRECTION_L) == LOW) 81 | Velocity_L++; 82 | else 83 | Velocity_L--; 84 | } 85 | } 86 | 87 | void READ_ENCODER_R() { 88 | if (digitalRead(ENCODER_R) == LOW) { 89 | if (digitalRead(DIRECTION_R) == LOW) 90 | Velocity_R++; 91 | else 92 | Velocity_R--; 93 | } else { 94 | if (digitalRead(DIRECTION_R) == LOW) 95 | Velocity_R--; 96 | else 97 | Velocity_R++; 98 | } 99 | } 100 | 101 | void setup() { 102 | // Init OLED screen 103 | oled.ssd1306_init(SSD1306_SWITCHCAPVCC); 104 | oled.clear(); // clears the screen and buffer 105 | 106 | // Init motor control 107 | pinMode(AIN1, OUTPUT); 108 | pinMode(AIN2, OUTPUT); 109 | pinMode(BIN1, OUTPUT); 110 | pinMode(BIN2, OUTPUT); 111 | 112 | // Init servo 113 | myservo.attach(SERVO); 114 | 115 | // Init encoder 116 | pinMode(ENCODER_L, INPUT); 117 | pinMode(DIRECTION_L, INPUT); 118 | pinMode(ENCODER_R, INPUT); 119 | pinMode(DIRECTION_R, INPUT); 120 | 121 | pinMode(A0, INPUT); 122 | 123 | // Init interrupt 124 | attachInterrupt(0, READ_ENCODER_R, CHANGE); 125 | attachPinChangeInterrupt(4, READ_ENCODER_L, CHANGE); 126 | 127 | delay(1000); 128 | Serial.begin(115200); 129 | Serial.println("[+] Setup done."); 130 | } 131 | 132 | void loop() { 133 | oled.clear(); 134 | 135 | // 显示串口收到的字符串 136 | oledShow(0, 0, input_str); 137 | // 显示电压 138 | oledShow(2, 0, String(analogRead(0)*5.371/100) + "V"); 139 | // 显示电机速度和舵机角度 140 | oledShow(4, 0, servo_degree); 141 | oledShow(5, 0, right_speed); 142 | oledShow(5, 35, left_speed); 143 | 144 | int start_pos = input_str.indexOf('S'); 145 | int end_pos = input_str.indexOf('E'); 146 | input_str = input_str.substring(start_pos+1, end_pos); 147 | Serial.println(input_str); 148 | 149 | int com_pos = input_str.indexOf(','); 150 | int next_servo_degree = input_str.substring(0, com_pos).toInt(); 151 | String temp_str = input_str.substring(com_pos+1); 152 | 153 | com_pos = temp_str.indexOf(','); 154 | int next_left_speed = temp_str.substring(0, com_pos).toInt(); 155 | temp_str = temp_str.substring(com_pos+1); 156 | 157 | int next_right_speed = temp_str.toInt(); 158 | 159 | setServo(next_servo_degree); 160 | setSpeed(next_left_speed, next_right_speed); 161 | 162 | oled.display(); 163 | } 164 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2019 Jed Zhang 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 机器人导论 2 | 3 | * 中山大学计算机学院 4 | * 机器人导论(Introduction to Robotics, DCS361) 5 | * 教师:万海 6 | * 2019 秋季学期(Fall 2019) 7 | 8 | 9 | ## 目录 10 | 11 | | 序号 | 任务 | 简介 | 12 | | ----- | ---------------------------------------------------------- | ------------------------------------------------------- | 13 | | EXP_1 | [LED 呼吸灯](EXP_1) | 用 PWN 实现板载 LED 呼吸灯效果 | 14 | | EXP_2 | [①简单通讯协议](EXP_2/EXP_2_1);[②启动车辆](EXP_2/EXP_2_2) | ①通过串口输入指令控制板载 LED 亮度;②使小车能够直线行驶 | 15 | | EXP_3 | [传感器](EXP_3) | 超声波传感器、红外传感器、巡线传感器的基本使用 | 16 | | EXP_4 | [高级控制](EXP_4) | 实现 OLED 显示的驱动,在屏幕上显示电压等参数 | 17 | | EXP_5 | [车辆沿墙避障](EXP_5) | 使车子沿着墙壁前进,能检测固定障碍物(拐角)并绕行 | 18 | | EXP_6 | [PID](EXP_6) | 对电机速度加入 PID 控制(实际只用 PI) | 19 | | EXP_7 | [①简单跟随](EXP_7/EXP_7_1);[②小车巡线](EXP_7/EXP_7_2) | ①让小车跟着某个物体前进;②沿固定黑线赛道正反各走一次 | 20 | | EXP_8 | [使用摄像头进行巡线](EXP_8) | 用摄像头和 OpenCV 进行巡线,不允许使用其它传感器 | 21 | 22 | 注:代码仅供参考,部分实验中使用“奇技淫巧”,实现方法可能并不严谨。 23 | 24 | 25 | ## Arduino Cheat Sheet 26 | 27 | * [函数速查](https://www.arduino.cc/reference/en/#functions) 28 | * [串口](https://www.arduino.cc/reference/en/language/functions/communication/serial/) 29 | * [中文函数速查](http://wiki.dfrobot.com.cn/index.php/Arduino%E7%BC%96%E7%A8%8B%E5%8F%82%E8%80%83%E6%89%8B%E5%86%8C) 30 | * [某个做得挺好的商家的 Wiki](http://wiki.dfrobot.com.cn/) 31 | * [我们使用的套件 Wiki](http://openjumper.cn/product-manuals/) 32 | 33 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/Adafruit_CircuitPlayground.h: -------------------------------------------------------------------------------- 1 | // this is a placeholder file. dont undo or delete this 'clever hack' :) 2 | 3 | #include 4 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/README.md: -------------------------------------------------------------------------------- 1 | # Adafruit CircuitPlayground Library [![Build Status](https://travis-ci.com/adafruit/Adafruit_CircuitPlayground.svg?branch=master)](https://travis-ci.com/adafruit/Adafruit_CircuitPlayground) 2 | 3 | 4 | 5 | This is a library for the Adafruit CircuitPlayground boards: 6 | * https://www.adafruit.com/products/3333 7 | * https://www.adafruit.com/product/3000 8 | 9 | Check out the links above for our tutorials and wiring diagrams. 10 | 11 | Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! 12 | 13 | Written by Limor Fried/Ladyada and others for Adafruit Industries. 14 | MIT license, all text above must be included in any redistribution 15 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/FidgetSpinner/FidgetSpinner.h: -------------------------------------------------------------------------------- 1 | // Fidget spinner logic. 2 | // This class represents a fidget spinner that can be spun to a specified 3 | // velocity and then over time will slow down and stop. The spinner keeps track 4 | // of its continuous (floating point) position value within the range 0...<10 5 | // so it can map to CircuitPlayground pixel positions easily.// Author: Tony DiCola 6 | // License: MIT License (https://opensource.org/licenses/MIT) 7 | // Usage: 8 | // - Create an instance of the class (specifying a custom decay value between 0 and 1, 9 | // the lower the decay the faster the spinner slows down). 10 | // - Call spin to start the spinner moving at the specified velocity (in pixels/second). 11 | // - Call getPosition periodically to get the current spinner position given an elapsed 12 | // amount of seconds since the last getPosition call. 13 | #ifndef FIDGETANIMATION_H 14 | #define FIDGETANIMATION_H 15 | 16 | class FidgetSpinner { 17 | public: 18 | FidgetSpinner(float decay=0.5): 19 | _position(0.0), _velocity(0.0), _elapsedS(0.0), _decay(decay) 20 | {} 21 | 22 | void spin(float velocity) { 23 | // Start the fidget spinner moving at the specified velocity (in pixels/second). 24 | // Over time the spinner will slow down based on its decay value. 25 | _velocity = velocity; 26 | _elapsedS = 0.0; // Reset elapsed time to start the decay from the beginning. 27 | } 28 | 29 | float getPosition(float deltaS) { 30 | // Get the fidget spinner's current position after moving for the specified number 31 | // of milliseconds. Returns a continuous value in the range 0...<10. 32 | _elapsedS += deltaS; 33 | // Compute current velocity based on exponential decay of initial 34 | // velocity over the elapsed time (this causes the spinner to 35 | // gradually slow down and mimics the effects of friction). 36 | float currentVelocity = _velocity*pow(_decay, _elapsedS); 37 | // Now move the position based on the current velocity. 38 | _position += currentVelocity*deltaS; 39 | // Finally make sure position is constrained within 0...<10 range. 40 | _position = fmod(_position, 10.0); 41 | if (_position < 0.0) { 42 | // Ensure position is never negative by wrapping back to the 43 | // same pixel position in a positive location. 44 | _position += 10.0; 45 | } 46 | return _position; 47 | } 48 | 49 | private: 50 | float _position; 51 | float _velocity; 52 | float _elapsedS; 53 | float _decay; 54 | }; 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/FidgetSpinner/PeakDetector.h: -------------------------------------------------------------------------------- 1 | // Signal peak detector using smoothed z-score algorithm. 2 | // Detects when a continuous signal has a significant peak in values. Based on 3 | // algorithm from the answer here: 4 | // https://stackoverflow.com/questions/22583391/peak-signal-detection-in-realtime-timeseries-data/22640362#22640362 5 | // Author: Tony DiCola 6 | // License: MIT License (https://opensource.org/licenses/MIT) 7 | // Usage: 8 | // - Create an instance of the PeakDetector class and configure its lag, threshold, 9 | // and influence. These likely need to be adjust to fit your dataset. See the 10 | // Stack Overflow question above for more details on their meaning. 11 | // - Continually call detect and feed it a new sample value. Detect will return 0 12 | // if no peak was detected, 1 if a positive peak was detected and -1 if a negative 13 | // peak was detected. 14 | #ifndef PEAKDETECTOR_H 15 | #define PEAKDETECTOR_H 16 | 17 | class PeakDetector { 18 | public: 19 | PeakDetector(const int lag=5, const float threshold=3.5, const float influence=0.5): 20 | _lag(lag), _threshold(threshold), _influence(influence), _avg(0.0), _std(0.0), _primed(false), _index(0) 21 | { 22 | // Allocate memory for last samples (used during averaging) and set them all to zero. 23 | _filtered = new float[lag]; 24 | for (int i=0; i (_threshold*_std))) { 43 | // Detected a peak! 44 | // Determine type of peak, positive or negative. 45 | if (sample > _avg) { 46 | result = 1; 47 | } 48 | else { 49 | result = -1; 50 | } 51 | // Save this sample but scaled down based on influence. 52 | _filtered[_index] = (_influence*sample) + ((1.0-_influence)*_filtered[_previousIndex()]); 53 | } 54 | else { 55 | // Did not detect a peak, or not yet primed with enough samples. 56 | // Just record this sample and move on. 57 | _filtered[_index] = sample; 58 | } 59 | // Increment index of next filtered sample. 60 | _incrementIndex(); 61 | // When primed update the average and standard deviation of the most recent 62 | // filtered values. 63 | if (_primed) { 64 | // Compute mean of filtered values. 65 | _avg = 0.0; 66 | for (int i=0; i<_lag; ++i) { 67 | _avg += _filtered[i]; 68 | } 69 | _avg = _avg/float(_lag); 70 | // Compute standard deviation of filtered values. 71 | _std = 0.0; 72 | for (int i=0; i<_lag; ++i) { 73 | _std += pow(_filtered[i]-_avg, 2.0); 74 | } 75 | _std = sqrt(_std/float(_lag)); 76 | } 77 | return result; 78 | } 79 | 80 | float getAvg() { 81 | // Return the current signal average, useful for debugging. 82 | return _avg; 83 | } 84 | 85 | float getStd() { 86 | // Return the current signal standard deviation, useful for debugging. 87 | return _std; 88 | } 89 | 90 | private: 91 | float _lag; 92 | float _threshold; 93 | float _influence; 94 | float* _filtered; 95 | float _avg; 96 | float _std; 97 | bool _primed; 98 | int _index; 99 | 100 | void _incrementIndex() { 101 | // Increment the index of the current sample. 102 | _index += 1; 103 | if (_index >= _lag) { 104 | // Loop back to start of sample buffer when full, but be sure to note 105 | // when this happens to indicate we are primed with enough samples. 106 | _index = 0; 107 | _primed = true; 108 | } 109 | } 110 | 111 | int _previousIndex() { 112 | // Find the index of the last sample. 113 | int result = _index-1; 114 | if (result < 0) { 115 | result = _lag-1; 116 | } 117 | return result; 118 | } 119 | }; 120 | 121 | #endif 122 | 123 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/Hello_CircuitPlayground/Hello_Accelerometer/Hello_Accelerometer.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | float X, Y, Z; 4 | 5 | void setup() { 6 | Serial.begin(9600); 7 | CircuitPlayground.begin(); 8 | } 9 | 10 | void loop() { 11 | X = CircuitPlayground.motionX(); 12 | Y = CircuitPlayground.motionY(); 13 | Z = CircuitPlayground.motionZ(); 14 | 15 | Serial.print("X: "); 16 | Serial.print(X); 17 | Serial.print(" Y: "); 18 | Serial.print(Y); 19 | Serial.print(" Z: "); 20 | Serial.println(Z); 21 | 22 | delay(1000); 23 | } 24 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/Hello_CircuitPlayground/Hello_Blink/Hello_Blink.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void setup() { 4 | CircuitPlayground.begin(); 5 | } 6 | 7 | void loop() { 8 | CircuitPlayground.redLED(HIGH); 9 | delay(500); 10 | CircuitPlayground.redLED(LOW); 11 | delay(500); 12 | } 13 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/Hello_CircuitPlayground/Hello_Buttons/Hello_Buttons.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | bool leftButtonPressed; 4 | bool rightButtonPressed; 5 | 6 | void setup() { 7 | Serial.begin(9600); 8 | CircuitPlayground.begin(); 9 | } 10 | 11 | void loop() { 12 | leftButtonPressed = CircuitPlayground.leftButton(); 13 | rightButtonPressed = CircuitPlayground.rightButton(); 14 | 15 | Serial.print("Left Button: "); 16 | if (leftButtonPressed) { 17 | Serial.print("DOWN"); 18 | } else { 19 | Serial.print(" UP"); 20 | } 21 | Serial.print(" Right Button: "); 22 | if (rightButtonPressed) { 23 | Serial.print("DOWN"); 24 | } else { 25 | Serial.print(" UP"); 26 | } 27 | Serial.println(); 28 | 29 | delay(1000); 30 | } 31 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/Hello_CircuitPlayground/Hello_LightSensor/Hello_LightSensor.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int value; 4 | 5 | void setup() { 6 | Serial.begin(9600); 7 | CircuitPlayground.begin(); 8 | } 9 | 10 | void loop() { 11 | value = CircuitPlayground.lightSensor(); 12 | 13 | Serial.print("Light Sensor: "); 14 | Serial.println(value); 15 | 16 | delay(1000); 17 | } 18 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/Hello_CircuitPlayground/Hello_NeoPixels/Hello_NeoPixels.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void setup() { 4 | CircuitPlayground.begin(); 5 | } 6 | 7 | void loop() { 8 | CircuitPlayground.clearPixels(); 9 | 10 | delay(500); 11 | 12 | CircuitPlayground.setPixelColor(0, 255, 0, 0); 13 | CircuitPlayground.setPixelColor(1, 128, 128, 0); 14 | CircuitPlayground.setPixelColor(2, 0, 255, 0); 15 | CircuitPlayground.setPixelColor(3, 0, 128, 128); 16 | CircuitPlayground.setPixelColor(4, 0, 0, 255); 17 | 18 | CircuitPlayground.setPixelColor(5, 0xFF0000); 19 | CircuitPlayground.setPixelColor(6, 0x808000); 20 | CircuitPlayground.setPixelColor(7, 0x00FF00); 21 | CircuitPlayground.setPixelColor(8, 0x008080); 22 | CircuitPlayground.setPixelColor(9, 0x0000FF); 23 | 24 | delay(5000); 25 | } 26 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/Hello_CircuitPlayground/Hello_SlideSwitch/Hello_SlideSwitch.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | bool slideSwitch; 4 | 5 | void setup() { 6 | Serial.begin(9600); 7 | CircuitPlayground.begin(); 8 | } 9 | 10 | void loop() { 11 | slideSwitch = CircuitPlayground.slideSwitch(); 12 | 13 | Serial.print("Slide Switch: "); 14 | if (slideSwitch) { 15 | Serial.print("+"); 16 | } else { 17 | Serial.print("-"); 18 | } 19 | Serial.println(); 20 | 21 | delay(1000); 22 | } 23 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/Hello_CircuitPlayground/Hello_SoundSensor/Hello_SoundSensor.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | float value; 4 | 5 | void setup() { 6 | Serial.begin(9600); 7 | CircuitPlayground.begin(); 8 | } 9 | 10 | void loop() { 11 | // Take 10 milliseconds of sound data to calculate 12 | value = CircuitPlayground.mic.soundPressureLevel(10); 13 | 14 | Serial.print("Sound Sensor SPL: "); 15 | Serial.println(value); 16 | 17 | delay(90); 18 | } -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/Hello_CircuitPlayground/Hello_Speaker/Hello_Speaker.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void setup() { 4 | CircuitPlayground.begin(); 5 | } 6 | 7 | void loop() { 8 | CircuitPlayground.playTone(500, 100); 9 | delay(1000); 10 | } 11 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/Hello_CircuitPlayground/Hello_Temperature/Hello_Temperature.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | float tempC, tempF; 4 | 5 | void setup() { 6 | Serial.begin(9600); 7 | CircuitPlayground.begin(); 8 | } 9 | 10 | void loop() { 11 | tempC = CircuitPlayground.temperature(); 12 | tempF = CircuitPlayground.temperatureF(); 13 | 14 | Serial.print("tempC: "); 15 | Serial.print(tempC); 16 | Serial.print(" tempF: "); 17 | Serial.println(tempF); 18 | 19 | delay(1000); 20 | } 21 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/Hello_CircuitPlayground/README.md: -------------------------------------------------------------------------------- 1 | # Hello Circuit Playground 2 | A set of very basic example sketches to demonstrate the various components 3 | of the [Circuit Playground](https://www.adafruit.com/products/3000). 4 | These sketches were tested and verified with: 5 | * Circuit Playground Developer Edition 6 | * Ubuntu 16.04 LTS 7 | * Arduino IDE 1.6.11 8 | * Adafruit AVR Boards 1.4.9 9 | * Adafruit Circuit Playground Library 1.6.1 10 | 11 | ## Hello_Blink 12 | Blinks the little red LED next to the micro USB connector once per second. 13 | 14 | ## Hello_SlideSwitch 15 | The position (+ or -) of the slide switch is sent to the serial monitor once 16 | per second. 17 | ``` 18 | Slide Switch: - 19 | Slide Switch: + 20 | Slide Switch: + 21 | ``` 22 | 23 | ## Hello_Buttons 24 | The position (UP or DOWN) of the two push buttons are sent to the serial 25 | monitor once per second. 26 | ``` 27 | Left Button: UP Right Button: UP 28 | Left Button: DOWN Right Button: UP 29 | Left Button: UP Right Button: UP 30 | Left Button: UP Right Button: DOWN 31 | ``` 32 | 33 | ## Hello_LightSensor 34 | The reading (0-1023) from the light sensor is sent to the serial monitor once 35 | per second. 36 | ``` 37 | Light Sensor: 962 38 | Light Sensor: 954 39 | Light Sensor: 275 40 | Light Sensor: 192 41 | Light Sensor: 688 42 | ``` 43 | 44 | ## Hello_Temperature 45 | The temperature is sent to the serial monitor once per second. 46 | ``` 47 | tempC: 28.25 tempF: 83.02 48 | tempC: 29.71 tempF: 85.64 49 | tempC: 30.72 tempF: 87.30 50 | tempC: 31.85 tempF: 89.32 51 | ``` 52 | 53 | ## Hello_Accelerometer 54 | The readings (in m/s2) from the 3 axes of the accelerometer are sent 55 | to the serial monitor once per second. (1G ~= 9.8 m/s2) 56 | ``` 57 | X: -0.33 Y: 2.41 Z: 9.40 58 | X: -1.25 Y: 4.20 Z: 1.86 59 | X: -7.95 Y: -3.50 Z: -2.47 60 | X: 0.11 Y: -8.38 Z: 2.25 61 | X: -2.28 Y: 2.73 Z: 9.10 62 | ``` 63 | 64 | ## Hello_SoundSensor 65 | The reading (0-1023) from the sound sensor (microphone) is sent to the serial 66 | monitor once per second. 67 | ``` 68 | Sound Sensor: 339 69 | Sound Sensor: 339 70 | Sound Sensor: 1023 71 | Sound Sensor: 10 72 | Sound Sensor: 15 73 | Sound Sensor: 1023 74 | Sound Sensor: 336 75 | ``` 76 | 77 | ## Hello_Speaker 78 | Plays a 500Hz tone for 0.1 seconds on the speaker, followed by 1 second of 79 | silence. 80 | 81 | ## Hello_NeoPixels 82 | Clears all pixels for 0.5 seconds then displays colors on the fist 5 pixels 83 | using individual 8-bit values and the same colors on the next 5 pixels using 84 | 24-bit values. After 5 seconds, this repeats. 85 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/Infrared_Demos/Infrared_NeoPixel/adafruit_mini_codes.h: -------------------------------------------------------------------------------- 1 | /* 2 | IR codes for Adafruit mini remote 3 | https://www.adafruit.com/product/389 4 | Uses NEC protocol 5 | */ 6 | 7 | #define ADAF_MINI_VOLUME_DOWN 0xfd00ff 8 | #define ADAF_MINI_PLAY_PAUSE 0xfd807f 9 | #define ADAF_MINI_VOLUME_UP 0xfd40bf 10 | #define ADAF_MINI_SETUP 0xfd20df 11 | #define ADAF_MINI_UP_ARROW 0xfda05f 12 | #define ADAF_MINI_STOP_MODE 0xfd609f 13 | #define ADAF_MINI_LEFT_ARROW 0xfd10ef 14 | #define ADAF_MINI_ENTER_SAVE 0xfd906f 15 | #define ADAF_MINI_RIGHT_ARROW 0xfd50af 16 | #define ADAF_MINI_0_10_PLUS 0xfd30cf 17 | #define ADAF_MINI_DOWN_ARROW 0xfdb04f 18 | #define ADAF_MINI_REPEAT 0xfd708f 19 | #define ADAF_MINI_1 0xfd08f7 20 | #define ADAF_MINI_2 0xfd8877 21 | #define ADAF_MINI_3 0xfd48b7 22 | #define ADAF_MINI_4 0xfd28d7 23 | #define ADAF_MINI_5 0xfda857 24 | #define ADAF_MINI_6 0xfd6897 25 | #define ADAF_MINI_7 0xfd18e7 26 | #define ADAF_MINI_8 0xfd9867 27 | #define ADAF_MINI_9 0xfd58a7 28 | 29 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/Infrared_Demos/Infrared_Read/Infrared_Read.ino: -------------------------------------------------------------------------------- 1 | /* Infrared_Read.ino Example sketch for IRLib2 and Circuit Playground Express 2 | Illustrates how to receive an IR signal, decode it and print 3 | information about it to the serial monitor. 4 | */ 5 | #include 6 | 7 | #if !defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS) 8 | #error "Infrared support is only for the Circuit Playground Express, it doesn't work with the Classic version" 9 | #endif 10 | 11 | 12 | void setup() { 13 | CircuitPlayground.begin(); 14 | Serial.begin(9600); 15 | 16 | while (!Serial); // Wait until serial console is opened 17 | 18 | CircuitPlayground.irReceiver.enableIRIn(); // Start the receiver 19 | Serial.println("Ready to receive IR signals"); 20 | } 21 | 22 | void loop() { 23 | //Continue looping until you get a complete signal received 24 | if (CircuitPlayground.irReceiver.getResults()) { 25 | CircuitPlayground.irDecoder.decode(); //Decode it 26 | CircuitPlayground.irDecoder.dumpResults(false); //Now print results. Use false for less detail 27 | CircuitPlayground.irReceiver.enableIRIn(); //Restart receiver 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/Infrared_Demos/Infrared_Record/Infrared_Record.ino: -------------------------------------------------------------------------------- 1 | /* Infrared_Record.ino Example sketch for IRLib2 and Circuit Playground Express 2 | Illustrates how to receive an IR signal, decode and save it. 3 | Then retransmit it whenever you push the left pushbutton. 4 | */ 5 | #include 6 | 7 | #if !defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS) 8 | #error "Infrared support is only for the Circuit Playground Express, it doesn't work with the Classic version" 9 | #endif 10 | 11 | 12 | /* IR signals consist of a protocol number, a value, and a number of bits. 13 | * Store all of these values for future use. 14 | */ 15 | uint8_t IR_protocol; 16 | uint32_t IR_value; 17 | uint16_t IR_bits; 18 | 19 | void setup() { 20 | Serial.begin(9600); 21 | while (!Serial); 22 | Serial.println("Send an IR signal and I will record it."); 23 | Serial.println("Press the left button and we will retransmit it."); 24 | CircuitPlayground.begin(); 25 | 26 | CircuitPlayground.irReceiver.enableIRIn(); // Start the receiver 27 | IR_protocol=0; // Indicates we've not received a code yet 28 | } 29 | 30 | void loop() { 31 | /* Receiver will look for a signal and when wa complete frame of data 32 | * has been received, getResults() returns true. Once that happens, 33 | * the receiver stops reccording so you will need to restart it 34 | * after you have processed the data. 35 | */ 36 | if(CircuitPlayground.irReceiver.getResults()) { 37 | //attempt to decode it 38 | if(CircuitPlayground.irDecoder.decode()) { 39 | Serial.println("IR decoded"); 40 | //Print the results. Change parameter to "true" for verbose output. 41 | CircuitPlayground.irDecoder.dumpResults(false); 42 | Serial.println("Saving results. Press left button to retransmit."); 43 | IR_protocol=CircuitPlayground.irDecoder.protocolNum; 44 | IR_value= CircuitPlayground.irDecoder.value; 45 | IR_bits= CircuitPlayground.irDecoder.bits; 46 | } 47 | CircuitPlayground.irReceiver.enableIRIn(); //Restart receiver 48 | } 49 | 50 | /* If the left button is pressed and we have received a code 51 | * retransmit it using the sender. 52 | */ 53 | if (CircuitPlayground.leftButton()) { 54 | Serial.println("Left button pressed!"); 55 | if(IR_protocol) { 56 | CircuitPlayground.irSend.send(IR_protocol, IR_value, IR_bits); 57 | Serial.println("Sending recorded IR signal"); 58 | Serial.print("Protocol:"); Serial.print(IR_protocol,DEC); 59 | Serial.print(" Value:0x"); Serial.print(IR_value,HEX); 60 | Serial.print(" Bits:"); Serial.println(IR_bits,DEC); 61 | } else { 62 | Serial.println("No signal saved yet."); 63 | } 64 | } 65 | } 66 | 67 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/Infrared_Demos/Infrared_Send/Infrared_Send.ino: -------------------------------------------------------------------------------- 1 | /* Infrared_Send.ino Example sketch for IRLib2 and Circuit Playground Express 2 | Illustrates how to transmit an IR signal whenever you do push one of the 3 | built-in pushbuttons. 4 | */ 5 | #include 6 | 7 | #if !defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS) 8 | #error "Infrared support is only for the Circuit Playground Express, it doesn't work with the Classic version" 9 | #endif 10 | 11 | void setup() { 12 | CircuitPlayground.begin(); 13 | } 14 | 15 | //Defines for a Samsung TV using NECx protocol 16 | #define MY_PROTOCOL NECX 17 | #define MY_BITS 32 18 | #define MY_MUTE 0xE0E0F00F 19 | #define MY_POWER 0xE0E040BF 20 | 21 | void loop() { 22 | // If the left button is pressed send a mute code. 23 | if (CircuitPlayground.leftButton()) { 24 | CircuitPlayground.irSend.send(MY_PROTOCOL,MY_MUTE,MY_BITS); 25 | while (CircuitPlayground.leftButton()) {}//wait until button released 26 | } 27 | // If the right button is pressed send a power code. 28 | if (CircuitPlayground.rightButton()) { 29 | CircuitPlayground.irSend.send(MY_PROTOCOL,MY_POWER,MY_BITS); 30 | while (CircuitPlayground.rightButton()) {}//wait until button released 31 | } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/Infrared_Demos/Infrared_Testpattern/Infrared_Testpattern.ino: -------------------------------------------------------------------------------- 1 | /* Infrared_Testpattern.ino Example sketch for IRLib2 and Circuit Playground Express 2 | * Send an easily recognized pattern of bits from one Arduino 3 | * to another to verify that your protocol is working. Load 4 | * this sketch to send a signal. Use the "dump" sketch on the other 5 | * Arduino to receive codes. Open the serial monitor and type the 6 | * number Of the protocol want to test. 7 | */ 8 | #include 9 | 10 | #if !defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS) 11 | #error "Infrared support is only for the Circuit Playground Express, it doesn't work with the Classic version" 12 | #endif 13 | 14 | void setup() { 15 | CircuitPlayground.begin(); 16 | Serial.begin(9600); 17 | while (!Serial); // Wait for serial console 18 | 19 | Serial.println("Type the protocol number: 1-12 Or '-1' for all"); 20 | } 21 | 22 | void sendOne(uint8_t protocol, uint32_t data, uint16_t data2 = 0, uint8_t khz = 0) { 23 | Serial.print("Protocol #"); Serial.print(protocol, DEC); 24 | Serial.print("\t"); Serial.print(Pnames(protocol)); 25 | Serial.print("\t data = 0x"); Serial.print(data, HEX); 26 | 27 | if (data2) { 28 | Serial.print("\t data2 = 0x"); Serial.print(data2, HEX); 29 | Serial.print(" "); Serial.print(data2, DEC); 30 | Serial.print(" dec"); 31 | } 32 | if (khz) { 33 | CircuitPlayground.irSend.send(protocol, data, data2, khz); 34 | Serial.print(" khz="); Serial.println(khz,DEC); 35 | } else { 36 | CircuitPlayground.irSend.send(protocol, data, data2); 37 | Serial.println(); 38 | } 39 | delay(2000); 40 | } 41 | #define PATTERN1 0x12345678 42 | #define ALL1S 0xFFFFFFFF 43 | 44 | void doTest (uint8_t P) { 45 | switch (P) { 46 | case 1: sendOne(1,PATTERN1); //NEC Regular data 47 | sendOne(1,REPEAT_CODE); //NEC Special ditto repeat code 48 | sendOne(1,PATTERN1,40); //Pioneer is NEC with 40 kHz modulation 49 | break; 50 | case 2: sendOne(2,PATTERN1,12); //Sony 12 bits 51 | sendOne(2,PATTERN1,15); //Sony 15 bits 52 | sendOne(2,PATTERN1,20); //Sony 20 bits 53 | break; //Note: Sony always sends three copies of signal 54 | case 3: sendOne(3,ALL1S,13); //RC5 55 | sendOne(3,ALL1S,14); //RC5-F7 56 | sendOne(3,ALL1S,14,57); //RC5-F7-57 57 | break; 58 | case 4: sendOne(4,0x0ffff,20); //RC6-0-16 Original Phillips RC6 59 | sendOne(4,0xcfffff,24); //RC6-6-20 Used by some Sky and Sky+ remotes 60 | sendOne(4,0xcfffff,28); //RC6-6-24 a.k.a. "Replay" protocol 61 | sendOne(4,ALL1S,32); //RC6-6-32 a.k.a. "MCE" protocol 62 | break; 63 | case 5: sendOne(5,ALL1S); //Panasonic_Old 22 bits used by some SA and Cisco cable boxes 64 | break; 65 | case 6: //JVC use "true" for first frame, "false" for repeats 66 | //When "true" it automatically sends one repeat. Use "false" 67 | //for additional repeats. The 2 lines below will actually send 68 | //a total of 3 frames... A first and 2 repeats. 69 | sendOne(6,PATTERN1,true); 70 | sendOne(6,PATTERN1,false); 71 | break; 72 | case 7: sendOne(7,PATTERN1); //NECx used by many Samsung TVs 73 | sendOne(7,REPEAT_CODE); //Some varieties use ditto 74 | break; 75 | case 8: sendOne(8,0x12345,0x1234);//Samsung36 16 bit address +20 data 76 | break; 77 | case 9: sendOne(9,PATTERN1); //G.I.Cable 16 bits with ditto repeat 78 | sendOne(9,REPEAT_CODE); //This will report NEC if both protocols used 79 | break; 80 | case 10: sendOne(10,PATTERN1); //DirecTV default no repeat, 38 khz 81 | sendOne(10,PATTERN1,true);//3rd parameter is repeat flag 82 | sendOne(10,PATTERN1,false,40);//4th is khz, 38, 40, 57 are legal 83 | break; 84 | case 11: sendOne(11,ALL1S,12); //RCMM Phillips protocol used by U-Verse 85 | sendOne(11,ALL1S,24); //also 24 or 32 bit possible 86 | sendOne(11,ALL1S,32); 87 | break; 88 | case 12: sendOne(12,CYKM_MOUSE_MOVE+CYKM_DIR_RIGHT);//Move mouse right 89 | sendOne(12,CYKM_MOUSE_MOVE+CYKM_DIR_UP); //Move mouse up 90 | sendOne(12,CYKM_MOUSE_MOVE+CYKM_DIR_LEFT); //Move mouse left 91 | sendOne(12,CYKM_MOUSE_MOVE+CYKM_DIR_DOWN); //Move mouse down 92 | break; 93 | }; 94 | 95 | } 96 | void loop() { 97 | if (Serial.available () > 0) { 98 | int16_t i = Serial.parseInt(); 99 | if(i==-1) { 100 | for(i=1;i<=12;i++) { 101 | doTest(i); 102 | }; 103 | } else { 104 | doTest(i); 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/Microphone_Demos/soundPressureLevel/soundPressureLevel.ino: -------------------------------------------------------------------------------- 1 | /* This example samples the microphone for 50 milliseconds repeatedly 2 | * and returns the max sound pressure level in dB SPL 3 | * https://en.wikipedia.org/wiki/Sound_pressure 4 | * 5 | * open the serial plotter window in the arduino IDE for a nice graph 6 | * of sound pressure level over time. 7 | */ 8 | 9 | #include 10 | 11 | void setup() { 12 | CircuitPlayground.begin(); 13 | Serial.begin(115200); 14 | } 15 | 16 | void loop() { 17 | Serial.println(CircuitPlayground.mic.soundPressureLevel(50)); 18 | } 19 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/Microphone_Demos/vu_meter/vu_meter.ino: -------------------------------------------------------------------------------- 1 | /* 2 | LED VU meter for Circuit Playground 3 | This is a port of the Adafruit Amplitie project to Circuit Playground. 4 | Based on code for the adjustable sensitivity version of amplitie from: 5 | https://learn.adafruit.com/led-ampli-tie/the-code 6 | 7 | Hardware requirements: 8 | - Circuit Playground 9 | 10 | Software requirements: 11 | - Adafruit Circuit Playground library 12 | 13 | Written by Adafruit Industries. Distributed under the BSD license. 14 | This paragraph must be included in any redistribution. 15 | 16 | */ 17 | #include 18 | #include 19 | #include 20 | 21 | #define SAMPLE_WINDOW 10 // Sample window for average level 22 | #define PEAK_HANG 24 // Time of pause before peak dot falls 23 | #define PEAK_FALL 4 // Rate of falling peak dot 24 | 25 | #define INPUT_FLOOR 56 // Lower range of mic sensitivity in dB SPL 26 | #define INPUT_CEILING 110 // Upper range of mic sensitivity in db SPL 27 | 28 | byte peak = 16; // Peak level of column; used for falling dots 29 | unsigned int sample; 30 | byte dotCount = 0; //Frame counter for peak dot 31 | byte dotHangCount = 0; //Frame counter for holding peak dot 32 | 33 | float mapf(float x, float in_min, float in_max, float out_min, float out_max); 34 | 35 | void setup() 36 | { 37 | CircuitPlayground.begin(); 38 | } 39 | 40 | void loop() 41 | { 42 | int numPixels = CircuitPlayground.strip.numPixels(); 43 | float peakToPeak = 0; // peak-to-peak level 44 | unsigned int c, y; 45 | 46 | //get peak sound pressure level over the sample window 47 | peakToPeak = CircuitPlayground.mic.soundPressureLevel(SAMPLE_WINDOW); 48 | 49 | //limit to the floor value 50 | peakToPeak = max(INPUT_FLOOR, peakToPeak); 51 | 52 | // Serial.println(peakToPeak); 53 | 54 | //Fill the strip with rainbow gradient 55 | for (int i=0;i<=numPixels-1;i++){ 56 | CircuitPlayground.strip.setPixelColor(i,Wheel(map(i,0,numPixels-1,30,150))); 57 | } 58 | 59 | c = mapf(peakToPeak, INPUT_FLOOR, INPUT_CEILING, numPixels, 0); 60 | 61 | // Turn off pixels that are below volume threshold. 62 | if(c < peak) { 63 | peak = c; // Keep dot on top 64 | dotHangCount = 0; // make the dot hang before falling 65 | } 66 | if (c <= numPixels) { // Fill partial column with off pixels 67 | drawLine(numPixels, numPixels-c, CircuitPlayground.strip.Color(0, 0, 0)); 68 | } 69 | 70 | // Set the peak dot to match the rainbow gradient 71 | y = numPixels - peak; 72 | CircuitPlayground.strip.setPixelColor(y-1,Wheel(map(y,0,numPixels-1,30,150))); 73 | CircuitPlayground.strip.show(); 74 | 75 | // Frame based peak dot animation 76 | if(dotHangCount > PEAK_HANG) { //Peak pause length 77 | if(++dotCount >= PEAK_FALL) { //Fall rate 78 | peak++; 79 | dotCount = 0; 80 | } 81 | } 82 | else { 83 | dotHangCount++; 84 | } 85 | } 86 | 87 | //Used to draw a line between two points of a given color 88 | void drawLine(uint8_t from, uint8_t to, uint32_t c) { 89 | uint8_t fromTemp; 90 | if (from > to) { 91 | fromTemp = from; 92 | from = to; 93 | to = fromTemp; 94 | } 95 | for(int i=from; i<=to; i++){ 96 | CircuitPlayground.strip.setPixelColor(i, c); 97 | } 98 | } 99 | 100 | float mapf(float x, float in_min, float in_max, float out_min, float out_max) 101 | { 102 | return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; 103 | } 104 | 105 | // Input a value 0 to 255 to get a color value. 106 | // The colours are a transition r - g - b - back to r. 107 | uint32_t Wheel(byte WheelPos) { 108 | if(WheelPos < 85) { 109 | return CircuitPlayground.strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0); 110 | } 111 | else if(WheelPos < 170) { 112 | WheelPos -= 85; 113 | return CircuitPlayground.strip.Color(255 - WheelPos * 3, 0, WheelPos * 3); 114 | } 115 | else { 116 | WheelPos -= 170; 117 | return CircuitPlayground.strip.Color(0, WheelPos * 3, 255 - WheelPos * 3); 118 | } 119 | } -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/ScratchSensorBoard/ScratchSensorBoard.ino: -------------------------------------------------------------------------------- 1 | // example sketch to turn your circuit playground into a picoboard 2 | // potentiometer is 'simulated' by tilting the cplay (accelerometer Z is reported) 3 | // pin #13 red LED is lit when data is sent to Scratch! 4 | 5 | #include 6 | 7 | #define SCRATCH_DATA_REQUEST 0x01 8 | #define SCRATCH_FW_VER 0x04 9 | 10 | void setup() { 11 | while (!Serial); 12 | Serial.begin(38400); 13 | //Serial.println("Start!"); 14 | 15 | CircuitPlayground.begin(); 16 | pinMode(13, OUTPUT); 17 | } 18 | 19 | void loop() { 20 | if (!Serial.available()) 21 | return; 22 | 23 | char c = Serial.read(); 24 | 25 | if (c != SCRATCH_DATA_REQUEST) 26 | return; 27 | 28 | digitalWrite(13, HIGH); 29 | // data is a request! 30 | sendPacket(0xF, SCRATCH_FW_VER); 31 | sendPacket(0x0, analogRead(A0)); 32 | sendPacket(0x1, analogRead(A1)); 33 | sendPacket(0x2, analogRead(A2)); 34 | if (CircuitPlayground.leftButton() || CircuitPlayground.rightButton()) { 35 | sendPacket(0x3, 0x0); 36 | } else { 37 | sendPacket(0x3, 0xFFFF); 38 | } 39 | sendPacket(0x4, CircuitPlayground.temperature() * 10); 40 | sendPacket(0x5, 1023 - CircuitPlayground.lightSensor()); 41 | float s = CircuitPlayground.mic.soundPressureLevel(10); 42 | sendPacket(0x6, s); 43 | float z = CircuitPlayground.motionZ(); 44 | z *= -50; // reverse direction 45 | z += 512; 46 | sendPacket(0x7, z); 47 | 48 | digitalWrite(13, LOW); 49 | } 50 | 51 | void sendPacket(uint8_t channel, uint16_t data) { 52 | uint8_t packet0, packet1; 53 | 54 | channel &= 0xF; 55 | if (data >= 1024) data = 1023; 56 | 57 | packet0 = 0x80 | (channel << 3) | ((data >> 7) & 0x7); 58 | packet1 = data & 0x7F; 59 | 60 | Serial.write(packet0); 61 | //delay(1); 62 | Serial.write(packet1); 63 | //delay(1); 64 | } 65 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/accelTap/accelTap.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // Adjust this number for the sensitivity of the 'click' force 6 | // this strongly depend on the range! for 16G, try 5-10 7 | // for 8G, try 10-20. for 4G try 20-40. for 2G try 40-80 8 | #define CLICKTHRESHHOLD 120 9 | 10 | void setup(void) { 11 | while (!Serial); 12 | 13 | Serial.begin(9600); 14 | CircuitPlayground.begin(); 15 | 16 | CircuitPlayground.setAccelRange(LIS3DH_RANGE_2_G); // 2, 4, 8 or 16 G! 17 | 18 | // 0 = turn off click detection & interrupt 19 | // 1 = single click only interrupt output 20 | // 2 = double click only interrupt output, detect single click 21 | // Adjust threshhold, higher numbers are less sensitive 22 | CircuitPlayground.setAccelTap(1, CLICKTHRESHHOLD); 23 | 24 | // have a procedure called when a tap is detected 25 | attachInterrupt(digitalPinToInterrupt(CPLAY_LIS3DH_INTERRUPT), tapTime, FALLING); 26 | } 27 | 28 | void tapTime(void) { 29 | // do something :) 30 | Serial.print("Tap! "); 31 | Serial.println(millis()); // the time 32 | } 33 | 34 | void loop() { 35 | /* 36 | // *or* uncomment this for manual polling of tap data 37 | uint8_t click = CircuitPlayground.getAccelTap(); 38 | if (click == 0) return; 39 | if (! (click & 0x30)) return; 40 | Serial.print("Click detected (0x"); Serial.print(click, HEX); Serial.print("): "); 41 | if (click & 0x10) Serial.print(" single click"); 42 | if (click & 0x20) Serial.print(" double click"); 43 | Serial.println(); 44 | 45 | delay(100); 46 | return; 47 | */ 48 | } 49 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/analog_sensors/analog_sensors.ino: -------------------------------------------------------------------------------- 1 | // Circuit Playground Analog Sensor Demo 2 | // Shows how to read an analog sensor like temperature, light, 3 | // sound, or even external inputs and convert the analog value 4 | // to color and sound on the board. Will light up NeoPixel 4 and 5 5 | // with a color proportional to the analog value, and if the slide 6 | // switch is turned to the left will play a music tone proportional 7 | // to the value. 8 | #include 9 | #include 10 | #include 11 | 12 | // Change the analog input value below to try different sensors: 13 | #define ANALOG_INPUT A5 // Specify the analog input to read. 14 | // Circuit Playground has the following 15 | // inputs available: 16 | // - A0 = temperature sensor / thermistor 17 | // - A4 = sound sensor / microphone 18 | // - A5 = light sensor 19 | // - A7 = pin #6 on board 20 | // - A9 = pin #9 on board 21 | // - A10 = pin #10 on board 22 | // - A11 = pin #12 on board 23 | 24 | // These defines set the range of expected analog values. 25 | // This is used to scale the NeoPixels, sound, etc. 26 | #define VALUE_MIN 0 27 | #define VALUE_MAX 200 28 | 29 | // These defines set the range of pixel color when mapping 30 | // to the sensor value. 31 | #define COLOR_RED_MIN 255 32 | #define COLOR_GREEN_MIN 0 33 | #define COLOR_BLUE_MIN 0 34 | 35 | #define COLOR_RED_MAX 0 36 | #define COLOR_GREEN_MAX 0 37 | #define COLOR_BLUE_MAX 255 38 | 39 | // These defines set the range of sound frequencies when 40 | // mapping to the sensor value. 41 | #define TONE_FREQ_MIN 523 // C5 note 42 | #define TONE_FREQ_MAX 988 // B5 note 43 | 44 | 45 | void setup() { 46 | // Setup serial port. 47 | Serial.begin(115200); 48 | Serial.println("Circuit Playground Analog Sensor Demos!"); 49 | 50 | // Setup Circuit Playground library. 51 | CircuitPlayground.begin(); 52 | } 53 | 54 | void loop() { 55 | // Get the sensor sensor value and print it out (can use serial plotter 56 | // to view realtime graph!). 57 | uint16_t value = analogRead(ANALOG_INPUT); 58 | Serial.println(value, DEC); 59 | 60 | // Map the sensor value to a color. 61 | // Use the range of minimum and maximum sensor values and 62 | // min/max colors to do the mapping. 63 | if(value < VALUE_MIN) value = VALUE_MIN; 64 | else if(value > VALUE_MAX) value = VALUE_MAX; 65 | int red = map(value, VALUE_MIN, VALUE_MAX, COLOR_RED_MIN , COLOR_RED_MAX); 66 | int green = map(value, VALUE_MIN, VALUE_MAX, COLOR_GREEN_MIN, COLOR_GREEN_MAX); 67 | int blue = map(value, VALUE_MIN, VALUE_MAX, COLOR_BLUE_MIN , COLOR_BLUE_MAX); 68 | // Gamma correction gives a more linear appearance to brightness ranges 69 | red = CircuitPlayground.gamma8(red); 70 | green = CircuitPlayground.gamma8(green); 71 | blue = CircuitPlayground.gamma8(blue); 72 | 73 | // Light up pixel #4 and 5 with the color. 74 | CircuitPlayground.clearPixels(); 75 | CircuitPlayground.setPixelColor(4, red, green, blue); 76 | CircuitPlayground.setPixelColor(5, red, green, blue); 77 | 78 | // Map the sensor value to a tone frequency. 79 | int frequency = map(value, VALUE_MIN, VALUE_MAX, TONE_FREQ_MIN, TONE_FREQ_MAX); 80 | 81 | // Play the tone if the slide switch is turned on (to the left). 82 | if (CircuitPlayground.slideSwitch()) { 83 | // Play tone of the mapped frequency value for 100 milliseconds. 84 | CircuitPlayground.playTone(frequency, 100); 85 | } 86 | 87 | // Delay for a bit and repeat the loop. 88 | delay(100); 89 | } 90 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/color_sense/color_sense.ino: -------------------------------------------------------------------------------- 1 | // Circuit Playground Color Sensing Example 2 | // Use a NeoPixel RGB LED and light sensor on the Circuit Playground board to 3 | // do basic color detection. By quickly flashing full red, green, and blue color 4 | // light from the NeoPixel the light sensor can read the intensity of the 5 | // reflected light and roughly approximate the color of the object. 6 | // 7 | // After uploading the sketch to Circuit Playground you can press and release the 8 | // left or right button to do a color sense and print the red, green, blue component 9 | // values to the serial monitor (115200 baud). In addition all the NeoPixels on 10 | // the board will be lit up to the detected color. You should hold a brightly 11 | // colored object right above the light sensor and NeoPixel #1 (upper 12 | // left part of board, look for the eye symbol next to the color sensor) when 13 | // performing the color sense. 14 | // 15 | // Author: Limor Fried & Tony DiCola 16 | // License: MIT License (https://opensource.org/licenses/MIT) 17 | #include 18 | #include 19 | #include 20 | 21 | void setup() { 22 | Serial.begin(115200); 23 | // Initialize Circuit Playground library. 24 | CircuitPlayground.begin(); 25 | } 26 | 27 | void loop() { 28 | // Detect if the left or right button is pressed by taking two readings with 29 | // a small delay inbetween. If the button changes state (like it was pressed 30 | // or released) then the two readings will be different. 31 | bool left_first = CircuitPlayground.leftButton(); 32 | bool right_first = CircuitPlayground.rightButton(); 33 | delay(20); 34 | bool left_second = CircuitPlayground.leftButton(); 35 | bool right_second = CircuitPlayground.rightButton(); 36 | // Now check if either button was released, i.e. changed from a true (pressed) 37 | // state to a false (non-pressed) state. 38 | if ((left_first && !left_second) || (right_first && !right_second)) { 39 | // Button was pressed, perform a color sense. 40 | // First turn off all the pixels to make sure they don't interfere with the 41 | // reading. 42 | CircuitPlayground.clearPixels(); 43 | // Now take a color reading (the red, green, blue color components will be 44 | // returned in the parameters passed in). 45 | uint8_t red, green, blue; 46 | CircuitPlayground.senseColor(red, green, blue); 47 | // Print out the color components. 48 | Serial.print("Color: red="); 49 | Serial.print(red, DEC); 50 | Serial.print(" green="); 51 | Serial.print(green, DEC); 52 | Serial.print(" blue="); 53 | Serial.println(blue, DEC); 54 | // Gamma correction makes LED brightness appear more linear 55 | red = CircuitPlayground.gamma8(red); 56 | green = CircuitPlayground.gamma8(green); 57 | blue = CircuitPlayground.gamma8(blue); 58 | // Finally set all the pixels to the detected color. 59 | for (int i=0; i<10; ++i) { 60 | CircuitPlayground.strip.setPixelColor(i, red, green, blue); 61 | } 62 | CircuitPlayground.strip.show(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/comm_badge/comm_badge.ino: -------------------------------------------------------------------------------- 1 | // Speaker demo for Circuit Playground -- when tapped, plays a very short 2 | // digitized sound sample, very quietly (because teeny tiny speaker). 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | // Enable ONE of these lines to pick a sound to play back when tapped: 9 | #include "coin.h" // Super Mario coin sound 10 | //#include "trek.h" // Star Trek TNG communicator noise 11 | 12 | volatile boolean play = false; 13 | 14 | // This function will be called automatically when a tap is detected by the 15 | // accelerometer. This just sets the global flag 'play' to true, which is 16 | // then detected in loop() (where the sound is then played)...doing heavy 17 | // processing within an interrupt function is sometimes considered poor form. 18 | void myFunction() { 19 | play = true; // Hey loop(), play the sound! 20 | } 21 | 22 | void setup() { 23 | CircuitPlayground.begin(); 24 | 25 | // Configure accelerometer for +-4G range, use the tap interrupt 26 | // feature to call myFunction() automatically when tapped. 27 | CircuitPlayground.setAccelRange(LIS3DH_RANGE_4_G); 28 | CircuitPlayground.setAccelTap(1, 127); 29 | attachInterrupt(digitalPinToInterrupt(CPLAY_LIS3DH_INTERRUPT), myFunction, RISING); 30 | } 31 | 32 | void loop() { 33 | while(!play); // Wait for tap interrupt 34 | 35 | // Play sound data in the audio[] array (declared in one of the .h files). 36 | // This function "blocks" -- that is, program flow stops until sound is 37 | // done playing -- it does not play in the background. 38 | CircuitPlayground.speaker.playSound(audio, sizeof(audio), SAMPLE_RATE); 39 | 40 | // Calling speaker.end() after playing a sound is optional -- this will 41 | // turn off the pin 13 LED (it's connected to a microcontroller pin that's 42 | // also related to the speaker), but there's a small audible click when it 43 | // turns off. Tradeoffs! 44 | CircuitPlayground.speaker.end(); 45 | 46 | play = false; // Clear flag, wait for interrupt 47 | } 48 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/demo/demo.ino: -------------------------------------------------------------------------------- 1 | // Demo program for testing library and board - flip the switch to turn on/off buzzer 2 | 3 | #include 4 | 5 | // we light one pixel at a time, this is our counter 6 | uint8_t pixeln = 0; 7 | 8 | void setup() { 9 | //while (!Serial); 10 | Serial.begin(9600); 11 | Serial.println("Circuit Playground test!"); 12 | 13 | CircuitPlayground.begin(); 14 | } 15 | 16 | 17 | void loop() { 18 | // test Red #13 LED 19 | CircuitPlayground.redLED(HIGH); 20 | delay(100); 21 | CircuitPlayground.redLED(LOW); 22 | delay(100); 23 | 24 | /************* TEST CAPTOUCH */ 25 | Serial.print("Capsense #3: "); Serial.println(CircuitPlayground.readCap(3)); 26 | Serial.print("Capsense #2: "); Serial.println(CircuitPlayground.readCap(2)); 27 | if (! CircuitPlayground.isExpress()) { // CPX does not have this captouch pin 28 | Serial.print("Capsense #0: "); Serial.println(CircuitPlayground.readCap(0)); 29 | } 30 | Serial.print("Capsense #1: "); Serial.println(CircuitPlayground.readCap(1)); 31 | Serial.print("Capsense #12: "); Serial.println(CircuitPlayground.readCap(12)); 32 | Serial.print("Capsense #6: "); Serial.println(CircuitPlayground.readCap(6)); 33 | Serial.print("Capsense #9: "); Serial.println(CircuitPlayground.readCap(9)); 34 | Serial.print("Capsense #10: "); Serial.println(CircuitPlayground.readCap(10)); 35 | 36 | /************* TEST SLIDE SWITCH */ 37 | if (CircuitPlayground.slideSwitch()) { 38 | Serial.println("Slide to the left"); 39 | } else { 40 | Serial.println("Slide to the right"); 41 | CircuitPlayground.playTone(500 + pixeln * 500, 100); 42 | } 43 | 44 | /************* TEST 10 NEOPIXELS */ 45 | CircuitPlayground.setPixelColor(pixeln++, CircuitPlayground.colorWheel(25 * pixeln)); 46 | if (pixeln == 11) { 47 | pixeln = 0; 48 | CircuitPlayground.clearPixels(); 49 | } 50 | 51 | /************* TEST BOTH BUTTONS */ 52 | if (CircuitPlayground.leftButton()) { 53 | Serial.println("Left button pressed!"); 54 | } 55 | if (CircuitPlayground.rightButton()) { 56 | Serial.println("Right button pressed!"); 57 | } 58 | 59 | /************* TEST LIGHT SENSOR */ 60 | Serial.print("Light sensor: "); 61 | Serial.println(CircuitPlayground.lightSensor()); 62 | 63 | /************* TEST SOUND SENSOR */ 64 | Serial.print("Sound sensor: "); 65 | Serial.println(CircuitPlayground.mic.soundPressureLevel(10)); 66 | 67 | /************* TEST ACCEL */ 68 | // Display the results (acceleration is measured in m/s*s) 69 | Serial.print("X: "); Serial.print(CircuitPlayground.motionX()); 70 | Serial.print(" \tY: "); Serial.print(CircuitPlayground.motionY()); 71 | Serial.print(" \tZ: "); Serial.print(CircuitPlayground.motionZ()); 72 | Serial.println(" m/s^2"); 73 | 74 | /************* TEST THERMISTOR */ 75 | Serial.print("Temperature "); 76 | Serial.print(CircuitPlayground.temperature()); 77 | Serial.println(" *C"); 78 | } -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/mega_demo/CapTouchDemo.h: -------------------------------------------------------------------------------- 1 | #ifndef CAPTOUCHDEMO_H 2 | #define CAPTOUCHDEMO_H 3 | 4 | #include "Demo.h" 5 | 6 | 7 | #define CAP_SAMPLES 20 // Number of samples to take for a capacitive touch read. 8 | #define TONE_DURATION_MS 100 // Duration in milliseconds to play a tone when touched. 9 | 10 | class CapTouchDemo: public Demo { 11 | public: 12 | uint16_t CAP_THRESHOLD = 200; // Threshold for a capacitive touch (higher = less sensitive). 13 | 14 | CapTouchDemo() { 15 | playSound = false; 16 | if (CircuitPlayground.isExpress()) { 17 | CAP_THRESHOLD = 800; 18 | } else { 19 | CAP_THRESHOLD = 200; 20 | } 21 | } 22 | ~CapTouchDemo() {} 23 | 24 | 25 | virtual void loop() { 26 | // Clear all the neopixels. 27 | for (int i=0; i<10; ++i) { 28 | CircuitPlayground.strip.setPixelColor(i, 0); 29 | } 30 | 31 | // Check if any of the cap touch inputs are pressed and turn on those pixels. 32 | // Also play a tone if in tone playback mode. 33 | if (CircuitPlayground.readCap(0, CAP_SAMPLES) >= CAP_THRESHOLD) { 34 | CircuitPlayground.strip.setPixelColor(3, CircuitPlayground.colorWheel(256/10*3)); 35 | if (playSound) { 36 | CircuitPlayground.playTone(330, TONE_DURATION_MS); // 330hz = E4 37 | } 38 | } 39 | if (CircuitPlayground.readCap(1, CAP_SAMPLES) >= CAP_THRESHOLD) { 40 | CircuitPlayground.strip.setPixelColor(4, CircuitPlayground.colorWheel(256/10*4)); 41 | if (playSound) { 42 | CircuitPlayground.playTone(349, TONE_DURATION_MS); // 349hz = F4 43 | } 44 | } 45 | if (CircuitPlayground.readCap(2, CAP_SAMPLES) >= CAP_THRESHOLD) { 46 | CircuitPlayground.strip.setPixelColor(1, CircuitPlayground.colorWheel(256/10)); 47 | if (playSound) { 48 | CircuitPlayground.playTone(294, TONE_DURATION_MS); // 294hz = D4 49 | } 50 | } 51 | if (CircuitPlayground.readCap(3, CAP_SAMPLES) >= CAP_THRESHOLD) { 52 | CircuitPlayground.strip.setPixelColor(0, CircuitPlayground.colorWheel(0)); 53 | if (playSound) { 54 | CircuitPlayground.playTone(262, TONE_DURATION_MS); // 262hz = C4 55 | } 56 | } 57 | if (CircuitPlayground.readCap(6, CAP_SAMPLES) >= CAP_THRESHOLD) { 58 | CircuitPlayground.strip.setPixelColor(6, CircuitPlayground.colorWheel(256/10*6)); 59 | if (playSound) { 60 | CircuitPlayground.playTone(440, TONE_DURATION_MS); // 440hz = A4 61 | } 62 | } 63 | if (CircuitPlayground.readCap(9, CAP_SAMPLES) >= CAP_THRESHOLD) { 64 | CircuitPlayground.strip.setPixelColor(8, CircuitPlayground.colorWheel(256/10*8)); 65 | if (playSound) { 66 | CircuitPlayground.playTone(494, TONE_DURATION_MS); // 494hz = B4 67 | } 68 | } 69 | if (CircuitPlayground.readCap(10, CAP_SAMPLES) >= CAP_THRESHOLD) { 70 | CircuitPlayground.strip.setPixelColor(9, CircuitPlayground.colorWheel(256/10*9)); 71 | if (playSound) { 72 | CircuitPlayground.playTone(523, TONE_DURATION_MS); // 523hz = C5 73 | } 74 | } 75 | if (CircuitPlayground.readCap(12, CAP_SAMPLES) >= CAP_THRESHOLD) { 76 | CircuitPlayground.strip.setPixelColor(5, CircuitPlayground.colorWheel(256/10*5)); 77 | if (playSound) { 78 | CircuitPlayground.playTone(392, TONE_DURATION_MS); // 392hz = G4 79 | } 80 | } 81 | 82 | // Light up the pixels. 83 | CircuitPlayground.strip.show(); 84 | } 85 | 86 | virtual void modePress() { 87 | // Turn sound on/off. 88 | playSound = !playSound; 89 | } 90 | 91 | private: 92 | bool playSound; 93 | }; 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/mega_demo/Demo.h: -------------------------------------------------------------------------------- 1 | #ifndef DEMO_H 2 | #define DEMO_H 3 | 4 | // Define each mode with the following interface for a loop and modePress 5 | // function that will be called during the main loop and if the mode button 6 | // was pressed respectively. It's up to each mode implementation to fill 7 | // these in and add their logic. 8 | class Demo { 9 | public: 10 | virtual ~Demo() {} 11 | 12 | virtual void loop() = 0; 13 | virtual void modePress() = 0; 14 | }; 15 | 16 | // Linear interpolation function is handy for all the modes to use. 17 | float lerp(float x, float xmin, float xmax, float ymin, float ymax) { 18 | if (x >= xmax) { 19 | return ymax; 20 | } 21 | if (x <= xmin) { 22 | return ymin; 23 | } 24 | return ymin + (ymax-ymin)*((x-xmin)/(xmax-xmin)); 25 | } 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/mega_demo/RainbowCycleDemo.h: -------------------------------------------------------------------------------- 1 | #ifndef RAINBOWCYCLEDEMO_H 2 | #define RAINBOWCYCLEDEMO_H 3 | 4 | #include "Demo.h" 5 | 6 | // Animation speeds to loop through with mode presses. The current milliseconds 7 | // are divided by this value so the smaller the value the faster the animation. 8 | static int speeds[] = { 5, 10, 50, 100 }; 9 | 10 | class RainbowCycleDemo: public Demo { 11 | public: 12 | RainbowCycleDemo() { currentSpeed = 0; } 13 | ~RainbowCycleDemo() {} 14 | 15 | virtual void loop() { 16 | // Make an offset based on the current millisecond count scaled by the current speed. 17 | uint32_t offset = millis() / speeds[currentSpeed]; 18 | // Loop through each pixel and set it to an incremental color wheel value. 19 | for(int i=0; i<10; ++i) { 20 | CircuitPlayground.strip.setPixelColor(i, CircuitPlayground.colorWheel(((i * 256 / 10) + offset) & 255)); 21 | } 22 | // Show all the pixels. 23 | CircuitPlayground.strip.show(); 24 | } 25 | 26 | virtual void modePress() { 27 | // Increment through the available speeds. 28 | currentSpeed += 1; 29 | if (currentSpeed >= sizeof(speeds)/sizeof(int)) { 30 | currentSpeed = 0; 31 | } 32 | } 33 | 34 | private: 35 | int currentSpeed; 36 | 37 | }; 38 | 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/mega_demo/SensorDemo.h: -------------------------------------------------------------------------------- 1 | #ifndef SENSORDEMO_H 2 | #define SENSORDEMO_H 3 | 4 | #include "Demo.h" 5 | 6 | // Define small, medium, large range of light sensor values. 7 | static int minLight[] = { 0, 0, 0}; 8 | static int maxLight[] = { 50, 255, 1023}; 9 | 10 | // Define small, medium, large range of temp sensor values (in Fahrenheit). 11 | static float minTempF[] = { 80.0, 70.0, -32.0}; 12 | static float maxTempF[] = { 85.0, 90.0, 212.0}; 13 | 14 | // Define color for light sensor pixels. 15 | #define LIGHT_RED 0xFF 16 | #define LIGHT_GREEN 0x00 17 | #define LIGHT_BLUE 0x00 18 | 19 | // Define color for temp sensor pixels. 20 | #define TEMP_RED 0x00 21 | #define TEMP_GREEN 0x00 22 | #define TEMP_BLUE 0xFF 23 | 24 | class SensorDemo: public Demo { 25 | public: 26 | SensorDemo() { mode = 0; } 27 | ~SensorDemo() {} 28 | 29 | virtual void loop() { 30 | // Reset all lights to off. 31 | for (int i=0; i<10; ++i) { 32 | CircuitPlayground.strip.setPixelColor(i, 0); 33 | } 34 | 35 | // Measure the light level and use it to light up its LEDs (right half). 36 | uint16_t light = CircuitPlayground.lightSensor(); 37 | int level = (int)lerp(light, minLight[mode], maxLight[mode], 0.0, 5.0); 38 | for (int i=9; i>9-level; --i) { 39 | CircuitPlayground.strip.setPixelColor(i, LIGHT_RED, LIGHT_GREEN, LIGHT_BLUE); 40 | } 41 | 42 | // Measure the temperatue and use it to light up its LEDs (left half). 43 | float tempF = CircuitPlayground.temperatureF(); 44 | level = (int)lerp(tempF, minTempF[mode], maxTempF[mode], 0.0, 5.0); 45 | for (int i=0; i 2) { 57 | mode = 0; 58 | } 59 | } 60 | 61 | private: 62 | int mode; 63 | }; 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/mega_demo/TiltDemo.h: -------------------------------------------------------------------------------- 1 | #ifndef TILTDEMO_H 2 | #define TILTDEMO_H 3 | 4 | #include "Demo.h" 5 | 6 | // Define range of possible acceleration values. 7 | #define MIN_ACCEL -10.0 8 | #define MAX_ACCEL 10.0 9 | 10 | // Define range of colors (min color and max color) using their red, green, blue components. 11 | // First the min color: 12 | #define MIN_COLOR_RED 0xFF 13 | #define MIN_COLOR_GREEN 0x00 14 | #define MIN_COLOR_BLUE 0x00 15 | 16 | // Then the max color: 17 | #define MAX_COLOR_RED 0x00 18 | #define MAX_COLOR_GREEN 0x00 19 | #define MAX_COLOR_BLUE 0xFF 20 | 21 | 22 | class TiltDemo: public Demo { 23 | public: 24 | TiltDemo() { mode = 0; } 25 | ~TiltDemo() {} 26 | 27 | virtual void loop() { 28 | // Grab the acceleration for the current mode's axis. 29 | float accel = 0; 30 | switch (mode) { 31 | case 0: 32 | accel = CircuitPlayground.motionX(); 33 | break; 34 | case 1: 35 | accel = CircuitPlayground.motionY(); 36 | break; 37 | case 2: 38 | accel = CircuitPlayground.motionZ(); 39 | break; 40 | } 41 | 42 | // Now interpolate the acceleration into a color for the pixels. 43 | uint8_t red = (uint8_t)lerp(accel, MIN_ACCEL, MAX_ACCEL, MIN_COLOR_RED, MAX_COLOR_RED); 44 | uint8_t green = (uint8_t)lerp(accel, MIN_ACCEL, MAX_ACCEL, MIN_COLOR_GREEN, MAX_COLOR_GREEN); 45 | uint8_t blue = (uint8_t)lerp(accel, MIN_ACCEL, MAX_ACCEL, MIN_COLOR_BLUE, MAX_COLOR_BLUE); 46 | 47 | // Gamma correction makes LED brightness appear more linear 48 | red = CircuitPlayground.gamma8(red); 49 | green = CircuitPlayground.gamma8(green); 50 | blue = CircuitPlayground.gamma8(blue); 51 | 52 | // Light up all the pixels the interpolated color. 53 | for (int i=0; i<10; ++i) { 54 | CircuitPlayground.strip.setPixelColor(i, red, green, blue); 55 | } 56 | CircuitPlayground.strip.show(); 57 | } 58 | 59 | virtual void modePress() { 60 | // Change the mode (axis being displayed) to a value inside 0-2 for X, Y, Z. 61 | mode += 1; 62 | if (mode > 2) { 63 | mode = 0; 64 | } 65 | } 66 | 67 | private: 68 | int mode; 69 | }; 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/examples/mega_demo/VUMeterDemo.h: -------------------------------------------------------------------------------- 1 | // This demo is based on the vumeter demo in the Adafruit Circuit Playground library. 2 | #ifndef VUMETERDEMO_H 3 | #define VUMETERDEMO_H 4 | 5 | #include 6 | #include "Demo.h" 7 | 8 | #define SAMPLE_WINDOW 10 // Sample window for average level 9 | #define PEAK_HANG 24 // Time of pause before peak dot falls 10 | #define PEAK_FALL 4 // Rate of falling peak dot 11 | #define INPUT_FLOOR 56 // Lower range of mic sensitivity in dB SPL 12 | #define INPUT_CEILING 110 // Upper range of mic sensitivity in db SPL 13 | 14 | static byte peak = 16; // Peak level of column; used for falling dots 15 | static unsigned int sample; 16 | static byte dotCount = 0; //Frame counter for peak dot 17 | static byte dotHangCount = 0; //Frame counter for holding peak dot 18 | 19 | static float mapf(float x, float in_min, float in_max, float out_min, float out_max); 20 | static void drawLine(uint8_t from, uint8_t to, uint32_t c); 21 | 22 | class VUMeterDemo: public Demo { 23 | public: 24 | VUMeterDemo() { currentCeiling = 0; } 25 | ~VUMeterDemo() {} 26 | 27 | virtual void loop() { 28 | int numPixels = CircuitPlayground.strip.numPixels(); 29 | float peakToPeak = 0; // peak-to-peak level 30 | unsigned int c, y; 31 | 32 | //get peak sound pressure level over the sample window 33 | peakToPeak = CircuitPlayground.mic.soundPressureLevel(SAMPLE_WINDOW); 34 | 35 | //limit to the floor value 36 | peakToPeak = max(INPUT_FLOOR, peakToPeak); 37 | 38 | // Serial.println(peakToPeak); 39 | 40 | //Fill the strip with rainbow gradient 41 | for (int i=0;i<=numPixels-1;i++){ 42 | CircuitPlayground.strip.setPixelColor(i, CircuitPlayground.colorWheel(map(i,0,numPixels-1,30,150))); 43 | } 44 | 45 | c = mapf(peakToPeak, INPUT_FLOOR, INPUT_CEILING, numPixels, 0); 46 | 47 | // Turn off pixels that are below volume threshold. 48 | if(c < peak) { 49 | peak = c; // Keep dot on top 50 | dotHangCount = 0; // make the dot hang before falling 51 | } 52 | if (c <= numPixels) { // Fill partial column with off pixels 53 | drawLine(numPixels, numPixels-c, CircuitPlayground.strip.Color(0, 0, 0)); 54 | } 55 | 56 | // Set the peak dot to match the rainbow gradient 57 | y = numPixels - peak; 58 | CircuitPlayground.strip.setPixelColor(y-1,CircuitPlayground.colorWheel(map(y,0,numPixels-1,30,150))); 59 | CircuitPlayground.strip.show(); 60 | 61 | // Frame based peak dot animation 62 | if(dotHangCount > PEAK_HANG) { //Peak pause length 63 | if(++dotCount >= PEAK_FALL) { //Fall rate 64 | peak++; 65 | dotCount = 0; 66 | } 67 | } 68 | else { 69 | dotHangCount++; 70 | } 71 | } 72 | 73 | virtual void modePress() { 74 | } 75 | 76 | private: 77 | int currentCeiling; 78 | }; 79 | 80 | 81 | 82 | static float mapf(float x, float in_min, float in_max, float out_min, float out_max) 83 | { 84 | return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; 85 | } 86 | 87 | //Used to draw a line between two points of a given color 88 | static void drawLine(uint8_t from, uint8_t to, uint32_t c) { 89 | uint8_t fromTemp; 90 | if (from > to) { 91 | fromTemp = from; 92 | from = to; 93 | to = fromTemp; 94 | } 95 | for(int i=from; i<=to; i++){ 96 | CircuitPlayground.strip.setPixelColor(i, c); 97 | } 98 | } 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/library.properties: -------------------------------------------------------------------------------- 1 | name=Adafruit Circuit Playground 2 | version=1.8.6 3 | author=Adafruit 4 | maintainer=Adafruit 5 | sentence=All in one library to control Adafruit's Circuit Playground board. 6 | paragraph=All in one library to control Adafruit's Circuit Playground board. Requires no other dependencies and exposes all Circuit Playground components in a simple to use class. 7 | category=Other 8 | url=https://github.com/adafruit/Adafruit_CircuitPlayground 9 | architectures=* 10 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/utility/Adafruit_CPlay_Mic.h: -------------------------------------------------------------------------------- 1 | // Adafruit Circuit Playground microphone library 2 | // by Phil Burgess / Paint Your Dragon. 3 | // Fast Fourier transform section is derived from 4 | // ELM-ChaN FFT library (see comments in ffft.S). 5 | 6 | #ifndef ADAFRUIT_CPLAY_MIC_H 7 | #define ADAFRUIT_CPLAY_MIC_H 8 | 9 | #ifdef __GNUC__ 10 | #define DEPRECATED(func) func __attribute__ ((deprecated)) 11 | #elif defined(_MSC_VER) 12 | #define DEPRECATED(func) __declspec(deprecated) func 13 | #else 14 | #pragma message("WARNING: You need to implement DEPRECATED for this compiler") 15 | #define DEPRECATED(func) func 16 | #endif 17 | 18 | #include "Adafruit_ZeroPDM.h" 19 | 20 | 21 | /**************************************************************************/ 22 | /*! 23 | @brief Class that stores state and functions for the microphone on CircuitPlayground boards 24 | */ 25 | /**************************************************************************/ 26 | class Adafruit_CPlay_Mic { 27 | public: 28 | Adafruit_CPlay_Mic(void) {}; // Empty constructor 29 | int peak(uint16_t ms) __attribute__ ((deprecated)); 30 | void capture(int16_t *buf, uint16_t nSamples), 31 | fft(uint16_t *spectrum); 32 | 33 | float soundPressureLevel(uint16_t ms); 34 | 35 | private: 36 | #if defined(ARDUINO_ARCH_SAMD) 37 | static Adafruit_ZeroPDM pdm; 38 | #endif 39 | }; 40 | 41 | #endif // ADAFRUIT_CPLAY_MIC_H 42 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/utility/Adafruit_CPlay_Sensor.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jed-Z/introduction-to-robotics/b66fc491361870f79edcb7a88715f2bb0e286534/libraries/Adafruit_Circuit_Playground/utility/Adafruit_CPlay_Sensor.h -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/utility/Adafruit_CPlay_Speaker.h: -------------------------------------------------------------------------------- 1 | // Adafruit Circuit Playground speaker library 2 | // by Phil Burgess / Paint Your Dragon. 3 | 4 | #ifndef ADAFRUIT_CPLAY_SPEAKER_H 5 | #define ADAFRUIT_CPLAY_SPEAKER_H 6 | 7 | #include 8 | 9 | #if !defined(__AVR__) // circuit playground express has nicer amp w/shutdown 10 | #define CPLAY_SPEAKER_SHUTDOWN 11 ///< shutdown pin (Express boards only) 11 | #endif 12 | 13 | /**************************************************************************/ 14 | /*! 15 | @brief Class that stores state and functions for the speaker on CircuitPlayground boards 16 | */ 17 | /**************************************************************************/ 18 | class Adafruit_CPlay_Speaker { 19 | public: 20 | Adafruit_CPlay_Speaker(void) { started = false; }; 21 | void begin(void), 22 | end(void), 23 | set(uint8_t value), 24 | playSound(const uint8_t *data, uint32_t length, uint16_t sampleRate, 25 | bool tenBit=false), 26 | say(const uint8_t *addr); 27 | 28 | void enable(bool e); 29 | 30 | /**************************************************************************/ 31 | /*! 32 | @brief disable the speaker. 33 | @note this function only has an effect on 'Express' boards 34 | */ 35 | /**************************************************************************/ 36 | void off(void) { enable(false); }; 37 | 38 | /**************************************************************************/ 39 | /*! 40 | @brief enable the speaker. 41 | @note this function only has an effect on 'Express' boards 42 | */ 43 | /**************************************************************************/ 44 | void on(void) { enable(true); }; 45 | 46 | private: 47 | bool started; 48 | }; 49 | 50 | #endif // ADAFRUIT_CPLAY_SPEAKER_H 51 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/utility/IRLibCPE.h: -------------------------------------------------------------------------------- 1 | /* IRLibCPE.h 2 | * Part of IRLib Library for Arduino receiving, decoding, and sending 3 | * infrared signals. See COPYRIGHT.txt and LICENSE.txt for more information. 4 | */ 5 | /* 6 | * Combines all of the necessary libraries for implementing IR transmit and receive 7 | * on the Adafruit Circuit Playground Express. Similar to the IRLibAll.h in the 8 | * regular IRLib2.xx. 9 | */ 10 | 11 | #ifndef IRLIB_CPE_H 12 | #define IRLIB_CPE_H 13 | #include "IRLibDecodeBase.h" 14 | #include "IRLibSendBase.h" 15 | #include "IRLib_P01_NEC.h" 16 | #include "IRLib_P02_Sony.h" 17 | #include "IRLib_P03_RC5.h" 18 | #include "IRLib_P04_RC6.h" 19 | #include "IRLib_P05_Panasonic_Old.h" 20 | #include "IRLib_P06_JVC.h" 21 | #include "IRLib_P07_NECx.h" 22 | #include "IRLib_P08_Samsung36.h" 23 | #include "IRLib_P09_GICable.h" 24 | #include "IRLib_P10_DirecTV.h" 25 | #include "IRLib_P11_RCMM.h" 26 | #include "IRLib_P12_CYKM.h" 27 | //include additional protocols here 28 | #include "IRLibCombo.h" 29 | #include "IRLibRecvPCI.h" 30 | #endif //IRLIB_CPE_H 31 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/utility/IRLibHardware.cpp: -------------------------------------------------------------------------------- 1 | /* IRLibHardware.cpp 2 | * Part of IRLib Library for Arduino receiving, decoding, and sending 3 | * infrared signals. See COPYRIGHT.txt and LICENSE.txt for more information. 4 | * 5 | * We need a way for the sending object to communicate with the receiving object. 6 | * Sending an IR signal can disable further receiving because the timer needed for the 50us 7 | * interrupts is used to modulate the frequency of the PWM output signal. We need a flag 8 | * for the send object to inform you receive object that this occurred. 9 | * 10 | * Some applications do sending only and would only require you to include IRLibSendBase.h 11 | * while others only do receiving/decoding and would include IRLibRecvBase.h but not 12 | * IRLibSendBase.h. The only include file that is used by both sending and receiving is 13 | * the IRLibHardware.h which was formerly called IRLibTimer.h. Therefore we put the flag 14 | * in this newly created IRLibHardware.cpp module. That way a send only can put the flag 15 | * here whether or not there is a receiver. Similarly the receiver can check the flag 16 | * whether or not there is a sender. 17 | * 18 | * The below is a global flag IRLib_didIROut that gets set true with every call to enableIROut. 19 | * Then any call to IRrecv::enableIRIn checks this to see if it needs to restart the ISR. 20 | * Regardless IRrecv::enableIRIn will always reset it it false for the next time. 21 | * Note as always if you try to send while in the middle of receiving, the partially received 22 | * data is lost. If the application wishes to create a system where the sending waits until 23 | * the receiver is idle, the programmer can implement such a system themselves and deal with 24 | * the consequences. 25 | * 26 | * The bottom line is the application no longer needs to figure out if it needs to 27 | * call enableIRIn or the "resume" method. There is no more "resume". You always do 28 | * enableIRIn after every decode and the system handles it. 29 | */ 30 | #include "IRLibHardware.h" 31 | uint8_t IRLib_didIROut=false; 32 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/utility/IRLibProtocols.cpp: -------------------------------------------------------------------------------- 1 | /* IRLibProtocols.cpp 2 | * Part of IRLib Library for Arduino receiving, decoding, and sending 3 | * infrared signals. See COPYRIGHT.txt and LICENSE.txt for more information. 4 | */ 5 | /* 6 | * This module enumerates the various supported protocols and defines a program memory 7 | * string used by the dump routines or your sketches to display the name of a protocol. 8 | * It is used by both Send and Decode sections of the code but not Receive. 9 | */ 10 | #include "IRLibProtocols.h" 11 | 12 | /* 13 | * Returns a pointer to a flash stored string that is the name of the protocol received. 14 | */ 15 | const __FlashStringHelper *Pnames(uint8_t type) { 16 | if(type>89) return F("Unsup"); 17 | if(type>LAST_PROTOCOL) type=UNKNOWN; 18 | // You can add additional strings before the entry for hash code. 19 | const __FlashStringHelper *Names[LAST_PROTOCOL+1]={ 20 | F("Unknown"),F("NEC"),F("Sony"),F("RC5"),F("RC6"),F("Panasonic Old"),F("JVC"), 21 | F("NECx"),F("Samsung36"),F("G.I.Cable"),F("DirecTV"),F("rcmm"),F("CYKM") 22 | //,F("Additional_13")//expand or edit these 23 | }; 24 | return Names[type]; 25 | }; 26 | 27 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/utility/IRLibProtocols.h: -------------------------------------------------------------------------------- 1 | /* IRLibProtocols.h 2 | * Part of IRLib Library for Arduino receiving, decoding, and sending 3 | * infrared signals. See COPYRIGHT.txt and LICENSE.txt for more information. 4 | */ 5 | /* 6 | * This module enumerates the various supported protocols and defines a program memory 7 | * string used by the dump routines or your sketches to display the name of a protocol. 8 | * It is used by both Send and Decode sections of the code but not Receive. 9 | */ 10 | #ifndef IRLIBPROTOCOLS_H 11 | #define IRLIBPROTOCOLS_H 12 | #include 13 | 14 | #define UNKNOWN 0 15 | #define NEC 1 16 | #define SONY 2 17 | #define RC5 3 18 | #define RC6 4 19 | #define PANASONIC_OLD 5 20 | #define JVC 6 21 | #define NECX 7 22 | #define SAMSUNG36 8 23 | #define GICABLE 9 24 | #define DIRECTV 10 25 | #define RCMM 11 26 | #define CYKM 12 27 | //#define ADDITIONAL_13 13 //add additional protocols here 28 | //#define ADDITIONAL_14 14 29 | #define LAST_PROTOCOL 12 //Be sure to update this when adding protocols 30 | 31 | /* 32 | * Returns a pointer to a flash stored string that is the name of the protocol received. 33 | */ 34 | const __FlashStringHelper *Pnames(uint8_t Type); 35 | 36 | /* 37 | * Miscellaneous values used by both Send and Decode modules 38 | */ 39 | #define TOPBIT 0x80000000 40 | 41 | // Decoded value for NEC and others when a repeat code is received or to be sent 42 | #define REPEAT_CODE 0xffffffff 43 | 44 | #endif //IRLIBPROTOCOLS_H 45 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/utility/IRLibRecvBase.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jed-Z/introduction-to-robotics/b66fc491361870f79edcb7a88715f2bb0e286534/libraries/Adafruit_Circuit_Playground/utility/IRLibRecvBase.h -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/utility/IRLibRecvPCI.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jed-Z/introduction-to-robotics/b66fc491361870f79edcb7a88715f2bb0e286534/libraries/Adafruit_Circuit_Playground/utility/IRLibRecvPCI.cpp -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/utility/IRLibRecvPCI.h: -------------------------------------------------------------------------------- 1 | /* IRLibRecvPCI.h 2 | * Part of IRLib Library for Arduino receiving, decoding, and sending 3 | * infrared signals. See COPYRIGHT.txt and LICENSE.txt for more information. 4 | * 5 | * You should include this header in your sketch if you're using the IRLibRecvPCI 6 | * receiver class which uses pin change interrupts to poll the input pin. 7 | * This version gives more accurate results than the 50us timer based IRrecv but it has 8 | * other limitations. It uses the Arduino "attachInterrupt()" function which can conflict 9 | * with other libraries. Also unless you use an external buffer and enable auto resume 10 | * this receiver occasionally fails to receive the second of 2 quickly sent frames. 11 | * If you do not have sufficient RAM for a second buffer you should consider using the 12 | * other two available receiver classes. 13 | * Applications that do sending only SHOULD NOT include this header. 14 | * 15 | * This receiver is based in part on Arduino firmware for use with AnalysIR IR signal analysis 16 | * software for Windows PCs. Many thanks to the people at http://analysir.com for their 17 | * assistance in developing this section of code. 18 | */ 19 | 20 | #ifndef IRLibRecvPCI_h 21 | #define IRLibRecvPCI_h 22 | #include "IRLibRecvBase.h" 23 | 24 | class IRrecvPCI: public IRrecvBase { 25 | public: 26 | IRrecvPCI(void){}; //Use only when receiver object is part of larger object. 27 | // Still must initialize using constructor below. 28 | IRrecvPCI(uint8_t pin); 29 | void enableIRIn(void); //call to initialize or resume receiving 30 | bool getResults(void); //returns true if new frame of data has been received 31 | void disableIRIn(void); //ISR runs continuously once started. Use this if you want to stop. 32 | private: 33 | uint8_t intrNum; 34 | }; 35 | #endif //IRLibRecvPCI_h 36 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/utility/IRLibSAMD21.cpp: -------------------------------------------------------------------------------- 1 | /* IRLibSAMD21.h 2 | * Part of IRLib Library for Arduino receiving, decoding, and sending 3 | * infrared signals. See COPYRIGHT.txt and LICENSE.txt for more information. 4 | * 5 | * This type of content is normally stored in IRLibHardware.h but we have 6 | * moved at her because the SAMD21 support is significantly different than the 7 | * AVR 8-bit hardware support. Separating it out into a separate file 8 | * will make it easier to include comments and to maintain the code. 9 | */ 10 | 11 | /* See IRLibSAMD21.h for details about this implementation. 12 | */ 13 | #if defined (__SAMD21G18A__) 14 | #include "IRLibHardware.h" 15 | 16 | //Save some typing 17 | #define IR_APD g_APinDescription[IR_SEND_PWM_PIN] 18 | 19 | void initializeSAMD21PWM(uint16_t khz) { 20 | // Enable the port multiplexer for the PWM channel on pin 21 | PORT->Group[IR_APD.ulPort].PINCFG[IR_APD.ulPin].bit.PMUXEN = 1; 22 | // Connect the TCC timer to the port outputs - port pins are paired odd PMUXO and even PMUXE 23 | // F & E peripherals specify the timers: TCC0, TCC1 and TCC2 24 | PORT->Group[IR_APD.ulPort].PMUX[IR_APD.ulPin >> 1].reg |= IR_MUX_EF; 25 | 26 | // Feed GCLK0 to TCC0 and TCC1 27 | REG_GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN | // Enable GCLK0 to TCC0 and TCC1 28 | GCLK_CLKCTRL_GEN_GCLK0 | // Select GCLK0 29 | GCLK_CLKCTRL_ID_TCC0_TCC1; // Feed GCLK0 to TCC0 and TCC1 30 | syncGCLK; // Wait for synchronization 31 | 32 | // Normal (single slope) PWM operation: timers countinuously count up to PER 33 | // register value and then is reset to 0 34 | IR_TCCx->WAVE.reg |= TCC_WAVE_WAVEGEN_NPWM; // Setup single slope PWM on TCCx 35 | while (IR_TCCx->SYNCBUSY.bit.WAVE); // Wait for synchronization 36 | 37 | // Each timer counts up to a maximum or TOP value set by the PER register, 38 | // this determines the frequency of the PWM operation. 39 | uint32_t cc = F_CPU/(khz*1000) - 1; 40 | IR_TCCx->PER.reg = cc; // Set the frequency of the PWM on IR_TCCx 41 | while(IR_TCCx->SYNCBUSY.bit.PER); 42 | 43 | // The CCx register value corresponds to the pulsewidth in microseconds (us) 44 | IR_TCCx->CC[(IR_CCn & 0x03)].reg = cc/3; // Set the duty cycle of the PWM on TCC0 to 33% 45 | while(IR_TCCx->SYNCBUSY.bit.IR_CCx); 46 | 47 | // Enable IR_TCCx timer but do not turn on PWM yet. Will turn it on later. 48 | IR_TCCx->CTRLA.reg |= TCC_CTRLA_PRESCALER_DIV1; // Divide GCLK0 by 1 49 | while (IR_TCCx->SYNCBUSY.bit.ENABLE); 50 | IR_TCCx->CTRLA.reg &= ~TCC_CTRLA_ENABLE; //initially off will turn on later 51 | while (IR_TCCx->SYNCBUSY.bit.ENABLE); 52 | } 53 | /* 54 | * Setup the 50 microsecond timer hardware interrupt for the IRrecv class. 55 | */ 56 | void initializeSAMD21timerInterrupt(void) { 57 | GCLK->CLKCTRL.reg = (uint16_t)(GCLK_CLKCTRL_CLKEN | 58 | GCLK_CLKCTRL_GEN_GCLK0 | 59 | GCLK_CLKCTRL_ID(IR_GCM)); 60 | syncGCLK; 61 | IR_TCx->COUNT16.CTRLA.reg &= ~TC_CTRLA_ENABLE; 62 | syncTC; 63 | IR_TCx->COUNT16.CTRLA.reg = TC_CTRLA_SWRST; 64 | while (IR_TCx->COUNT16.CTRLA.bit.SWRST); 65 | IR_TCx->COUNT16.CTRLA.reg |= TC_CTRLA_MODE_COUNT16; 66 | IR_TCx->COUNT16.CTRLA.reg |= TC_CTRLA_WAVEGEN_MFRQ; 67 | IR_TCx->COUNT16.CC[0].reg = F_CPU/(1000000/USEC_PER_TICK) - 1; 68 | syncTC; 69 | } 70 | #endif 71 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/utility/IRLibSendBase.h: -------------------------------------------------------------------------------- 1 | /* IRLibSendBase.h 2 | * Part of IRLib Library for Arduino receiving, decoding, and sending 3 | * infrared signals. See COPYRIGHT.txt and LICENSE.txt for more information. 4 | */ 5 | /* 6 | * This module contains the base classes for sending. You will not create instances 7 | * of these classes, rather you will use them as base classes in creating derived 8 | * protocol specific decoders. Each protocol specific send class begins 9 | * by calling enableIROut(uint8_t kHz) to set the carrier frequency. 10 | * It then calls mark(int usec) and space(inc usec) to transmit marks and 11 | * spaces of varying length of microseconds in the manner which the protocol defines. 12 | */ 13 | #ifndef IRLIBSENDBASE_H 14 | #define IRLIBSENDBASE_H 15 | 16 | #include "IRLibProtocols.h" 17 | 18 | class IRsendBase { 19 | public: 20 | IRsendBase(); 21 | void sendGeneric(uint32_t data, uint8_t numBits, uint16_t headMark, uint16_t headSpace, 22 | uint16_t markOne, uint16_t markZero, uint16_t spaceOne, uint16_t spaceZero, 23 | uint8_t kHz, bool stopBits, uint32_t maxExtent=0); 24 | protected: 25 | void enableIROut(uint8_t khz); 26 | void mark(uint16_t usec); 27 | void space(uint16_t usec); 28 | uint32_t extent; 29 | uint8_t onTime,offTime,iLength;//used by bit-bang output. 30 | }; 31 | 32 | #endif //IRLIBSENDBASE_H 33 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/utility/IRLib_COPYRIGHT.txt: -------------------------------------------------------------------------------- 1 | Copyright information for IRLib – an Arduino library for 2 | infrared encoding and decoding 3 | 4 | IRLib2 is a collection of libraries which we will collectively referred 5 | to as the PACKAGE. The PACKAGE consists of all files in the IRLib2, 6 | IRLibFreq, IRLibRecv, IRLibRecvPCI, and IRLibProtocols folders. 7 | 8 | The PACKAGE is Copyright (c) 2014-2017 by Chris Young 9 | 10 | This program is free software: you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation, either version 3 of the License, or 13 | (at your option) any later version. 14 | 15 | This program is distributed in the hope that it will be useful, 16 | but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | GNU General Public License for more details. 19 | 20 | These files will be maintained at https://github.com/cyborg5/IRLib2 21 | Documentation and other support info at http://tech.cyborg5.com/irlib 22 | 23 | This is an updated version of my original IRLib which is still available at 24 | https://github.com/cyborg5/IRLib which will not be updated after this 25 | PACKAGE has its first stable non-beta release. 26 | 27 | Both libraries are derived from the original source code in a library called 28 | IRemote by Ken Shirriff which was covered by GNU LESSER GENERAL PUBLIC 29 | LICENSE version 2.1. This package is covered by the GNU GENERAL PUBLIC 30 | LICENSE 3.0. See LICENSE.txt for a copy of that license or visit 31 | https://www.gnu.org/licenses/ 32 | 33 | As I understand these licenses it is permissible to upgrade the license 34 | this way. Additionally this license change was made with the approval of 35 | Mr. Shirriff in an email conversation I had with him. In accord with his 36 | wishes and out of respect for his work, his original copyright message is 37 | shown below. 38 | 39 | /* 40 | * IRremote 41 | * Version 0.1 July, 2009 42 | * Copyright 2009 Ken Shirriff 43 | * For details, see http://www.righto.com/2009/08/multi-protocol-infrared-remote-library.html http://www.righto.com/ 44 | * 45 | * Interrupt code based on NECIRrcv by Joe Knapp 46 | * http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556 47 | * Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/ 48 | */ 49 | 50 | We also acknowledge and thank the developers of the AnalysIR program. AnalysIR is a Windows-based application which allows you to graphically analyze IR input signals through an Arduino, Raspberry Pi or other microcontrollers systems. The frequency analysis and other PCI based versions of the program are based upon and inspired by their work. We value their input into the development of that portion of the code. You can find more about their software at http://analysir.com 51 | 52 | We also knowledge and thank programmer Gabriel Staples contributed bug fixes and an earlier version of the auto resume feature. Although much of his code was rewritten it could not have been possible without his contributions. 53 | 54 | Other major contributors will be acknowledged in this file in the future. -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/utility/IRLib_HashRaw.h: -------------------------------------------------------------------------------- 1 | /* IRLib_P00_HashRaw.h 2 | * Part of IRLib Library for Arduino receiving, decoding, and sending 3 | * infrared signals. See COPYRIGHT.txt and LICENSE.txt for more information. 4 | */ 5 | /* 6 | * If you have a protocol which is unsupported by this library, you can still receive 7 | * and transmit the data. You can store the raw data values in a buffer and retransmit the 8 | * data exactly as you received it. Of course it takes a lot of memory to store such data 9 | * so it is inefficient but it is better than nothing. 10 | * If all you need to do is detect a unique value for an unsupported protocol and you do 11 | * not need to resend the data, you can use the hash code decoder. It looks at the 12 | * array of raw timing values and create a 32 bit value based on the data. It is 13 | * highly likely to be unique however you cannot reverse engineer the process. 14 | * You cannot re-create the original data stream for 32 bit hash code. 15 | * This module also implements the raw send method. You have to have the original 16 | * timing values. 17 | */ 18 | 19 | #ifndef IRLIB_HASHRAW_H 20 | #define IRLIB_HASHRAW_H 21 | #define IR_SEND_RAW case 0: IRsendRaw::send((uint16_t*)data,data2,khz); break; 22 | #define IR_DECODE_HASH if(IRdecodeHash::decode()) return true; 23 | #ifdef IRLIB_HAVE_COMBO 24 | #define PV_IR_DECODE_HASH ,public virtual IRdecodeHash 25 | #define PV_IR_SEND_RAW ,public virtual IRsendRaw 26 | #else 27 | #define PV_IR_DECODE_HASH public virtual IRdecodeHash 28 | #define PV_IR_SEND_RAW public virtual IRsendRaw 29 | #endif 30 | 31 | #ifdef IRLIBSENDBASE_H 32 | /* The first parameter to the "IRendRaw" method is a pointer to the first element of an 33 | * array of uint16_t values. These values are the raw timing values in microseconds. Note 34 | * it is possible to simply pass "(uint16_t*) &My_Decoder.decodeBuffer[1]" if you have just 35 | * received a code and wish to echo it. You have to point to the index "1" because index "0" 36 | * of that buffer contains the gap between successive frames data and it should be ignored. 37 | * If the frequency to be used in transmission is not specified, it defaults to 38kHz. 38 | */ 39 | class IRsendRaw: public virtual IRsendBase { 40 | public: 41 | void send(uint16_t *buf, uint8_t len, uint8_t khz) { 42 | enableIROut(khz); 43 | for (uint8_t i = 0; i < len; i++) { 44 | if (i & 1) { 45 | space(buf[i]); 46 | } 47 | else { 48 | mark(buf[i]); 49 | } 50 | } 51 | space(0); // Just to be sure 52 | } 53 | }; 54 | #endif //IRLIBSENDBASE_H 55 | 56 | #ifdef IRLIBDECODEBASE_H 57 | /* This Hash decoder is based on IRhashcode Copyright 2010 Ken Shirriff 58 | * For details see http://www.righto.com/2010/01/using-arbitrary-remotes-with-arduino.html 59 | * Use FNV hash algorithm: http://isthe.com/chongo/tech/comp/fnv/#FNV-param 60 | * Converts the raw code values into a 32-bit hash code. 61 | * Hopefully this code is unique for each button. 62 | */ 63 | #define FNV_PRIME_32 16777619 64 | #define FNV_BASIS_32 2166136261 65 | // Compare two tick values, return 0 if v1 is lower, 1 if equal, and 2 if v2 is higher 66 | #define TICKS_COMPARE(v1,v2) ( (v2< v1*0.8)?0:( (v1< v2*0.8)?2:1) ) 67 | class IRdecodeHash: public virtual IRdecodeBase { 68 | public: 69 | bool decode(void) { 70 | value = FNV_BASIS_32; 71 | for (int i = 1; i+2 < recvGlobal.decodeLength; i++) { 72 | value = (value * FNV_PRIME_32) ^ TICKS_COMPARE(recvGlobal.decodeBuffer[i], recvGlobal.decodeBuffer[i+2]); 73 | } 74 | protocolNum = UNKNOWN; 75 | bits= (recvGlobal.decodeLength-3)/2;//Estimated number of bits of unknown protocol 76 | //Note that value is always 32 bit hash code. 77 | return true; 78 | } 79 | }; 80 | #endif //IRLIBDECODEBASE_H 81 | 82 | #define IRLIB_HAVE_COMBO 83 | 84 | #endif //IRLIB_HASHRAW_H 85 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/utility/IRLib_P01_NEC.h: -------------------------------------------------------------------------------- 1 | /* IRLib_P01_NEC.h 2 | * Part of IRLib Library for Arduino receiving, decoding, and sending 3 | * infrared signals. See COPYRIGHT.txt and LICENSE.txt for more information. 4 | */ 5 | /* 6 | * NEC is an extremely common protocol. There are two variations NEC1 and NEC2. 7 | * They differ only in the way in which they handle repeat codes. If you hold a button 8 | * using NEC1 it does not repeat the same sequence. Rather it sends a special sequence 9 | * consisting of the usual header mark, a half-size header space, a normal mark. 10 | * When IRLib receives one of these special repeat sequences, it returns the 11 | * value REPEAT_CODE which is defined in IRLibProtocols.h as the value 0xffffffff. If you 12 | * send REPEAT_CODE, the send routine will create a special sequence for you. 13 | * NOTE that the timing for this special did sequence is nearly identical to a ditto 14 | * used by the G.I.Cable protocol and IRLib generally not distinguish between the two. 15 | * The header timing for G.I. Cable ditto is 8820,1960 and for NEC is 9024,2256 16 | * If you are using both protocols and you receive an NEC ditto immediately after 17 | * receiving a G.I.Cable then you should presume it is a G.I.Cable and vice versa. 18 | * Whether it is a normal code or a repeat code the entire frame has a 108ms extent. 19 | * The IRP notation for these protocols are: 20 | * NEC1: {38k,564}<1,-1|1,-3>(16,-8,D:8,S:8,F:8,~F:8,1,^108,(16,-4,1,^108)*) 21 | * NEC2: {38k,564}<1,-1|1,-3>(16,-8,D:8,S:8,F:8,~F:8,1,^108)+ 22 | * Other protocols use the same timing and 32 bits of data but they interpret the data fields 23 | * differently. These include Apple and TiVo. Also Pioneer protocol is identical to NEC2 24 | * however uses 40k rather than 38k modulation. Pioneer sometimes requires a 2 frame 25 | * sequence of different data for a single pushbutton function. The optional 2nd 26 | * parameter to the "send" method allows you to change the frequency from the default 38. 27 | */ 28 | 29 | #ifndef IRLIB_PROTOCOL_01_H 30 | #define IRLIB_PROTOCOL_01_H 31 | #define IR_SEND_PROTOCOL_01 case 1: if(data2==0)data2=38;IRsendNEC::send(data,data2); break; 32 | #define IR_DECODE_PROTOCOL_01 if(IRdecodeNEC::decode()) return true; 33 | #ifdef IRLIB_HAVE_COMBO 34 | #define PV_IR_DECODE_PROTOCOL_01 ,public virtual IRdecodeNEC 35 | #define PV_IR_SEND_PROTOCOL_01 ,public virtual IRsendNEC 36 | #else 37 | #define PV_IR_DECODE_PROTOCOL_01 public virtual IRdecodeNEC 38 | #define PV_IR_SEND_PROTOCOL_01 public virtual IRsendNEC 39 | #endif 40 | #ifdef IRLIBSENDBASE_H 41 | 42 | class IRsendNEC: public virtual IRsendBase { 43 | public: 44 | void send(uint32_t data, uint8_t kHz=38) { 45 | if (data==REPEAT_CODE) { 46 | enableIROut(kHz); 47 | mark (564* 16); space(564*4); mark(564);space(572);delay(97);//actually 97572us 48 | } else { 49 | sendGeneric(data,32, 564*16, 564*8, 564, 564, 564*3, 564, kHz, true,108000); 50 | } 51 | }; 52 | }; 53 | #endif //IRLIBSENDBASE_H 54 | 55 | #ifdef IRLIBDECODEBASE_H 56 | class IRdecodeNEC: public virtual IRdecodeBase { 57 | public: 58 | bool decode(void) { 59 | resetDecoder();//This used to be in the receiver getResults. 60 | IRLIB_ATTEMPT_MESSAGE(F("NEC repeat")); 61 | // Check for repeat 62 | if (recvGlobal.decodeLength == 4 && MATCH(recvGlobal.decodeBuffer[1],564*16) && MATCH(recvGlobal.decodeBuffer[2],564*4) 63 | && MATCH(recvGlobal.decodeBuffer[3],564)) { 64 | bits = 0; 65 | value = REPEAT_CODE; 66 | protocolNum = NEC; 67 | return true; 68 | } 69 | IRLIB_ATTEMPT_MESSAGE(F("NEC")); 70 | if(!decodeGeneric(68, 564*16, 564*8, 564, 564*3, 564)) return false; 71 | protocolNum = NEC; 72 | return true; 73 | } 74 | }; 75 | 76 | #endif //IRLIBDECODEBASE_H 77 | 78 | #define IRLIB_HAVE_COMBO 79 | 80 | #endif //IRLIB_PROTOCOL_01_H 81 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/utility/IRLib_P02_Sony.h: -------------------------------------------------------------------------------- 1 | /* IRLib_P02_Sony.h 2 | * Part of IRLib Library for Arduino receiving, decoding, and sending 3 | * infrared signals. See COPYRIGHT.txt and LICENSE.txt for more information. 4 | */ 5 | /* 6 | * Sony is backwards from most protocols. It uses a variable length mark and a fixed length 7 | * space rather than a fixed mark and a variable space. Our generic send will still work 8 | * however we need a custom decoding routine because it's difficult to get the generic 9 | * decoder to handle a variable length mark without cluttering up the code to much. 10 | * According to the protocol you must send Sony commands at least three times so we 11 | * automatically do it here. Sony can be 8, 12, 15, or 20 bits in length. 12 | * The 8 bit version uses a shorter trailing space at the end. The signal is modulated 13 | * at 40 kHz however most 38 kHz receivers are broad enough to receive it. 14 | */ 15 | 16 | #ifndef IRLIB_PROTOCOL_02_H 17 | #define IRLIB_PROTOCOL_02_H 18 | #define IR_SEND_PROTOCOL_02 case 2: IRsendSony::send(data,data2); break; 19 | #define IR_DECODE_PROTOCOL_02 if(IRdecodeSony::decode()) return true; 20 | #ifdef IRLIB_HAVE_COMBO 21 | #define PV_IR_DECODE_PROTOCOL_02 ,public virtual IRdecodeSony 22 | #define PV_IR_SEND_PROTOCOL_02 ,public virtual IRsendSony 23 | #else 24 | #define PV_IR_DECODE_PROTOCOL_02 public virtual IRdecodeSony 25 | #define PV_IR_SEND_PROTOCOL_02 public virtual IRsendSony 26 | #endif 27 | 28 | #ifdef IRLIBSENDBASE_H 29 | class IRsendSony: public virtual IRsendBase { 30 | public: 31 | void send(uint32_t data, uint8_t nbits) { 32 | for(uint8_t i=0; i<3;i++){ 33 | sendGeneric(data,nbits, 600*4, 600, 600*2, 600, 600, 600, 40, false,45000); 34 | } 35 | } 36 | }; 37 | #endif //IRLIBSENDBASE_H 38 | 39 | #ifdef IRLIBDECODEBASE_H 40 | class IRdecodeSony: public virtual IRdecodeBase { 41 | public: 42 | virtual bool decode(void) { 43 | IRLIB_ATTEMPT_MESSAGE(F("Sony")); 44 | resetDecoder();//This used to be in the receiver getResults. 45 | if(recvGlobal.decodeLength!=2*8+2 && recvGlobal.decodeLength!=2*12+2 && recvGlobal.decodeLength!=2*15+2 46 | && recvGlobal.decodeLength!=2*20+2) return RAW_COUNT_ERROR; 47 | if(!ignoreHeader) { 48 | if (!MATCH(recvGlobal.decodeBuffer[1],600*4)) return HEADER_MARK_ERROR(600*4); 49 | } 50 | offset=2;//skip initial gap plus header Mark. 51 | while (offset < recvGlobal.decodeLength) { 52 | if (!MATCH(recvGlobal.decodeBuffer[offset],600)) return DATA_SPACE_ERROR(600); 53 | offset++; 54 | if (MATCH(recvGlobal.decodeBuffer[offset],600*2)) { 55 | value = (value << 1) | 1; 56 | } 57 | else if (MATCH(recvGlobal.decodeBuffer[offset],600)) { 58 | value <<= 1; 59 | } 60 | else return DATA_MARK_ERROR(600); 61 | offset++; 62 | } 63 | bits = (offset - 1) / 2; 64 | protocolNum = SONY; 65 | return true; 66 | } 67 | }; 68 | #endif //IRLIBDECODEBASE_H 69 | 70 | #define IRLIB_HAVE_COMBO 71 | 72 | #endif //IRLIB_PROTOCOL_02_H 73 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/utility/IRLib_P03_RC5.h: -------------------------------------------------------------------------------- 1 | /* IRLib_P03_RC5.h 2 | * Part of IRLib Library for Arduino receiving, decoding, and sending 3 | * infrared signals. See COPYRIGHT.txt and LICENSE.txt for more information. 4 | */ 5 | /* 6 | * The RC5 protocol was invented by Phillips but is used by wide variety of manufacturers. 7 | * It uses a phase encoding of data bits. A space/mark pair indicates "1" 8 | * and a mark/space indicates a "0". It begins with a single "1" bit which is not encoded 9 | * in the data. The second highest order data bit is a toggle bit that indicates individual 10 | * keypresses. You must toggle this bit yourself when sending data. The protocol uses 36 kHz 11 | * modulation however 38 kHz receivers can typically receive the codes okay. 12 | * There are three supported varieties as follows: 13 | * RC5 13 bits, 36 kHz (default, most common variety. 14 | * RC5-F7 14 bits, 36 kHz 15 | * RC5-F7-57 14 bits, 57 kHz 16 | * There's also a 19 bit variety called RC5x that is not supported here but may be a separate 17 | * module eventually. 18 | */ 19 | 20 | #ifndef IRLIB_PROTOCOL_03_H 21 | #define IRLIB_PROTOCOL_03_H 22 | #define IR_SEND_PROTOCOL_03 case 03: if(khz==38)khz=36; IRsendRC5::send(data,data2,khz); break; 23 | #define IR_DECODE_PROTOCOL_03 if(IRdecodeRC5::decode()) return true; 24 | #ifdef IRLIB_HAVE_COMBO 25 | #define PV_IR_DECODE_PROTOCOL_03 ,public virtual IRdecodeRC5 26 | #define PV_IR_SEND_PROTOCOL_03 ,public virtual IRsendRC5 27 | #else 28 | #define PV_IR_DECODE_PROTOCOL_03 public virtual IRdecodeRC5 29 | #define PV_IR_SEND_PROTOCOL_03 public virtual IRsendRC5 30 | #endif 31 | #define RC5_T1 889 32 | 33 | #ifdef IRLIBSENDBASE_H 34 | 35 | class IRsendRC5: public virtual IRsendBase { 36 | public: 37 | void send(uint32_t data, uint8_t nBits=13, uint8_t kHz=36) { 38 | if(nBits==0)nBits=13; 39 | if(kHz==0)kHz=36; 40 | enableIROut(kHz); 41 | data = data << (32 - nBits); 42 | extent=0; 43 | mark(RC5_T1); // First start bit 44 | //Note: Original IRremote library incorrectly assumed second bit was 45 | //always a "1". Bit patterns from this decoder are not backward compatible 46 | //with patterns produced by the original library. Uncomment the following two 47 | //lines to maintain backward compatibility. 48 | //space(RC5_T1); // Second start bit 49 | //mark(RC5_T1); // Second start bit 50 | for (uint8_t i = 0; i < nBits; i++) { 51 | if (data & TOPBIT) { 52 | space(RC5_T1); mark(RC5_T1);// 1 is space, then mark 53 | } else { 54 | mark(RC5_T1); space(RC5_T1);// 0 is mark, then space 55 | } 56 | data <<= 1; 57 | } 58 | space(114000-extent); // Turn off at end 59 | } 60 | }; 61 | #endif //IRLIBSENDBASE_H 62 | 63 | #ifdef IRLIBDECODEBASE_H 64 | 65 | /* Note this decoder is a derived class from the IRdecodeRC base class 66 | * rather than IRdecodeBase. The base class defines the method "getRClevel" 67 | * which is common to both RC5 and RC6 protocols. It facilitates the decoding 68 | * of phase encoded data. 69 | */ 70 | 71 | class IRdecodeRC5: public virtual IRdecodeRC { 72 | public: 73 | virtual bool decode(void) { 74 | IRLIB_ATTEMPT_MESSAGE(F("RC5")); 75 | resetDecoder();//This used to be in the receiver getResults. 76 | if (recvGlobal.decodeLength < 13) return RAW_COUNT_ERROR; 77 | offset = 1; // Skip gap space 78 | data = 0; 79 | used = 0; 80 | // Get start bits 81 | if (getRClevel(&used, RC5_T1) != MARK) return HEADER_MARK_ERROR(RC5_T1); 82 | //Note: Original IRremote library incorrectly assumed second bit was always 83 | // a "1". Bit patterns from this decoder are not backward compatible with 84 | // patterns produced by original library. Uncomment the following two lines 85 | // to maintain backward compatibility. 86 | //if (getRClevel(&used, RC5_T1) != SPACE) return HEADER_SPACE_ERROR(RC5_T1); 87 | //if (getRClevel(&used, RC5_T1) != MARK) return HEADER_MARK_ERROR(RC5_T1); 88 | for (nBits = 0; offset < recvGlobal.decodeLength; nBits++) { 89 | RCLevel levelA = getRClevel(&used, RC5_T1); 90 | RCLevel levelB = getRClevel(&used, RC5_T1); 91 | if (levelA == SPACE && levelB == MARK) { 92 | data = (data << 1) | 1; // 1 bit 93 | } else if (levelA == MARK && levelB == SPACE) { 94 | data <<= 1; // zero bit 95 | } else return DATA_MARK_ERROR(RC5_T1); 96 | } 97 | // Success 98 | bits = nBits; 99 | value = data; 100 | protocolNum = RC5; 101 | return true; 102 | } 103 | }; 104 | #endif //IRLIBDECODEBASE_H 105 | 106 | #define IRLIB_HAVE_COMBO 107 | 108 | #endif //IRLIB_PROTOCOL_03_H 109 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/utility/IRLib_P05_Panasonic_Old.h: -------------------------------------------------------------------------------- 1 | /* IRLib_P05_Panasonic_Old.h 2 | * Part of IRLib Library for Arduino receiving, decoding, and sending 3 | * infrared signals. See COPYRIGHT.txt and LICENSE.txt for more information. 4 | */ 5 | /* 6 | * This protocol #5 named "Panasonic_Old" is a 57 kHz protocol with 22 bits 7 | * of data. The second 11 bits are the bitwise logical complement of the first 11 bits. 8 | * The protocol is used by many cable boxes and DVR's made by Scientific Atlantic and 9 | * Cisco. They are common for Bright House and Time Warner cable systems. 10 | */ 11 | 12 | #ifndef IRLIB_PROTOCOL_05_H 13 | #define IRLIB_PROTOCOL_05_H 14 | #define IR_SEND_PROTOCOL_05 case 5: IRsendPanasonic_Old::send(data); break; 15 | #define IR_DECODE_PROTOCOL_05 if(IRdecodePanasonic_Old::decode()) return true; 16 | #ifdef IRLIB_HAVE_COMBO 17 | #define PV_IR_DECODE_PROTOCOL_05 ,public virtual IRdecodePanasonic_Old 18 | #define PV_IR_SEND_PROTOCOL_05 ,public virtual IRsendPanasonic_Old 19 | #else 20 | #define PV_IR_DECODE_PROTOCOL_05 public virtual IRdecodePanasonic_Old 21 | #define PV_IR_SEND_PROTOCOL_05 public virtual IRsendPanasonic_Old 22 | #endif 23 | 24 | #ifdef IRLIBSENDBASE_H 25 | class IRsendPanasonic_Old: public virtual IRsendBase { 26 | public: 27 | void send(uint32_t data) { 28 | sendGeneric(data,22, 833*4, 833*4, 833, 833, 833*3, 833,57, true); 29 | }; 30 | }; 31 | #endif //IRLIBSENDBASE_H 32 | 33 | #ifdef IRLIBDECODEBASE_H 34 | class IRdecodePanasonic_Old: public virtual IRdecodeBase { 35 | public: 36 | virtual bool decode(void) { 37 | IRLIB_ATTEMPT_MESSAGE(F("Panasonic_Old")); 38 | if(!decodeGeneric(48,833*4,833*4,833,833*3,833)) return false; 39 | // The protocol spec says that the first 11 bits described the device and function. 40 | // The next 11 bits are the same thing only it is the logical Bitwise complement. 41 | // Many protocols have such check features in their definition but our code typically 42 | // doesn't perform these checks. For example NEC's least significant 8 bits are the 43 | // complement of the next more significant 8 bits. While it's probably not necessary 44 | // to error check this, you can un-comment the next 4 lines of code to do this extra 45 | // checking. 46 | // long S1= (value & 0x0007ff); // 00 0000 0000 0111 1111 1111 47 | // long S2= (value & 0x3ff800)>> 11; // 11 1111 1111 1000 0000 0000 48 | // S2= (~S2) & 0x0007ff; 49 | // if (S1!=S2) return IRLIB_REJECTION_MESSAGE(F("inverted bit redundancy")); 50 | protocolNum = PANASONIC_OLD; 51 | return true; 52 | }; 53 | }; 54 | #endif //IRLIBDECODEBASE_H 55 | 56 | #define IRLIB_HAVE_COMBO 57 | 58 | #endif //IRLIB_PROTOCOL_05_H 59 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/utility/IRLib_P06_JVC.h: -------------------------------------------------------------------------------- 1 | /* IRLib_P06_JVC.h 2 | * Part of IRLib Library for Arduino receiving, decoding, and sending 3 | * infrared signals. See COPYRIGHT.txt and LICENSE.txt for more information. 4 | */ 5 | /* 6 | * JVC omits the mark/space header on repeat sending. Therefore we multiply 7 | * it by 0 if it's a repeat. The only device I had to test this protocol was 8 | * an old JVC VCR. It would only work if at least 2 frames are sent separated 9 | * by 45 time periods of "space". Therefore you should call this routine once 10 | * with "first=true" and it will send a first frame followed by one repeat 11 | * frame. If First==false, it will only send a single repeat frame. 12 | */ 13 | 14 | #ifndef IRLIB_PROTOCOL_06_H 15 | #define IRLIB_PROTOCOL_06_H 16 | #define IR_SEND_PROTOCOL_06 case 06: IRsendJVC::send(data,(bool)data2); break; 17 | #define IR_DECODE_PROTOCOL_06 if(IRdecodeJVC::decode()) return true; 18 | #ifdef IRLIB_HAVE_COMBO 19 | #define PV_IR_DECODE_PROTOCOL_06 ,public virtual IRdecodeJVC 20 | #define PV_IR_SEND_PROTOCOL_06 ,public virtual IRsendJVC 21 | #else 22 | #define PV_IR_DECODE_PROTOCOL_06 public virtual IRdecodeJVC 23 | #define PV_IR_SEND_PROTOCOL_06 public virtual IRsendJVC 24 | #endif 25 | 26 | #ifdef IRLIBSENDBASE_H 27 | class IRsendJVC: public virtual IRsendBase { 28 | public: 29 | void send(uint32_t data, bool first=true) { 30 | sendGeneric(data, 16,525*16*first, 525*8*first, 525, 525,525*3, 525, 38, true); 31 | space(525*45); 32 | if(first) { 33 | sendGeneric(data, 16,0,0, 525, 525,525*3, 525, 38, true); 34 | space(525*45); 35 | } 36 | } 37 | }; 38 | #endif //IRLIBSENDBASE_H 39 | 40 | #ifdef IRLIBDECODEBASE_H 41 | class IRdecodeJVC: public virtual IRdecodeBase { 42 | public: 43 | bool decode(void) { 44 | // JVC does not send any header if there is a repeat. 45 | // first try with the header. If that fails, try without. 46 | IRLIB_ATTEMPT_MESSAGE(F("JVC")); 47 | if(!decodeGeneric(36,525*16,525*8,525,525*3,525)) { 48 | IRLIB_ATTEMPT_MESSAGE(F("JVC Repeat")); 49 | if (recvGlobal.decodeLength==34) { 50 | if(!decodeGeneric(0,525,0,525,525*3,525)) { 51 | return IRLIB_REJECTION_MESSAGE(F("JVC repeat failed generic")); 52 | } else { 53 | //If this is a repeat code then IRdecodeBase::decodeGeneric fails to add the most significant bit 54 | if (MATCH(recvGlobal.decodeBuffer[2],(525*3))) { 55 | value |= 0x8000; 56 | } else { 57 | if (!MATCH(recvGlobal.decodeBuffer[2],525)) return DATA_SPACE_ERROR(525); 58 | } 59 | } 60 | bits++; 61 | } 62 | else return RAW_COUNT_ERROR; 63 | } 64 | address=(recvGlobal.decodeLength==36); 65 | protocolNum =JVC; 66 | return true; 67 | } 68 | }; 69 | #endif //IRLIBDECODEBASE_H 70 | 71 | #define IRLIB_HAVE_COMBO 72 | 73 | #endif //IRLIB_PROTOCOL_06_H 74 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/utility/IRLib_P07_NECx.h: -------------------------------------------------------------------------------- 1 | /* IRLib_P07_NECx.h 2 | * Part of IRLib Library for Arduino receiving, decoding, and sending 3 | * infrared signals. See COPYRIGHT.txt and LICENSE.txt for more information. 4 | */ 5 | /* 6 | * NECx is a variation of NEC protocol. The only difference is in the timing of the 7 | * header. There are two variations NECx1 and NECx2. They differ only in the way in 8 | * which they handle repeat codes. If you hold a button using NECx1 it does not repeat 9 | * the same sequence. Rather it sends a special sequence consisting of the usual header 10 | * followed by a normal mark, a "1" bit, and then a long space with a 108ms extent. Note 11 | * this so-called "ditto" repeat code is slightly different than the one for regular NEC. 12 | * When IRLib receives one of these special repeat sequences, it returns the 13 | * value REPEAT_CODE which is defined in IRLibProtocols.h as the value 0xffffffff. If you 14 | * send REPEAT_CODE, the send routine will create a special sequence for you. 15 | * Whether it is a normal code or a repeat code the entire frame has a 108ms extent. 16 | * The IRP notation for these protocols are: 17 | * NECx1: {38k,564}<1,-1|1,-3>(8,-8,D:8,S:8,F:8,~F:8,1,^108,(8,-8,D:1,1,^108m)*) 18 | * NECx2: {38k,564}<1,-1|1,-3>(8,-8,D:8,S:8,F:8,~F:8,1,^108)+ 19 | */ 20 | 21 | #ifndef IRLIB_PROTOCOL_07_H 22 | #define IRLIB_PROTOCOL_07_H 23 | #define IR_SEND_PROTOCOL_07 case 07: IRsendNECx::send(data); break; 24 | #define IR_DECODE_PROTOCOL_07 if(IRdecodeNECx::decode()) return true; 25 | #ifdef IRLIB_HAVE_COMBO 26 | #define PV_IR_DECODE_PROTOCOL_07 ,public virtual IRdecodeNECx 27 | #define PV_IR_SEND_PROTOCOL_07 ,public virtual IRsendNECx 28 | #else 29 | #define PV_IR_DECODE_PROTOCOL_07 public virtual IRdecodeNECx 30 | #define PV_IR_SEND_PROTOCOL_07 public virtual IRsendNECx 31 | #endif 32 | 33 | #ifdef IRLIBSENDBASE_H 34 | class IRsendNECx: public virtual IRsendBase { 35 | public: 36 | void send(uint32_t data) { 37 | if (data==REPEAT_CODE) { 38 | enableIROut(38); 39 | mark(564*8); space(564*8); mark(564);space(564); 40 | mark(564); space(412);delay(98);//actually 98412us 41 | } 42 | else { 43 | sendGeneric(data,32, 564*8, 564*8, 564, 564, 564*3, 564, 38, true); 44 | } 45 | }; 46 | }; 47 | #endif //IRLIBSENDBASE_H 48 | 49 | #ifdef IRLIBDECODEBASE_H 50 | class IRdecodeNECx: public virtual IRdecodeBase { 51 | public: 52 | virtual bool decode(void) { 53 | IRLIB_ATTEMPT_MESSAGE(F("NECx")); 54 | resetDecoder();//This used to be in the receiver getResults. 55 | // Check for repeat 56 | if (recvGlobal.decodeLength == 6 && MATCH(recvGlobal.decodeBuffer[1], 564*8) && MATCH(recvGlobal.decodeBuffer[2],564*8) 57 | && MATCH(recvGlobal.decodeBuffer[3],564) && MATCH(recvGlobal.decodeBuffer[5],564) 58 | ) { 59 | bits = 0; 60 | value = REPEAT_CODE; 61 | protocolNum = NECX; 62 | return true; 63 | } 64 | if(!decodeGeneric(68, 564*8, 564*8, 564, 564*3, 564)) return false; 65 | protocolNum = NECX; 66 | return true; 67 | } 68 | }; 69 | #endif //IRLIBDECODEBASE_H 70 | 71 | #define IRLIB_HAVE_COMBO 72 | 73 | #endif //IRLIB_PROTOCOL_07_H 74 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/utility/IRLib_P09_GICable.h: -------------------------------------------------------------------------------- 1 | /* IRLib_P09_GICable.h 2 | * Part of IRLib Library for Arduino receiving, decoding, and sending 3 | * infrared signals. See COPYRIGHT.txt and LICENSE.txt for more information. 4 | */ 5 | 6 | /* The G.I. Cable protocol is is used by many Motorola brand cable boxes manufactured by 7 | * General Instruments. The IRP notation for this protocol is 8 | * "{38.7k,490}<1,-4.5|1,-9>(18,-9,F:8,D:4,C:4,1,-84,(18,-4.5,1,-178)*) {C = -(D + F:4 + F:4:4)}" 9 | * It is a 16-bit code which uses an unusual "ditto" repeat sequence similar to NEC. 10 | * In fact it is so similar that IRLib generally not distinguish between the two. 11 | * The header timing for G.I. Cable ditto is 8820,1960 and for NEC is 9024,2256 12 | * If you are using both protocols and you receive an NEC ditto immediately after 13 | * receiving a G.I.Cable then you should presume it is a G.I.Cable and vice versa. 14 | */ 15 | #ifndef IRLIB_PROTOCOL_09_H 16 | #define IRLIB_PROTOCOL_09_H 17 | #define IR_SEND_PROTOCOL_09 case 9: IRsendGICable::send(data); break; 18 | #define IR_DECODE_PROTOCOL_09 if(IRdecodeGICable::decode()) return true; 19 | #ifdef IRLIB_HAVE_COMBO 20 | #define PV_IR_DECODE_PROTOCOL_09 ,public virtual IRdecodeGICable 21 | #define PV_IR_SEND_PROTOCOL_09 ,public virtual IRsendGICable 22 | #else 23 | #define PV_IR_DECODE_PROTOCOL_09 public virtual IRdecodeGICable 24 | #define PV_IR_SEND_PROTOCOL_09 public virtual IRsendGICable 25 | #endif 26 | 27 | #ifdef IRLIBSENDBASE_H 28 | class IRsendGICable: public virtual IRsendBase { 29 | public: 30 | void send(uint32_t data) { 31 | if(data==REPEAT_CODE) { 32 | enableIROut(39); 33 | mark (490*18); space(2205);//actually "490*4.5" 34 | mark (490); space(220);delay(87);//actually 490*178 or "space(87220);" 35 | } else { 36 | sendGeneric(data,16, 490*18, 490*9, 490, 490, 490*9, 2205/*(4.5*490)*/, 39, true); 37 | space(37*490); 38 | } 39 | } 40 | }; 41 | #endif //IRLIBSENDBASE_H 42 | 43 | #ifdef IRLIBDECODEBASE_H 44 | class IRdecodeGICable: public virtual IRdecodeBase { 45 | public: 46 | bool decode(void) { 47 | IRLIB_ATTEMPT_MESSAGE(F("G.I.cable")); 48 | // Check for repeat 49 | if (recvGlobal.decodeLength == 4 && MATCH(recvGlobal.decodeBuffer[1], 490*18) && MATCH(recvGlobal.decodeBuffer[2],2205) 50 | && MATCH(recvGlobal.decodeBuffer[3],490)) { 51 | bits = 0; 52 | value = REPEAT_CODE; 53 | protocolNum=GICABLE; 54 | return true; 55 | } 56 | if(!decodeGeneric(36, 18*490, 9*490, 490, 9*490, 2205/*(4.5*490)*/)) return false; 57 | protocolNum=GICABLE; 58 | return true; 59 | } 60 | }; 61 | #endif //IRLIBDECODEBASE_H 62 | 63 | #define IRLIB_HAVE_COMBO 64 | 65 | #endif //IRLIB_PROTOCOL_09_H 66 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/utility/IRLib_P99_Additional.h: -------------------------------------------------------------------------------- 1 | /* IRLib_P99_Additional.h 2 | * Part of IRLib Library for Arduino receiving, decoding, and sending 3 | * infrared signals. See COPYRIGHT.txt and LICENSE.txt for more information. 4 | */ 5 | /* 6 | * This is dummy code that you can copy and rename and modify when implementing new protocols. 7 | */ 8 | 9 | #ifndef IRLIB_PROTOCOL_99_H 10 | #define IRLIB_PROTOCOL_99_H 11 | #define IR_SEND_PROTOCOL_99 case 99: IRsendAdditional::send(data); break; 12 | #define IR_DECODE_PROTOCOL_99 if(IRdecodeAdditional::decode()) return true; 13 | #ifdef IRLIB_HAVE_COMBO 14 | #define PV_IR_DECODE_PROTOCOL_99 ,public virtual IRdecodeAdditional 15 | #define PV_IR_SEND_PROTOCOL_99 ,public virtual IRsendAdditional 16 | #else 17 | #define PV_IR_DECODE_PROTOCOL_99 public virtual IRdecodeAdditional 18 | #define PV_IR_SEND_PROTOCOL_99 public virtual IRsendAdditional 19 | #endif 20 | 21 | #ifdef IRLIBSENDBASE_H 22 | class IRsendAdditional: public virtual IRsendBase { 23 | public: 24 | void IRsendAdditional::send(uint32_t data) { 25 | //void IRsendAdditional::send(uint32_t data, uint32_t data2)//optional form 26 | /********* 27 | * Insert your code here. 28 | *********/ 29 | }; 30 | }; 31 | #endif //IRLIBSENDBASE_H 32 | 33 | #ifdef IRLIBDECODEBASE_H 34 | class IRdecodeAdditional: public virtual IRdecodeBase { 35 | public: 36 | bool IRdecodeAdditional::decode(void) { 37 | IRLIB_ATTEMPT_MESSAGE(F("Additional")); 38 | /********* 39 | * Insert your code here. Return false if it fails. 40 | * Don't forget to include the following lines or 41 | * equivalent somewhere in the code. 42 | * 43 | * bits = 32; //Substitute proper value here 44 | * value = data; //return data in "value" 45 | * protocolNum = ADDITIONAL; //set the protocol number here. 46 | */ 47 | return true; 48 | } 49 | }; 50 | 51 | #endif //IRLIBDECODEBASE_H 52 | 53 | #define IRLIB_HAVE_COMBO 54 | 55 | #endif //IRLIB_PROTOCOL_99_H 56 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/utility/IRLib_readme.md: -------------------------------------------------------------------------------- 1 | # IRLib2 A Library for Receiving, Decoding and Sending Infrared Signals Using Arduino. 2 | 3 | IRLib2 is copyright 2017 by Chris Young. It it is a major rewrite of the original IRLib 1.x by Chris Young which in turn was based on IRremote by Ken Shirriff. See COPYRIGHT.txt for details. 4 | 5 | This library is covered under the GNU GENERAL PUBLIC LICENSE Version 3. See LICENSE.txt for a copy of the license. 6 | 7 | This somewhat stripped-down version has been customized for use with Circuit Playground Express. It contains only IRrecvPCI receiver class because that is the one we recommend for use with Circuit Playground Express. It is automatically configured to use the building IR input and output capabilities of this board. 8 | 9 | The complete library is available on GitHub at https://github.com/cyborg5/IRLib2 10 | 11 | In that archive see CHANGELOG.txt for recent changes. It also contains a detailed Users Manual consisting of a reference, several tutorials, and information on how to implement new protocols is available in .docx, .pdf and .epub formats in the IRLib2/manuals/ folder. 12 | -------------------------------------------------------------------------------- /libraries/Adafruit_Circuit_Playground/utility/README.md: -------------------------------------------------------------------------------- 1 | #CapacitiveSensor Library# 2 | 3 | CapacitiveSensor lets you create sensors that can detect touch or proximity. 4 | 5 | http://www.pjrc.com/teensy/td_libs_CapacitiveSensor.html 6 | 7 | http://playground.arduino.cc/Main/CapacitiveSensor 8 | 9 | http://www.youtube.com/watch?v=BHQPqQ_5ulc 10 | 11 | CapacitiveSensor was originally written by Paul Badger and is now maintained by Paul Stoffregen. 12 | 13 | ![CapacitiveSensor Demo](http://www.pjrc.com/teensy/td_libs_CapacitiveSensor_1.jpg) 14 | -------------------------------------------------------------------------------- /libraries/MsTimer2/MsTimer2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | unsigned long MsTimer2::msecs; 4 | void (*MsTimer2::func)(); 5 | volatile unsigned long MsTimer2::count; 6 | volatile char MsTimer2::overflowing; 7 | volatile unsigned int MsTimer2::tcnt2; 8 | 9 | void MsTimer2::set(unsigned long ms, void (*f)()) { 10 | float prescaler = 0.0; 11 | 12 | #if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || (__AVR_ATmega1280__) 13 | TIMSK2 &= ~(1<= 1000000UL) && (F_CPU <= 16000000UL)) { // prescaler set to 64 20 | TCCR2B |= (1< 16Mhz, prescaler set to 128 28 | TCCR2B |= ((1<= 1000000UL) && (F_CPU <= 16000000UL)) { // prescaler set to 64 39 | TCCR2 |= (1< 16Mhz, prescaler set to 128 47 | TCCR2 |= ((1<= 1000000UL) && (F_CPU <= 16000000UL)) { // prescaler set to 64 57 | TCCR2 |= ((1< 16Mhz, prescaler set to 256 65 | TCCR2 |= (1<= msecs && !overflowing) { 110 | overflowing = 1; 111 | count = 0; 112 | (*func)(); 113 | overflowing = 0; 114 | } 115 | } 116 | 117 | ISR(TIMER2_OVF_vect) { 118 | #if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || (__AVR_ATmega1280__) 119 | TCNT2 = MsTimer2::tcnt2; 120 | #elif defined (__AVR_ATmega128__) 121 | TCNT2 = MsTimer2::tcnt2; 122 | #elif defined (__AVR_ATmega8__) 123 | TCNT2 = MsTimer2::tcnt2; 124 | #endif 125 | MsTimer2::_overflow(); 126 | } 127 | 128 | -------------------------------------------------------------------------------- /libraries/MsTimer2/MsTimer2.h: -------------------------------------------------------------------------------- 1 | #ifndef MsTimer2_h 2 | #define MsTimer2_h 3 | 4 | #include 5 | 6 | namespace MsTimer2 { 7 | extern unsigned long msecs; 8 | extern void (*func)(); 9 | extern volatile unsigned long count; 10 | extern volatile char overflowing; 11 | extern volatile unsigned int tcnt2; 12 | 13 | void set(unsigned long ms, void (*f)()); 14 | void start(); 15 | void stop(); 16 | void _overflow(); 17 | } 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /libraries/MsTimer2/examples/FlashLed/FlashLed.pde: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // Switch on LED on pin 13 each second 4 | 5 | 6 | void flash() { 7 | static boolean output = HIGH; 8 | 9 | digitalWrite(13, output); 10 | output = !output; 11 | } 12 | 13 | void setup() { 14 | pinMode(13, OUTPUT); 15 | 16 | MsTimer2::set(500, flash); // 500ms period 17 | MsTimer2::start(); 18 | } 19 | 20 | void loop() { 21 | } 22 | -------------------------------------------------------------------------------- /libraries/PS2X_lib/examples/PS2XMouse/PS2XMouse.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | PS2X ps2x; // create PS2 Controller Class 4 | 5 | int error = 0; 6 | byte type = 0; 7 | const int ledPin = 11; // Mouse control LED (11 on Teensy 2.0, 13 on Arduino Leonardo) 8 | 9 | // parameters for reading the joystick: 10 | int range = 12; // output range of X or Y movement 11 | int responseDelay = 5; // response delay of the mouse, in ms 12 | int threshold = range/4; // resting threshold 13 | int center = range/2; // resting position value 14 | 15 | boolean mouseIsActive = false; // whether or not to control the mouse 16 | int lastSwitchState = LOW; // previous switch state 17 | 18 | void setup(){ 19 | Serial.begin(57600); 20 | 21 | error = ps2x.config_gamepad(15,14,13,12, true, true); //setup pins and settings: GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error 22 | 23 | if(error == 0){ 24 | Serial.println("Found Controller, configured successful"); 25 | } 26 | 27 | else if(error == 1) 28 | Serial.println("No controller found, check wiring, see readme.txt to enable debug. visit www.billporter.info for troubleshooting tips"); 29 | 30 | else if(error == 2) 31 | Serial.println("Controller found but not accepting commands. see readme.txt to enable debug. Visit www.billporter.info for troubleshooting tips"); 32 | 33 | else if(error == 3) 34 | Serial.println("Controller refusing to enter Pressures mode, may not support it. "); 35 | 36 | type = ps2x.readType(); 37 | switch(type) { 38 | case 0: 39 | Serial.println("Unknown Controller type"); 40 | break; 41 | case 1: 42 | Serial.println("DualShock Controller Found"); 43 | break; 44 | case 2: 45 | Serial.println("GuitarHero Controller Found"); 46 | break; 47 | } 48 | 49 | // take control of the mouse: 50 | Mouse.begin(); 51 | Keyboard.begin(); 52 | } 53 | 54 | void loop() 55 | { 56 | 57 | if(error == 1) //skip loop if no controller found 58 | return; 59 | 60 | ps2x.read_gamepad(false, 0); //read controller and set large motor to spin at 'vibrate' speed 61 | 62 | // read the switch: 63 | int switchState = ps2x.ButtonPressed(PSB_RED); 64 | // if it's changed and it's high, toggle the mouse state: 65 | if (switchState != lastSwitchState) { 66 | if (switchState == HIGH) { 67 | mouseIsActive = !mouseIsActive; 68 | // turn on LED to indicate mouse state: 69 | digitalWrite(ledPin, mouseIsActive); 70 | } 71 | } 72 | // save switch state for next comparison: 73 | lastSwitchState = switchState; 74 | 75 | // read and scale the two axes: 76 | int xReading = readAxis(PSS_LX); 77 | int yReading = readAxis(PSS_LY); 78 | 79 | // if the mouse control state is active, move the mouse: 80 | if (mouseIsActive) { 81 | Mouse.move(xReading, yReading, 0); 82 | } 83 | 84 | // read the mouse button and click or not click: 85 | // if the mouse button is pressed: 86 | if (ps2x.ButtonPressed(PSB_BLUE)) { 87 | // if the mouse is not pressed, press it: 88 | if (!Mouse.isPressed(MOUSE_LEFT)) { 89 | Mouse.press(MOUSE_LEFT); 90 | } 91 | } 92 | // else the mouse button is not pressed: 93 | else { 94 | // if the mouse is pressed, release it: 95 | if (Mouse.isPressed(MOUSE_LEFT)) { 96 | Mouse.release(MOUSE_LEFT); 97 | } 98 | } 99 | 100 | if (ps2x.Button(PSB_PAD_UP)) { 101 | Keyboard.press(KEY_UP_ARROW); 102 | } else { 103 | Keyboard.release(KEY_UP_ARROW); 104 | } 105 | 106 | if (ps2x.Button(PSB_PAD_DOWN)) { 107 | Keyboard.press(KEY_DOWN_ARROW); 108 | } else { 109 | Keyboard.release(KEY_DOWN_ARROW); 110 | } 111 | 112 | if (ps2x.Button(PSB_PAD_RIGHT)) { 113 | Keyboard.press(KEY_RIGHT_ARROW); 114 | } else { 115 | Keyboard.release(KEY_RIGHT_ARROW); 116 | } 117 | 118 | if (ps2x.Button(PSB_PAD_LEFT)) { 119 | Keyboard.press(KEY_LEFT_ARROW); 120 | } else { 121 | Keyboard.release(KEY_LEFT_ARROW); 122 | } 123 | 124 | delay(5); 125 | 126 | } 127 | 128 | /* 129 | reads an axis (0 or 1 for x or y) and scales the 130 | analog input range to a range from 0 to 131 | */ 132 | 133 | int readAxis(int thisAxis) { 134 | // read the analog input: 135 | int reading = ps2x.Analog(thisAxis); 136 | 137 | // map the reading from the analog input range to the output range: 138 | reading = map(reading, 0, 255, 0, range); 139 | 140 | // if the output reading is outside from the 141 | // rest position threshold, use it: 142 | int distance = reading - center; 143 | 144 | if (abs(distance) < threshold) { 145 | distance = 0; 146 | } 147 | 148 | // return the distance for this axis: 149 | return distance; 150 | } 151 | -------------------------------------------------------------------------------- /libraries/PS2X_lib/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map PS2X 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | PS2X KEYWORD1 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | Button KEYWORD2 15 | ButtonDataByte KEYWORD2 16 | NewButtonState KEYWORD2 17 | ButtonPressed KEYWORD2 18 | ButtonReleased KEYWORD2 19 | read_gamepad KEYWORD2 20 | config_gamepad KEYWORD2 21 | enableRumble KEYWORD2 22 | enablePressures KEYWORD2 23 | Analog KEYWORD2 24 | 25 | ####################################### 26 | # Constants (LITERAL1) 27 | ####################################### 28 | PSB_SELECT LITERAL1 29 | PSB_L3 LITERAL1 30 | PSB_R3 LITERAL1 31 | PSB_START LITERAL1 32 | PSB_PAD_UP LITERAL1 33 | PSB_PAD_RIGHT LITERAL1 34 | PSB_PAD_DOWN LITERAL1 35 | PSB_PAD_LEFT LITERAL1 36 | PSB_L2 LITERAL1 37 | PSB_R2 LITERAL1 38 | PSB_L1 LITERAL1 39 | PSB_R1 LITERAL1 40 | PSB_GREEN LITERAL1 41 | PSB_RED LITERAL1 42 | PSB_BLUE LITERAL1 43 | PSB_PINK LITERAL1 44 | PSB_TRIANGLE LITERAL1 45 | PSB_CIRCLE LITERAL1 46 | PSB_CROSS LITERAL1 47 | PSB_SQUARE LITERAL1 48 | PSS_RX LITERAL1 49 | PSS_RY LITERAL1 50 | PSS_LX LITERAL1 51 | PSS_LY LITERAL1 52 | 53 | PSAB_PAD_RIGHT LITERAL1 54 | PSAB_PAD_UP LITERAL1 55 | PSAB_PAD_DOWN LITERAL1 56 | PSAB_PAD_LEFT LITERAL1 57 | PSAB_L2 LITERAL1 58 | PSAB_R2 LITERAL1 59 | PSAB_L1 LITERAL1 60 | PSAB_R1 LITERAL1 61 | PSAB_GREEN LITERAL1 62 | PSAB_RED LITERAL1 63 | PSAB_BLUE LITERAL1 64 | PSAB_PINK LITERAL1 65 | PSAB_TRIANGLE LITERAL1 66 | PSAB_CIRCLE LITERAL1 67 | PSAB_CROSS LITERAL1 68 | PSAB_SQUARE LITERAL1 69 | 70 | GREEN_FRET LITERAL1 71 | RED_FRET LITERAL1 72 | YELLOW_FRET LITERAL1 73 | BLUE_FRET LITERAL1 74 | ORANGE_FRET LITERAL1 75 | STAR_POWER LITERAL1 76 | UP_STRUM LITERAL1 77 | DOWN_STRUM LITERAL1 78 | WHAMMY_BAR LITERAL1 79 | -------------------------------------------------------------------------------- /libraries/PinChangeInt/Examples/ByteBuffer/ByteBuffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | ByteBuffer.h - A circular buffer implementation for Arduino 3 | Created by Sigurdur Orn, July 19, 2010. siggi@mit.edu 4 | Updated by GreyGnome (aka Mike Schwager) Thu Feb 23 17:25:14 CST 2012 5 | added the putString() method and the fillError variable. 6 | added the checkError() and resetError() methods. The checkError() method resets the fillError variable 7 | to false as a side effect. 8 | added the ByteBuffer(unsigned int buf_size) constructor. 9 | added the init() method, and had the constructor call it automagically. 10 | protected certain sections of the code with cli()/sei() calls, for safe use by interrupts. 11 | Also made the capacity, position, length, and fillError variables volatile, for safe use by interrupts. 12 | */ 13 | 14 | #ifndef ByteBuffer_h 15 | #define ByteBuffer_h 16 | 17 | #if defined(ARDUINO) && ARDUINO >= 100 18 | #include 19 | #else 20 | #include 21 | #endif 22 | //#include 23 | 24 | #define DEFAULTBUFSIZE 32 25 | class ByteBuffer 26 | { 27 | public: 28 | ByteBuffer() { 29 | init(); 30 | }; 31 | ByteBuffer(unsigned int buf_size) { 32 | init(buf_size); 33 | }; 34 | 35 | // This method initializes the datastore of the buffer to a certain size. 36 | void init(unsigned int buf_size); 37 | 38 | // This method initializes the datastore of the buffer to the default size. 39 | void init(); 40 | 41 | // This method resets the buffer into an original state (with no data) 42 | void clear(); 43 | 44 | // This method resets the fillError variable to false. 45 | void resetError(); 46 | 47 | // This method tells you if your buffer overflowed at some time since the last 48 | // check. The error state will be reset to false. 49 | boolean checkError(); 50 | 51 | // This releases resources for this buffer, after this has been called the buffer should NOT be used 52 | void deAllocate(); 53 | 54 | // Returns how much space is used in the buffer 55 | int getSize(); 56 | 57 | // Returns the maximum capacity of the buffer 58 | int getCapacity(); 59 | 60 | // This method returns the byte that is located at index in the buffer but doesn't modify the buffer like the get methods (doesn't remove the retured byte from the buffer) 61 | byte peek(unsigned int index); 62 | 63 | // 64 | // Put methods, either a regular put in back or put in front 65 | // 66 | uint8_t putInFront(byte in); 67 | uint8_t put(byte in); 68 | uint8_t putString(char *in); 69 | 70 | void putIntInFront(int in); 71 | void putInt(int in); 72 | 73 | void putLongInFront(long in); 74 | void putLong(long in); 75 | 76 | void putFloatInFront(float in); 77 | void putFloat(float in); 78 | 79 | // 80 | // Get methods, either a regular get from front or from back 81 | // 82 | byte get(); 83 | byte getFromBack(); 84 | 85 | int getInt(); 86 | int getIntFromBack(); 87 | 88 | long getLong(); 89 | long getLongFromBack(); 90 | 91 | float getFloat(); 92 | float getFloatFromBack(); 93 | 94 | private: 95 | byte* data; 96 | 97 | volatile unsigned int capacity; 98 | volatile unsigned int position; 99 | volatile unsigned int length; 100 | volatile boolean fillError; 101 | }; 102 | 103 | #endif 104 | 105 | -------------------------------------------------------------------------------- /libraries/PinChangeInt/Examples/GetPSTR/GetPSTR.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_GETPSTR 2 | #define INCLUDE_GETPSTR 3 | 4 | #if defined(ARDUINO) && ARDUINO >= 100 5 | #include 6 | #else 7 | #include "pins_arduino.h" 8 | #include "WProgram.h" 9 | #include "wiring.h" 10 | #endif 11 | 12 | #define getPSTR(s) pgmStrToRAM(PSTR(s)) 13 | 14 | char *_pstr_to_print; 15 | char *pgmStrToRAM(PROGMEM char *theString) { 16 | free(_pstr_to_print); 17 | _pstr_to_print=(char *) malloc(strlen_P(theString)); 18 | strcpy_P(_pstr_to_print, theString); 19 | return (_pstr_to_print); 20 | } 21 | #endif 22 | -------------------------------------------------------------------------------- /libraries/PinChangeInt/Examples/PinChangeIntExample2560/PinChangeIntExample2560.ino: -------------------------------------------------------------------------------- 1 | // PinChangeIntExample2560 2 | // This only works for ATMega2560-based boards. 3 | // See the Arduino and the chip documentation for more details. 4 | 5 | // See the Wiki at http://code.google.com/p/arduino-pinchangeint/wiki for more information. 6 | // for vim editing: :set et ts=2 sts=2 sw=2 7 | 8 | // This example demonstrates a configuration of 3 interrupting pins and 2 interrupt functions. 9 | // The functions set the values of some global variables. All interrupts are serviced immediately, 10 | // and the sketch can then query the values at our leisure. This makes loop timing non-critical. 11 | 12 | // The interrupt functions are a simple count of the number of times the pin was brought high. 13 | // For 2 of the pins, the values are stored and retrieved from an array and they are reset after 14 | // every read. For one of the pins ("MYPIN3"), there is a monotonically increasing count; that is, 15 | // until the 8-bit value reaches 255. Then it will go back to 0. 16 | 17 | // For a more introductory sketch, see the SimpleExample328.ino sketch in the PinChangeInt 18 | // library distribution. 19 | 20 | #include 21 | 22 | // PIN NAMING 23 | // For the Analog Input pins used as digital input pins, you can call them 14, 15, 16, etc. 24 | // or you can use A0, A1, A2, etc. (the Arduino code will properly recognize the symbolic names, 25 | // for example, pinMode(A0, INPUT_PULLUP); 26 | 27 | // For Arduino MEGA (AT2560-based), besides the regular pins and the A (analog) pins, 28 | // you have 4 more pins with defined names: 29 | // SS = 53 30 | // MOSI = 51 31 | // MISO = 50 32 | // SCK = 52 33 | 34 | // NOW CHOOSE PINS 35 | #if ! ( defined __AVR_ATmega2560__ || defined __AVR_ATmega1280__ || defined __AVR_ATmega1281__ || defined __AVR_ATmega2561__ || defined __AVR_ATmega640__ ) 36 | #error "This sketch only works on chips in the ATmega2560 family." 37 | #endif 38 | 39 | #define FIRST_ANALOG_PIN 54 40 | #define TOTAL_PINS 69 // But only 18 of them (not including RX0) are PinChangeInt-compatible 41 | // Don't use RX0 (Arduino pin 0) in this program- it won't work this is the 42 | // pin that Serial.print() uses! 43 | // See the Arduino and the chip documentation for more details. 44 | #define MYPIN1 SS 45 | #define MYPIN2 SCK 46 | #define MYPIN3 MOSI 47 | #define PIN3TEXT "MOSI" // This will say what MYPIN3 is, on the serial monitor 48 | 49 | volatile uint8_t latest_interrupted_pin; 50 | volatile uint8_t interrupt_count[TOTAL_PINS]={0}; // possible arduino pins 51 | volatile uint8_t pin3Count=0; 52 | 53 | // Do not use any Serial.print() in this function. Serial.print() uses interrupts, and is not compatible 54 | // with an interrupt routine...! 55 | void quicfunc() { 56 | latest_interrupted_pin=PCintPort::arduinoPin; 57 | interrupt_count[latest_interrupted_pin]++; 58 | }; 59 | 60 | // You can assign any number of functions to different pins. How cool is that? 61 | void pin3func() { 62 | pin3Count++; 63 | } 64 | 65 | void setup() { 66 | pinMode(MYPIN1, INPUT_PULLUP); 67 | attachPinChangeInterrupt(MYPIN1, quicfunc, FALLING); // add more attachInterrupt code as required 68 | pinMode(MYPIN2, INPUT_PULLUP); 69 | attachPinChangeInterrupt(MYPIN2, quicfunc, FALLING); 70 | pinMode(MYPIN3, INPUT_PULLUP); 71 | attachPinChangeInterrupt(MYPIN3, pin3func, CHANGE); 72 | Serial.begin(115200); 73 | Serial.println("---------------------------------------"); 74 | } 75 | 76 | uint8_t i; 77 | uint8_t currentPIN3Count=0; 78 | void loop() { 79 | uint8_t count; 80 | Serial.print("."); 81 | delay(1000); // every second, 82 | for (i=0; i < TOTAL_PINS; i++) { 83 | if (interrupt_count[i] != 0) { // look at all the interrupted pins 84 | count=interrupt_count[i]; // store its count since the last iteration 85 | interrupt_count[i]=0; // and reset it to 0. 86 | Serial.print("Count for pin "); 87 | if (i == 50) { Serial.print("MISO"); } // then tell the user what it was, in a friendly way. 88 | else if (i == 51) { Serial.print("MOSI"); } 89 | else if (i == 52) { Serial.print("SCK"); } 90 | else if (i == 53) { Serial.print("SS"); } 91 | else if (i < FIRST_ANALOG_PIN) { 92 | Serial.print("D"); 93 | Serial.print(i, DEC); 94 | } else { 95 | Serial.print("A"); 96 | Serial.print(i-FIRST_ANALOG_PIN, DEC); 97 | } 98 | Serial.print(" is "); 99 | Serial.println(count, DEC); 100 | } 101 | } 102 | if (currentPIN3Count != pin3Count) { // Print our monotonically increasing counter (no reset to 0) 103 | Serial.print(PIN3TEXT); 104 | Serial.print(" count update: "); Serial.print(pin3Count, DEC); Serial.println(); 105 | currentPIN3Count=pin3Count; 106 | } 107 | } 108 | 109 | -------------------------------------------------------------------------------- /libraries/PinChangeInt/Examples/PinChangeIntExample328/PinChangeIntExample328.ino: -------------------------------------------------------------------------------- 1 | // PinChangeIntExample 2 | // This only works for ATMega328-compatibles; ie, Leonardo is not covered here. 3 | // See the Arduino and the chip documentation for more details. 4 | // See the Wiki at http://code.google.com/p/arduino-pinchangeint/wiki for more information. 5 | 6 | // for vim editing: :set et ts=2 sts=2 sw=2 7 | 8 | // This example demonstrates a configuration of 3 interrupting pins and 2 interrupt functions. 9 | // The functions set the values of some global variables. All interrupts are serviced immediately, 10 | // and the sketch can then query the values at our leisure. This makes loop timing non-critical. 11 | 12 | // The interrupt functions are a simple count of the number of times the pin was brought high. 13 | // For 2 of the pins, the values are stored and retrieved from an array and they are reset after 14 | // every read. For one of the pins ("MYPIN3"), there is a monotonically increasing count; that is, 15 | // until the 8-bit value reaches 255. Then it will go back to 0. 16 | 17 | // For a more introductory sketch, see the SimpleExample328.ino sketch in the PinChangeInt 18 | // library distribution. 19 | 20 | #include 21 | 22 | // Modify these at your leisure. 23 | #define MYPIN1 A3 24 | #define MYPIN2 A4 25 | #define MYPIN3 A5 26 | 27 | // Don't change these. 28 | #define FIRST_ANALOG_PIN 14 29 | #define TOTAL_PINS 19 30 | // Notice that anything that gets modified inside an interrupt, that I wish to access 31 | // outside the interrupt, is marked "volatile". That tells the compiler not to optimize 32 | // them. 33 | volatile uint8_t latest_interrupted_pin; 34 | volatile uint8_t interrupt_count[TOTAL_PINS]={0}; // possible arduino pins 35 | volatile uint8_t pin3Count=0; 36 | 37 | // Do not use any Serial.print() in interrupt subroutines. Serial.print() uses interrupts, 38 | // and by default interrupts are off in interrupt subroutines. 39 | // Here we update a counter corresponding to whichever pin interrupted. 40 | void quicfunc0() { 41 | interrupt_count[MYPIN1]++; 42 | }; 43 | 44 | void quicfunc1() { 45 | interrupt_count[MYPIN2]++; 46 | }; 47 | 48 | // You can assign any number of functions to different pins. How cool is that? 49 | // Here we have a global variable that we increment. We can access this variable outside the interrupt, 50 | // and we know it will be valid because it was declared "volatile"- meaning, the compiler performs 51 | // no optimizations on it. 52 | void pin3func() { 53 | pin3Count++; 54 | } 55 | 56 | // Attach the interrupts in setup() 57 | void setup() { 58 | pinMode(MYPIN1, INPUT_PULLUP); 59 | attachPinChangeInterrupt(MYPIN1, quicfunc0, RISING); 60 | pinMode(MYPIN2, INPUT_PULLUP); 61 | attachPinChangeInterrupt(MYPIN2, quicfunc1, RISING); 62 | pinMode(MYPIN3, INPUT_PULLUP); 63 | attachPinChangeInterrupt(MYPIN3, pin3func, CHANGE); // Any state change will trigger the interrupt. 64 | Serial.begin(115200); 65 | Serial.println("---------------------------------------"); 66 | } 67 | 68 | uint8_t i; 69 | uint8_t currentPIN3Count=0; 70 | 71 | void loop() { 72 | uint8_t count; 73 | Serial.print("."); 74 | delay(1000); // every second, 75 | for (i=0; i < TOTAL_PINS; i++) { 76 | if (interrupt_count[i] != 0) { // look at all the interrupted pins 77 | count=interrupt_count[i]; // store its count since the last iteration 78 | interrupt_count[i]=0; // and reset it to 0 79 | Serial.print("Count for pin "); 80 | if (i < FIRST_ANALOG_PIN) { // then tell the user what it was, in a friendly way 81 | Serial.print("D"); 82 | Serial.print(i, DEC); 83 | } else { 84 | Serial.print("A"); 85 | Serial.print(i-FIRST_ANALOG_PIN, DEC); 86 | } 87 | Serial.print(" is "); 88 | Serial.println(count, DEC); 89 | } 90 | } 91 | if (currentPIN3Count != pin3Count) { // Print our monotonically increasing counter (no reset to 0). 92 | Serial.print("Third pin count update: "); Serial.print(pin3Count, DEC); Serial.println(); 93 | currentPIN3Count=pin3Count; 94 | } 95 | } 96 | 97 | -------------------------------------------------------------------------------- /libraries/PinChangeInt/Examples/SimpleExample328/SimpleExample328.ino: -------------------------------------------------------------------------------- 1 | // PinChangeInt SimpleExample sketch 2 | // See the Wiki at http://code.google.com/p/arduino-pinchangeint/wiki for more information. 3 | 4 | // for vim editing: :set et ts=2 sts=2 sw=2 et 5 | 6 | // This example demonstrates the use of the PinChangeInt library on a single pin of your choice. 7 | // This only works for ATMega328-compatibles; ie, Leonardo is not covered here. 8 | // To use: 9 | 10 | // 1. You must be using a fairly recent version of the Arduino IDE software on your PC/Mac, 11 | // that is, version 1.0.1 or later. Check Help->About Arduino in the IDE. 12 | 13 | // 2. Wire a simple switch to any Analog or Digital pin (known as ARDUINOPIN, defined below). 14 | // Attach the other end to a GND pin. A "single pole single throw momentary contact" 15 | // pushbutton switch is best for the best interrupting fun. 16 | 17 | // 3. When pressed, the switch will connect the pin to ground ("low", or "0") voltage, and interrupt the 18 | // processor. Don't let it confuse you that a switch press means the pin's voltage goes to 0; it 19 | // may seem more intuitive to apply a "1" or high voltage to the pin to represent "pressed". 20 | // But the processor is perfectly happy that we've made "0" equal "Pressed". The reason we've done so 21 | // is because we are using the "internal pullup resistor" feature of the processor... the chip gives 22 | // us a free resistor on every pin! 23 | // See http://arduino.cc/en/Tutorial/DigitalPins for a complete explanation. 24 | 25 | // 4. The interrupt is serviced immediately, and the ISR (Interrupt SubRoutine) sets the value of a global 26 | // variable. The sketch can then query the value at its leisure. This makes loop timing non-critical. 27 | // Open Tools->Serial Monitor in the IDE to see the results of your interrupts. 28 | 29 | // 5. See PinChangeIntExample328.ino (in the PinChangeInt distribution) for a more elaborate example. 30 | 31 | // 6. Create your own sketch using the PinChangeInt library! 32 | 33 | #include 34 | 35 | // Modify this at your leisure. 36 | #define ARDUINOPIN A4 37 | 38 | // Notice that values that get modified inside an interrupt, that I wish to access 39 | // outside the interrupt, are marked "volatile". It tells the compiler not to optimize 40 | // the variable. 41 | volatile uint16_t interruptCount=0; // The count will go back to 0 after hitting 65535. 42 | 43 | // Do not use any Serial.print() in interrupt subroutines. Serial.print() uses interrupts, 44 | // and by default interrupts are off in interrupt subroutines. Interrupt routines should also 45 | // be as fast as possible. Here we just increment a counter. 46 | void interruptFunction() { 47 | interruptCount++; 48 | } 49 | 50 | // Attach the interrupt in setup() 51 | void setup() { 52 | pinMode(ARDUINOPIN, INPUT_PULLUP); // Configure the pin as an input, and turn on the pullup resistor. 53 | // See http://arduino.cc/en/Tutorial/DigitalPins 54 | attachPinChangeInterrupt(ARDUINOPIN, interruptFunction, FALLING); 55 | Serial.begin(115200); 56 | Serial.println("---------------------------------------"); 57 | } 58 | 59 | // In the loop, we just check to see where the interrupt count is at. The value gets updated by the 60 | // interrupt routine. 61 | void loop() { 62 | delay(1000); // Every second, 63 | Serial.print("Pin was interrupted: "); 64 | Serial.print(interruptCount, DEC); // print the interrupt count. 65 | Serial.println(" times so far."); 66 | } 67 | -------------------------------------------------------------------------------- /libraries/PinChangeInt/NOTICE: -------------------------------------------------------------------------------- 1 | NOTICE 2 | PinChangeInt Arduino Library 3 | Copyright 2008 Chris J. Kiick 4 | Copyright 2009-2011 Lex Talionis 5 | Copyright 2010-2014 Michael Schwager (aka "GreyGnome") 6 | 7 | This product includes software developed by Chris J. Kiick, Lex Talionis, 8 | and Mike Schwager (aka, 'GreyGnome'). 9 | 10 | This library was inspired by and derived from Chris J. Kiick's PCInt Arduino 11 | Playground example here: http://www.arduino.cc/playground/Main/PcInt 12 | 13 | Lex Talionis picked it up, refined it, and created a Google Code page for 14 | it, found here: http://code.google.com/p/arduino-pinchangeint/ 15 | 16 | GreyGnome is the current maintainer, and would like to thank all those 17 | Open Source coders, the Arduino makers and community, and especially Chris 18 | and Lex for lighting the flame and showing the way! And a big thank you to 19 | the users who have contributed comments and bug fixes along the way. 20 | Without you this project would not have overcome some significant hurdles. 21 | A more complete list can be found in the README file. 22 | 23 | A HUGE thanks to Jan Baeyens ("jantje"), who has graciously DONATED an 24 | Arduino Mega ADK board to the PinChangeInt project!!! Wow, thanks Jan! 25 | This makes the 2560-based Arduino Mega a first class supported platform- 26 | I will be able to test it and verify that it works. 27 | 28 | -------------------------------------------------------------------------------- /libraries/PinChangeInt/Technical_Notes: -------------------------------------------------------------------------------- 1 | The purpose of this library is to give the programmer the ability to add interrupts 2 | with the easy of attachInterrupt, which looks like this: 3 | attachInterrupt(interrupt, &function, MODE) 4 | ...the interrupt is a number which gets translated to the proper pin on the Arduino. For example, 5 | Board int.0 int.1 int.2 int.3 int.4 int.5 6 | Uno, Ethernet 2 3 7 | Mega2560 2 3 21 20 19 18 8 | Leonardo 3 2 0 1 7 9 | Due (doesn't use interrupt numbers, it uses the pin numbers directly) 10 | 11 | The MODE is LOW, CHANGE, RISING, or FALLING. On the Due board, you also have HIGH. 12 | 13 | 14 | The PinChangeInterrupt library does not work on the Due; it is not necessary. It is somewhat easier 15 | to use than attachInterrupt() because you don't have to translate from an "Interrupt number" to a 16 | pin number- you simply give it the pin that you want to Interrupt on: 17 | 18 | PCintPort::attachInterrupt(interrupt, &function, MODE) 19 | 20 | The MODE is LOW, CHANGE, RISING, or FALLING. On the Due board, you also have HIGH. 21 | 22 | To have an Interrupt: 23 | 24 | Global Interrupt flag must be enabled. 25 | Set the I-bit in SREG. 26 | In PCICR: bit 2 == PCIE2: set, enable pins PCINT[23:16], enable individual by PCMSK2 27 | bit 1 == PCIE1: set, enable PCINT[14:8], enable individual by PCMSK1 28 | bit 0 == PCIE0: set, enable PCINT[7:0], enable individual by PCMSK0 29 | 30 | Pin Change Interrupts and Other Libraries ============================================================ 31 | 32 | Serial.print()---------------- 33 | 34 | Serial.print() does not work well inside interrupts. This is because it uses interrupts, 35 | and while you are in an interrupt, interrupts are (by default) turned off. 36 | Serial is declared in /usr/share/arduino/hardware/arduino/cores/arduino/HardwareSerial.h . 37 | In the write() method in the .cpp file, for example it says: 38 | ... 39 | // If the output buffer is full, there's nothing for it other than to 40 | // wait for the interrupt handler to empty it a bit 41 | // ???: return 0 here instead? 42 | while (i == _tx_buffer->tail) 43 | ; 44 | ... 45 | And the ISR is further down in that file (this for the ATmega328 I believe): 46 | ISR(USART_RX_vect) 47 | ... 48 | 49 | If a user wants to try to use Serial.print() inside an ISR, I believe it's possible 50 | (by turning on interrupts inside the interrupt)... 51 | but it would require them to be aware of any possible contention between the interrupts, 52 | and the print ISRs. 53 | 54 | 55 | Software Serial---------- 56 | The SoftwareSerial library defines ISRs for Pin Change Interrupt ports: 57 | 58 | ISR(PCINT0_vect) 59 | { 60 | SoftwareSerial::handle_interrupt(); 61 | } 62 | 63 | ...It defines the interrupt on all ports, whether it's using them or not 64 | (the library cannot know ahead of time if the user will be using a set of pins 65 | or not). 66 | 67 | To ensure compatibility with the SoftwareSerial library, the user should comment 68 | out the ports that they are NOT using with the SoftwareSerial library, in 69 | /usr/share/arduino/libraries/SoftwareSerial/SoftwareSerial.cpp 70 | and comment out the ports that they ARE using with this library in PinChangeInt.h 71 | -------------------------------------------------------------------------------- /libraries/PinChangeInt/keywords.txt: -------------------------------------------------------------------------------- 1 | # LITERAL1 specifies constants 2 | 3 | # KEYWORD1 specifies datatypes and C/C++ keywords 4 | pinState KEYWORD1 PinState 5 | arduinoPin KEYWORD1 ArduinoPin 6 | PCintPort KEYWORD1 PCInterruptPort 7 | 8 | # KEYWORD2 specifies methods and functions 9 | attachInterrupt KEYWORD2 AttachInterrupt 10 | detachInterrupt KEYWORD2 DetachInterrupt 11 | -------------------------------------------------------------------------------- /libraries/SSD1306/SSD1306.h: -------------------------------------------------------------------------------- 1 | #if ARDUINO >= 100 2 | #include "Arduino.h" 3 | // #else 4 | // #include "WProgram.h" 5 | #endif 6 | 7 | #define swap(a, b) { uint8_t t = a; a = b; b = t; } 8 | 9 | #define BLACK 0 10 | #define WHITE 1 11 | 12 | /*========================================================================= 13 | SSD1306 Displays 14 | ----------------------------------------------------------------------- 15 | The driver is used in multiple displays (128x64, 128x32, etc.). 16 | Select the appropriate display below to create an appropriately 17 | sized framebuffer, etc. 18 | 19 | SSD1306_128_64 128x64 pixel display 20 | 21 | SSD1306_128_32 128x32 pixel display 22 | 23 | You also need to set the LCDWIDTH and LCDHEIGHT defines to an 24 | appropriate size 25 | 26 | -----------------------------------------------------------------------*/ 27 | #define SSD1306_128_64 28 | // #define SSD1306_128_32 29 | /*=========================================================================*/ 30 | 31 | #if defined SSD1306_128_64 && defined SSD1306_128_32 32 | #error "Only one SSD1306 display can be specified at once in SSD1306.h" 33 | #endif 34 | #if !defined SSD1306_128_64 && !defined SSD1306_128_32 35 | #error "At least one SSD1306 display must be specified in SSD1306.h" 36 | #endif 37 | 38 | #if defined SSD1306_128_64 39 | #define SSD1306_LCDWIDTH 128 40 | #define SSD1306_LCDHEIGHT 64 41 | #endif 42 | #if defined SSD1306_128_32 43 | #define SSD1306_LCDWIDTH 128 44 | #define SSD1306_LCDHEIGHT 32 45 | #endif 46 | 47 | #define SSD1306_SETCONTRAST 0x81 48 | #define SSD1306_DISPLAYALLON_RESUME 0xA4 49 | #define SSD1306_DISPLAYALLON 0xA5 50 | #define SSD1306_NORMALDISPLAY 0xA6 51 | #define SSD1306_INVERTDISPLAY 0xA7 52 | #define SSD1306_DISPLAYOFF 0xAE 53 | #define SSD1306_DISPLAYON 0xAF 54 | 55 | #define SSD1306_SETDISPLAYOFFSET 0xD3 56 | #define SSD1306_SETCOMPINS 0xDA 57 | 58 | #define SSD1306_SETVCOMDETECT 0xDB 59 | 60 | #define SSD1306_SETDISPLAYCLOCKDIV 0xD5 61 | #define SSD1306_SETPRECHARGE 0xD9 62 | 63 | #define SSD1306_SETMULTIPLEX 0xA8 64 | 65 | #define SSD1306_SETLOWCOLUMN 0x00 66 | #define SSD1306_SETHIGHCOLUMN 0x10 67 | 68 | #define SSD1306_SETSTARTLINE 0x40 69 | 70 | #define SSD1306_MEMORYMODE 0x20 71 | 72 | #define SSD1306_COMSCANINC 0xC0 73 | #define SSD1306_COMSCANDEC 0xC8 74 | 75 | #define SSD1306_SEGREMAP 0xA0 76 | 77 | #define SSD1306_CHARGEPUMP 0x8D 78 | 79 | #define SSD1306_EXTERNALVCC 0x1 80 | #define SSD1306_SWITCHCAPVCC 0x2 81 | 82 | class SSD1306 { 83 | public: 84 | SSD1306(int8_t SID, int8_t SCLK, int8_t DC, int8_t RST, int8_t CS) :sid(SID), sclk(SCLK), dc(DC), rst(RST), cs(CS) {} 85 | SSD1306(int8_t SID, int8_t SCLK, int8_t DC, int8_t RST) :sid(SID), sclk(SCLK), dc(DC), rst(RST), cs(-1) {} 86 | 87 | 88 | void ssd1306_init(uint8_t switchvcc); 89 | void ssd1306_command(uint8_t c); 90 | void ssd1306_data(uint8_t c); 91 | void ssd1306_set_brightness(uint8_t val); 92 | void clear_display(void); 93 | void clear(); 94 | void invert(uint8_t i); 95 | void display(); 96 | 97 | void setpixel(uint8_t x, uint8_t y, uint8_t color); 98 | void fillcircle(uint8_t x0, uint8_t y0, uint8_t r, 99 | uint8_t color); 100 | void drawcircle(uint8_t x0, uint8_t y0, uint8_t r, 101 | uint8_t color); 102 | void drawrect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, 103 | uint8_t color); 104 | void fillrect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, 105 | uint8_t color); 106 | void drawline(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, 107 | uint8_t color); 108 | void drawchar(uint8_t x, uint8_t line, uint8_t c); 109 | void drawstring(uint8_t x, uint8_t line, char *c); 110 | 111 | void drawbitmap(uint8_t x, uint8_t y, 112 | const uint8_t *bitmap, uint8_t w, uint8_t h, 113 | uint8_t color); 114 | 115 | private: 116 | int8_t sid, sclk, dc, rst, cs; 117 | void spiwrite(uint8_t c); 118 | 119 | //uint8_t buffer[128*64/8]; 120 | }; 121 | -------------------------------------------------------------------------------- /libraries/Servo/README.adoc: -------------------------------------------------------------------------------- 1 | = Servo Library for Arduino = 2 | 3 | This library allows an Arduino board to control RC (hobby) servo motors. 4 | 5 | For more information about this library please visit us at 6 | http://www.arduino.cc/en/Reference/Servo 7 | 8 | == License == 9 | 10 | Copyright (c) 2013 Arduino LLC. All right reserved. 11 | Copyright (c) 2009 Michael Margolis. All right reserved. 12 | 13 | This library is free software; you can redistribute it and/or 14 | modify it under the terms of the GNU Lesser General Public 15 | License as published by the Free Software Foundation; either 16 | version 2.1 of the License, or (at your option) any later version. 17 | 18 | This library is distributed in the hope that it will be useful, 19 | but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | Lesser General Public License for more details. 22 | 23 | You should have received a copy of the GNU Lesser General Public 24 | License along with this library; if not, write to the Free Software 25 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 26 | -------------------------------------------------------------------------------- /libraries/Servo/examples/Knob/Knob.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Controlling a servo position using a potentiometer (variable resistor) 3 | by Michal Rinott 4 | 5 | modified on 8 Nov 2013 6 | by Scott Fitzgerald 7 | http://www.arduino.cc/en/Tutorial/Knob 8 | */ 9 | 10 | #include 11 | 12 | Servo myservo; // create servo object to control a servo 13 | 14 | int potpin = 0; // analog pin used to connect the potentiometer 15 | int val; // variable to read the value from the analog pin 16 | 17 | void setup() { 18 | myservo.attach(9); // attaches the servo on pin 9 to the servo object 19 | } 20 | 21 | void loop() { 22 | val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023) 23 | val = map(val, 0, 1023, 0, 180); // scale it to use it with the servo (value between 0 and 180) 24 | myservo.write(val); // sets the servo position according to the scaled value 25 | delay(15); // waits for the servo to get there 26 | } 27 | 28 | -------------------------------------------------------------------------------- /libraries/Servo/examples/Sweep/Sweep.ino: -------------------------------------------------------------------------------- 1 | /* Sweep 2 | by BARRAGAN 3 | This example code is in the public domain. 4 | 5 | modified 8 Nov 2013 6 | by Scott Fitzgerald 7 | http://www.arduino.cc/en/Tutorial/Sweep 8 | */ 9 | 10 | #include 11 | 12 | Servo myservo; // create servo object to control a servo 13 | // twelve servo objects can be created on most boards 14 | 15 | int pos = 0; // variable to store the servo position 16 | 17 | void setup() { 18 | myservo.attach(9); // attaches the servo on pin 9 to the servo object 19 | } 20 | 21 | void loop() { 22 | for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees 23 | // in steps of 1 degree 24 | myservo.write(pos); // tell servo to go to position in variable 'pos' 25 | delay(15); // waits 15ms for the servo to reach the position 26 | } 27 | for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees 28 | myservo.write(pos); // tell servo to go to position in variable 'pos' 29 | delay(15); // waits 15ms for the servo to reach the position 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /libraries/Servo/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map Servo 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | Servo KEYWORD1 Servo 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | attach KEYWORD2 15 | detach KEYWORD2 16 | write KEYWORD2 17 | read KEYWORD2 18 | attached KEYWORD2 19 | writeMicroseconds KEYWORD2 20 | readMicroseconds KEYWORD2 21 | 22 | ####################################### 23 | # Constants (LITERAL1) 24 | ####################################### 25 | -------------------------------------------------------------------------------- /libraries/Servo/library.properties: -------------------------------------------------------------------------------- 1 | name=Servo 2 | version=1.1.5 3 | author=Michael Margolis, Arduino 4 | maintainer=Arduino 5 | sentence=Allows Arduino/Genuino boards to control a variety of servo motors. 6 | paragraph=This library can control a great number of servos.
It makes careful use of timers: the library can control 12 servos using only 1 timer.
On the Arduino Due you can control up to 60 servos.
7 | category=Device Control 8 | url=http://www.arduino.cc/en/Reference/Servo 9 | architectures=avr,megaavr,sam,samd,nrf52,stm32f4 10 | -------------------------------------------------------------------------------- /libraries/Servo/src/avr/ServoTimers.h: -------------------------------------------------------------------------------- 1 | /* 2 | Servo.h - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2 3 | Copyright (c) 2009 Michael Margolis. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | /* 21 | * Defines for 16 bit timers used with Servo library 22 | * 23 | * If _useTimerX is defined then TimerX is a 16 bit timer on the current board 24 | * timer16_Sequence_t enumerates the sequence that the timers should be allocated 25 | * _Nbr_16timers indicates how many 16 bit timers are available. 26 | */ 27 | 28 | /** 29 | * AVR Only definitions 30 | * -------------------- 31 | */ 32 | 33 | // Say which 16 bit timers can be used and in what order 34 | #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 35 | #define _useTimer5 36 | #define _useTimer1 37 | #define _useTimer3 38 | #define _useTimer4 39 | typedef enum { _timer5, _timer1, _timer3, _timer4, _Nbr_16timers } timer16_Sequence_t; 40 | 41 | #elif defined(__AVR_ATmega32U4__) 42 | #define _useTimer1 43 | typedef enum { _timer1, _Nbr_16timers } timer16_Sequence_t; 44 | 45 | #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) 46 | #define _useTimer3 47 | #define _useTimer1 48 | typedef enum { _timer3, _timer1, _Nbr_16timers } timer16_Sequence_t; 49 | 50 | #elif defined(__AVR_ATmega128__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega2561__) 51 | #define _useTimer3 52 | #define _useTimer1 53 | typedef enum { _timer3, _timer1, _Nbr_16timers } timer16_Sequence_t; 54 | 55 | #else // everything else 56 | #define _useTimer1 57 | typedef enum { _timer1, _Nbr_16timers } timer16_Sequence_t; 58 | #endif 59 | 60 | -------------------------------------------------------------------------------- /libraries/Servo/src/megaavr/ServoTimers.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018 Arduino LLC. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | /* 20 | * Defines for 16 bit timers used with Servo library 21 | * 22 | */ 23 | 24 | #ifndef __SERVO_TIMERS_H__ 25 | #define __SERVO_TIMERS_H__ 26 | 27 | #include 28 | 29 | //#define USE_TIMERB1 // interferes with PWM on pin 3 30 | #define USE_TIMERB2 // interferes with PWM on pin 11 31 | //#define USE_TIMERB0 // interferes with PWM on pin 6 32 | 33 | #if !defined(USE_TIMERB1) && !defined(USE_TIMERB2) && !defined(USE_TIMERB0) 34 | # error "No timers allowed for Servo" 35 | /* Please uncomment a timer above and rebuild */ 36 | #endif 37 | 38 | static volatile TCB_t* _timer = 39 | #if defined(USE_TIMERB0) 40 | &TCB0; 41 | #endif 42 | #if defined(USE_TIMERB1) 43 | &TCB1; 44 | #endif 45 | #if defined(USE_TIMERB2) 46 | &TCB2; 47 | #endif 48 | 49 | typedef enum { 50 | timer0, 51 | _Nbr_16timers } timer16_Sequence_t; 52 | 53 | 54 | #endif /* __SERVO_TIMERS_H__ */ 55 | -------------------------------------------------------------------------------- /libraries/Servo/src/nrf52/Servo.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 Arduino. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #if defined(ARDUINO_ARCH_NRF52) 20 | 21 | #include 22 | #include 23 | 24 | 25 | static servo_t servos[MAX_SERVOS]; // static array of servo structures 26 | 27 | uint8_t ServoCount = 0; // the total number of attached servos 28 | 29 | 30 | 31 | uint32_t group_pins[3][NRF_PWM_CHANNEL_COUNT]={{NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED}, {NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED}, {NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED}}; 32 | static uint16_t seq_values[3][NRF_PWM_CHANNEL_COUNT]={{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}; 33 | 34 | Servo::Servo() 35 | { 36 | if (ServoCount < MAX_SERVOS) { 37 | this->servoIndex = ServoCount++; // assign a servo index to this instance 38 | } else { 39 | this->servoIndex = INVALID_SERVO; // too many servos 40 | } 41 | 42 | } 43 | 44 | uint8_t Servo::attach(int pin) 45 | { 46 | 47 | return this->attach(pin, 0, 2500); 48 | } 49 | 50 | 51 | uint8_t Servo::attach(int pin, int min, int max) 52 | { 53 | int servo_min, servo_max; 54 | if (this->servoIndex < MAX_SERVOS) { 55 | pinMode(pin, OUTPUT); // set servo pin to output 56 | servos[this->servoIndex].Pin.nbr = pin; 57 | 58 | if(min < servo_min) min = servo_min; 59 | if (max > servo_max) max = servo_max; 60 | this->min = min; 61 | this->max = max; 62 | 63 | servos[this->servoIndex].Pin.isActive = true; 64 | 65 | } 66 | return this->servoIndex; 67 | } 68 | 69 | void Servo::detach() 70 | { 71 | servos[this->servoIndex].Pin.isActive = false; 72 | } 73 | 74 | 75 | void Servo::write(int value) 76 | { 77 | if (value < 0) 78 | value = 0; 79 | else if (value > 180) 80 | value = 180; 81 | value = map(value, 0, 180, MIN_PULSE, MAX_PULSE); 82 | 83 | writeMicroseconds(value); 84 | } 85 | 86 | 87 | void Servo::writeMicroseconds(int value) 88 | { 89 | uint8_t channel, instance; 90 | uint8_t pin = servos[this->servoIndex].Pin.nbr; 91 | //instance of pwm module is MSB - look at VWariant.h 92 | instance=(g_APinDescription[pin].ulPWMChannel & 0xF0)/16; 93 | //index of pwm channel is LSB - look at VWariant.h 94 | channel=g_APinDescription[pin].ulPWMChannel & 0x0F; 95 | group_pins[instance][channel]=g_APinDescription[pin].ulPin; 96 | NRF_PWM_Type * PWMInstance = instance == 0 ? NRF_PWM0 : (instance == 1 ? NRF_PWM1 : NRF_PWM2); 97 | //configure pwm instance and enable it 98 | seq_values[instance][channel]= value | 0x8000; 99 | nrf_pwm_sequence_t const seq={ 100 | seq_values[instance], 101 | NRF_PWM_VALUES_LENGTH(seq_values), 102 | 0, 103 | 0 104 | }; 105 | nrf_pwm_pins_set(PWMInstance, group_pins[instance]); 106 | nrf_pwm_enable(PWMInstance); 107 | nrf_pwm_configure(PWMInstance, NRF_PWM_CLK_125kHz, NRF_PWM_MODE_UP, 2500); // 20ms - 50Hz 108 | nrf_pwm_decoder_set(PWMInstance, NRF_PWM_LOAD_INDIVIDUAL, NRF_PWM_STEP_AUTO); 109 | nrf_pwm_sequence_set(PWMInstance, 0, &seq); 110 | nrf_pwm_loop_set(PWMInstance, 0UL); 111 | nrf_pwm_task_trigger(PWMInstance, NRF_PWM_TASK_SEQSTART0); 112 | } 113 | 114 | int Servo::read() // return the value as degrees 115 | { 116 | return map(readMicroseconds(), MIN_PULSE, MAX_PULSE, 0, 180); 117 | } 118 | 119 | int Servo::readMicroseconds() 120 | { 121 | uint8_t channel, instance; 122 | uint8_t pin=servos[this->servoIndex].Pin.nbr; 123 | instance=(g_APinDescription[pin].ulPWMChannel & 0xF0)/16; 124 | channel=g_APinDescription[pin].ulPWMChannel & 0x0F; 125 | // remove the 16th bit we added before 126 | return seq_values[instance][channel] & 0x7FFF; 127 | } 128 | 129 | bool Servo::attached() 130 | { 131 | return servos[this->servoIndex].Pin.isActive; 132 | } 133 | 134 | #endif // ARDUINO_ARCH_NRF52 -------------------------------------------------------------------------------- /libraries/Servo/src/nrf52/ServoTimers.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 Arduino. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | /* 20 | * NRF52 doesn't use timer, but pwm. This file include definitions to keep 21 | * compatibility with the Servo library standards. 22 | */ 23 | 24 | #ifndef __SERVO_TIMERS_H__ 25 | #define __SERVO_TIMERS_H__ 26 | 27 | /** 28 | * NRF52 Only definitions 29 | * --------------------- 30 | */ 31 | 32 | #define MIN_PULSE 55 33 | #define MAX_PULSE 284 34 | 35 | // define one timer in order to have MAX_SERVOS = 12 36 | typedef enum { _timer1, _Nbr_16timers } timer16_Sequence_t; 37 | 38 | #endif // __SERVO_TIMERS_H__ -------------------------------------------------------------------------------- /libraries/Servo/src/sam/ServoTimers.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 Arduino LLC. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | /* 20 | * Defines for 16 bit timers used with Servo library 21 | * 22 | * If _useTimerX is defined then TimerX is a 16 bit timer on the current board 23 | * timer16_Sequence_t enumerates the sequence that the timers should be allocated 24 | * _Nbr_16timers indicates how many 16 bit timers are available. 25 | */ 26 | 27 | /** 28 | * SAM Only definitions 29 | * -------------------- 30 | */ 31 | 32 | // For SAM3X: 33 | #define _useTimer1 34 | #define _useTimer2 35 | #define _useTimer3 36 | #define _useTimer4 37 | #define _useTimer5 38 | 39 | /* 40 | TC0, chan 0 => TC0_Handler 41 | TC0, chan 1 => TC1_Handler 42 | TC0, chan 2 => TC2_Handler 43 | TC1, chan 0 => TC3_Handler 44 | TC1, chan 1 => TC4_Handler 45 | TC1, chan 2 => TC5_Handler 46 | TC2, chan 0 => TC6_Handler 47 | TC2, chan 1 => TC7_Handler 48 | TC2, chan 2 => TC8_Handler 49 | */ 50 | 51 | #if defined (_useTimer1) 52 | #define TC_FOR_TIMER1 TC1 53 | #define CHANNEL_FOR_TIMER1 0 54 | #define ID_TC_FOR_TIMER1 ID_TC3 55 | #define IRQn_FOR_TIMER1 TC3_IRQn 56 | #define HANDLER_FOR_TIMER1 TC3_Handler 57 | #endif 58 | #if defined (_useTimer2) 59 | #define TC_FOR_TIMER2 TC1 60 | #define CHANNEL_FOR_TIMER2 1 61 | #define ID_TC_FOR_TIMER2 ID_TC4 62 | #define IRQn_FOR_TIMER2 TC4_IRQn 63 | #define HANDLER_FOR_TIMER2 TC4_Handler 64 | #endif 65 | #if defined (_useTimer3) 66 | #define TC_FOR_TIMER3 TC1 67 | #define CHANNEL_FOR_TIMER3 2 68 | #define ID_TC_FOR_TIMER3 ID_TC5 69 | #define IRQn_FOR_TIMER3 TC5_IRQn 70 | #define HANDLER_FOR_TIMER3 TC5_Handler 71 | #endif 72 | #if defined (_useTimer4) 73 | #define TC_FOR_TIMER4 TC0 74 | #define CHANNEL_FOR_TIMER4 2 75 | #define ID_TC_FOR_TIMER4 ID_TC2 76 | #define IRQn_FOR_TIMER4 TC2_IRQn 77 | #define HANDLER_FOR_TIMER4 TC2_Handler 78 | #endif 79 | #if defined (_useTimer5) 80 | #define TC_FOR_TIMER5 TC0 81 | #define CHANNEL_FOR_TIMER5 0 82 | #define ID_TC_FOR_TIMER5 ID_TC0 83 | #define IRQn_FOR_TIMER5 TC0_IRQn 84 | #define HANDLER_FOR_TIMER5 TC0_Handler 85 | #endif 86 | 87 | typedef enum { _timer1, _timer2, _timer3, _timer4, _timer5, _Nbr_16timers } timer16_Sequence_t ; 88 | 89 | -------------------------------------------------------------------------------- /libraries/Servo/src/samd/ServoTimers.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Arduino LLC. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | /* 20 | * Defines for 16 bit timers used with Servo library 21 | * 22 | * If _useTimerX is defined then TimerX is a 16 bit timer on the current board 23 | * timer16_Sequence_t enumerates the sequence that the timers should be allocated 24 | * _Nbr_16timers indicates how many 16 bit timers are available. 25 | */ 26 | 27 | #ifndef __SERVO_TIMERS_H__ 28 | #define __SERVO_TIMERS_H__ 29 | 30 | /** 31 | * SAMD Only definitions 32 | * --------------------- 33 | */ 34 | 35 | // For SAMD: 36 | #define _useTimer1 37 | //#define _useTimer2 // <- TODO do not activate until the code in Servo.cpp has been changed in order 38 | // to manage more than one channel per timer on the SAMD architecture 39 | 40 | #if defined (_useTimer1) 41 | #define TC_FOR_TIMER1 TC4 42 | #define CHANNEL_FOR_TIMER1 0 43 | #define INTENSET_BIT_FOR_TIMER_1 TC_INTENSET_MC0 44 | #define INTENCLR_BIT_FOR_TIMER_1 TC_INTENCLR_MC0 45 | #define INTFLAG_BIT_FOR_TIMER_1 TC_INTFLAG_MC0 46 | #define ID_TC_FOR_TIMER1 ID_TC4 47 | #define IRQn_FOR_TIMER1 TC4_IRQn 48 | #define HANDLER_FOR_TIMER1 TC4_Handler 49 | #define GCM_FOR_TIMER_1 GCM_TC4_TC5 50 | #endif 51 | #if defined (_useTimer2) 52 | #define TC_FOR_TIMER2 TC4 53 | #define CHANNEL_FOR_TIMER2 1 54 | #define INTENSET_BIT_FOR_TIMER_2 TC_INTENSET_MC1 55 | #define INTENCLR_BIT_FOR_TIMER_2 TC_INTENCLR_MC1 56 | #define ID_TC_FOR_TIMER2 ID_TC4 57 | #define IRQn_FOR_TIMER2 TC4_IRQn 58 | #define HANDLER_FOR_TIMER2 TC4_Handler 59 | #define GCM_FOR_TIMER_2 GCM_TC4_TC5 60 | #endif 61 | 62 | typedef enum { 63 | #if defined (_useTimer1) 64 | _timer1, 65 | #endif 66 | #if defined (_useTimer2) 67 | _timer2, 68 | #endif 69 | _Nbr_16timers } timer16_Sequence_t; 70 | 71 | #endif // __SERVO_TIMERS_H__ 72 | -------------------------------------------------------------------------------- /libraries/readme.txt: -------------------------------------------------------------------------------- 1 | 安装库的详细信息,请参阅:http://www.arduino.cc/en/Guide/Libraries 2 | --------------------------------------------------------------------------------