Add files via upload

This commit is contained in:
SeasonWings
2022-06-20 21:18:16 +08:00
committed by GitHub
parent 82e9d8cb6d
commit 5d21ceb208
12 changed files with 1136 additions and 0 deletions
@@ -0,0 +1,39 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the usual convention is to give header files names that end with `.h'.
It is most portable to use only letters, digits, dashes, and underscores in
header file names, and at most one dot.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
@@ -0,0 +1,46 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into executable file.
The source code of each library should be placed in a an own separate directory
("lib/your_library_name/[here are source files]").
For example, see a structure of the following two libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
and a contents of `src/main.c`:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
PlatformIO Library Dependency Finder will find automatically dependent
libraries scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html
@@ -0,0 +1,18 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:sparkfun_samd21_dev_usb]
platform = atmelsam
board = sparkfun_samd21_dev_usb
framework = arduino
lib_deps =
nicohood/HID-Project@^2.8.2
fastled/FastLED@^3.4.0
cmaglie/FlashStorage@^1.0.0
+177
View File
@@ -0,0 +1,177 @@
////基础定义////
#include "HID-Project.h"
#include "FastLED.h"
#include <Arduino.h>
#define Serial SerialUSB
////Air定义////
int calibrationCounter;
bool calibrated;
uint16_t thresholds[6];
uint16_t maxReadings[6];
#define AIR_LED_DELAY 96//轮询延迟
#define AIR_INPUT_SENSITIVITY 0.3//红外敏感度
#define CALIBRATION_SAMPLES 256//校准采样数
#define SKIP_SAMPLES 256//校准跳过采样数
int ir_input_pins[6] = {3,4,5,2,6,11};//定义轮询发射红外针脚
int ir_sensor_pins[6] = {A0,A1,A2,A3,A4,A5};//定义轮询接收红外针脚
////按键定义////
KeyboardKeycode AirKeys[6] = {KEY_SLASH, KEY_PERIOD, KEY_QUOTE, KEY_SEMICOLON, KEY_RIGHT_BRACE, KEY_LEFT_BRACE};
uint8_t AirState[6];
////灯光定义////
#define air_right_pin 8 //R灯引脚
#define air_right_num 6 //R灯数量
CRGB AIR_RIGHT[air_right_num];
#define air_left_pin 10 //L灯引脚
#define air_left_num 6 //L灯数量
CRGB AIR_LEFT[air_left_num];
uint8_t colorIndex;
void CloudboardAirLED(){//键盘Air灯效1
colorIndex++;
fill_palette(AIR_LEFT, 6 , colorIndex, 5, CloudColors_p, 100, LINEARBLEND);
fill_palette(AIR_RIGHT, 6 , colorIndex, 5, CloudColors_p, 100, LINEARBLEND);
for (uint8_t i = 0; i < 6; i++) {
if (AirState[i]) {
AIR_RIGHT[i] = CRGB::White;
AIR_LEFT[i] = CRGB::White;
}
FastLED[1].show(AIR_RIGHT,6, 150);
FastLED[2].show(AIR_LEFT,6, 150);
}
}
//////////Air//////////
void AirSetup() {
calibrated = false;
for (int i = 0; i < 6; i++) {
maxReadings[i] = 0;
}
for (int i = 0; i < 6; i++) {
pinMode(ir_sensor_pins[i], INPUT_PULLUP);
pinMode(ir_input_pins[i], OUTPUT);
AirState[i] = 0;
}
}
void turnOffLight() {//关闭发射函数
for(int i = 0;i < 6;i++){
digitalWrite(ir_input_pins[i], LOW);
}
}
void changeLight(int light) {//红外发射轮询
switch (light) {
case 0:
digitalWrite(ir_input_pins[light], HIGH);//#1
break;
case 1:
digitalWrite(ir_input_pins[light], HIGH);//#2
break;
case 2:
digitalWrite(ir_input_pins[light], HIGH);//#3
break;
case 3:
digitalWrite(ir_input_pins[light], HIGH);//#4
break;
case 4:
digitalWrite(ir_input_pins[light], HIGH);//#5
break;
case 5:
digitalWrite(ir_input_pins[light], HIGH);//#6
break;
default:
turnOffLight();
break;
}
}
uint16_t getValue(int sensor) {//获取开灯数值函数
changeLight(sensor);// 开灯
delayMicroseconds(AIR_LED_DELAY/2);// 加上延迟保证完全开启
return analogRead(ir_sensor_pins[sensor]);//读数值
}
bool getSensorState(int sensor) {//返回Air状态
turnOffLight();//关灯
delayMicroseconds(AIR_LED_DELAY/2);//加上延迟保证完全关闭
int enviroment = analogRead(ir_sensor_pins[sensor]);//读取环境数值
int value = getValue(sensor);//读取开灯数值
//调试AIR用输出
// Serial.print(sensor);
// Serial.print("\t");
// Serial.print(value);
// Serial.print("\t");
// Serial.print(enviroment);
// Serial.print("\t");
// Serial.print(value - enviroment);
// Serial.print("\t");
// Serial.print(value - enviroment + 200);
// Serial.print("\t");
// Serial.print(maxReadings[sensor]);
// Serial.print("\t");
// Serial.print(thresholds[sensor]);
// Serial.println();
//把读数减去环境数值和校准数值比较后返回布尔值,+200为防止负数的比较
return (value - enviroment + 200) < (thresholds[sensor] + 200);
}
void AirCalibrate() {//校准接收端
// 跳过开头采样
for (int i = 0; i < SKIP_SAMPLES; i++) {
for (int sensor = 0; sensor < 6; sensor++) {
getValue(sensor);
turnOffLight();
}
}
//开始校准
for (int i = 0; i < CALIBRATION_SAMPLES; i++) {
for (int sensor = 0; sensor < 6; sensor++) {
turnOffLight();//关灯
delayMicroseconds(AIR_LED_DELAY/2);//加上延迟保证完全关闭
int enviroment = analogRead(ir_sensor_pins[sensor]);//读取环境数值
int value = getValue(sensor) - enviroment;//读取开灯数值
if (value > maxReadings[sensor])//记录最高读数
maxReadings[sensor] = value;
}
Serial.println();
}
for (int i = 0; i < 6; i++) {//通过敏感度生成阈值
thresholds[i] = (AIR_INPUT_SENSITIVITY * maxReadings[i]);
}
calibrated = true;//完成校准
}
void AirCheck(){
if (calibrated){
for (int i = 0; i < 6; i++){
if (getSensorState(i)){
NKROKeyboard.press(AirKeys[i]);
AirState[i] = 1;
} else if (!getSensorState(i)){
NKROKeyboard.release(AirKeys[i]);
AirState[i] = 0;
}
}
}
}
void NoAirCheck(){
if (calibrated){
for (int i = 0; i < 6; i++){
if (getSensorState(i)){
AirState[i] = 1;
} else if (!getSensorState(i)){
AirState[i] = 0;
}
}
}
}
+117
View File
@@ -0,0 +1,117 @@
////基础定义////
#include "mpr121-helper.h"
#include "mpr121-config.h"
#include "serial.h"
#include "HID-Project.h"
#include "FastLED.h"
#define Serial SerialUSB
////MPR定义////
#define CA_ADDR 0x5A//mpr121A
#define CB_ADDR 0x5B//mpr121B
#define CC_ADDR 0x5C//mpr121C
uint16_t LastA = -1, CurrA, LastB = -1, CurrB, LastC = -1, CurrC; //存储触摸的状态
static MPR121 capA, capB, capC; //mpr121定义
////串口定义////
#define CLAMP(val, lo, hi) (val < lo ? lo : (val > hi ? hi : val))
uint8_t checkrelease[32];
static bool auto_scan = false;//串口用标记
////按键定义////
KeyboardKeycode KeyCode[32] = {//键值列表
KEY_I, KEY_COMMA, KEY_8, KEY_K, KEY_U, KEY_M, KEY_7, KEY_J, KEY_Y, KEY_N,
KEY_6, KEY_H, KEY_T, KEY_B, KEY_5, KEY_G, KEY_R, KEY_V, KEY_4, KEY_F, KEY_E, KEY_C,
KEY_3, KEY_D, KEY_W, KEY_X, KEY_2, KEY_S, KEY_Q, KEY_Z, KEY_1, KEY_A,
};
////灯光定义////
uint16_t LED_BRI = 255; //灯亮度
#define LED_PIN 7 //灯针脚
#define LED_NUM 31 //灯数量
CRGB leds[LED_NUM];
uint32_t MiddleLED=CRGB::Black; //中缝灯色
uint32_t GroundLED=CRGB::Aqua; //触摸区常态灯色
uint32_t PressLED=CRGB::Red; //触摸时灯色
////函数指针////
void (*AirSensor)();
void (*AirLED)();
void (*TouchCheck)();
void (*TouchLEDCheck)();
void TouchSetup() {//触摸初始化
capA.begin(CA_ADDR);
capA.init();
capA.run();
capB.begin(CB_ADDR);
capB.init();
capB.run();
capC.begin(CC_ADDR);
capC.init();
capC.run();
Wire.setClock(800000);//I2C波特率
}
//直连触摸函数部分//
int CalCheck(int bl, int fd) {//触摸数值计算
int cal = bl - fd;
return cal > 4 ? 5 * cal : (cal > 0 ? cal : 0) ;
}
//键盘触摸函数部分//
uint8_t ledindex = 0;
uint8_t TouchState[32];
uint8_t val = 30;
void K32Check() {
int16_t bl, fl, cal, calpress[32];
for (uint8_t i = 0; i < 12; i++) {//计算数值
if (i < 10) {
bl = capA.baselineData(i);
fl = capA.filteredData(i);
cal = CalCheck(bl, fl);
calpress[i] = CLAMP(cal, 0, 255);
}
bl = capB.baselineData(i);
fl = capB.filteredData(i);
cal = CalCheck(bl, fl);
calpress[i + 10] = CLAMP(cal, 0, 255);
if (i < 10) {
bl = capC.baselineData(i);
fl = capC.filteredData(i);
cal = CalCheck(bl, fl);
calpress[i + 10 + 12] = CLAMP(cal, 0, 255);
}
}
for (uint8_t i = 0; i < 32; i++) {
uint8_t calkeypress = calpress[i];
Serial.println(calpress[i]);
if (ledindex <= 15) {//初始化完成后的灯
leds[31 - i * 2] = MiddleLED;
leds[30 - i * 2] = GroundLED;
FastLED[0].showLeds(255);
ledindex++;
}
if (calkeypress >= val) {//Check
checkrelease[i] = SLIDER_CMD_AUTO_SCAN;
NKROKeyboard.press(KeyCode[i]);
i%2==0?leds[i] = PressLED:leds[i-1] = PressLED;
}
else {
if (checkrelease[i]) {
checkrelease[i] = 0;
NKROKeyboard.release(KeyCode[i]);
i%2==0?leds[i] = GroundLED:leds[i-1] = GroundLED;
}
continue;
}
}
leds[7] = PressLED;
leds[15] = PressLED;
leds[23] = PressLED;
FastLED[0].showLeds(255);
}
@@ -0,0 +1,134 @@
#include "Touch.h"
#include "Air.h"
#define Serial SerialUSB
////核心函数////
static void slider_set_led() {//串口读取led数据
if (slider_tx_pending) {
return;
}
for (int i = 0; i < 31; i++) {//BRG
uint8_t t1 = i;
uint8_t t2 = i * 3;
leds[t1].r = slider_req.leds[t2 + 1];
leds[t1].g = slider_req.leds[t2 + 2];
leds[t1].b = slider_req.leds[t2 + 0];
}
FastLED[0].show(leds, LED_NUM, LED_BRI);
slider_req.cmd = 0;
}
static void slider_scan() {//直连触摸扫描
if (!auto_scan || slider_tx_pending) {//分支选择,非直连状态
TouchCheck();//各状态的触摸板检测
NoAirCheck();//无HID输入的Air
AirLED();
return;
}//分支选择,直连状态
slider_resp.syn = 0xff;
slider_resp.cmd = SLIDER_CMD_AUTO_SCAN;
slider_resp.size = sizeof(slider_resp.pressure);
int16_t bv, fd, clp;
for (int i = 0; i < 12; i++) {//直连触摸数值计算
if (i < 10) {
bv = capA.baselineData(i);
fd = capA.filteredData(i);
clp = CalCheck(bv, fd);
slider_resp.pressure[i] = CLAMP(clp, 0, 255);
}
bv = capB.baselineData(i);
fd = capB.filteredData(i);
clp = CalCheck(bv, fd);
slider_resp.pressure[i + 10] = CLAMP(clp, 0, 255);
if (i < 10) {
bv = capC.baselineData(i);
fd = capC.filteredData(i);
clp = CalCheck(bv, fd);
slider_resp.pressure[i + 10 + 12] = CLAMP(clp, 0, 255);
}
}
AirCheck();//有HID输入的Air
AirLED();
}
static void slider_scan_start() {//启动slider
auto_scan = true;
slider_scan();
}
static void slider_scan_stop() {//停止slider
auto_scan = false;
slider_resp.syn = 0xff;
slider_resp.cmd = SLIDER_CMD_AUTO_SCAN_STOP;
slider_resp.size = 0;
slider_req.cmd = 0;
}
static void slider_reset() {//重置slider,重新初始化触摸
capA.init();
capA.run();
capB.init();
capB.run();
capC.init();
capC.run();
slider_resp.syn = 0xff;
slider_resp.cmd = SLIDER_CMD_RESET;
slider_resp.size = 0;
slider_req.cmd = 0;
}
static void slider_get_board_info() {//返回版本信息,勿修改
slider_resp.syn = 0xff;
slider_resp.cmd = SLIDER_CMD_GET_BOARD_INFO;
slider_resp.size = sizeof(slider_resp.version);
strcpy(slider_resp.version, "15330 \xA0""06712\xFF""\x90");
slider_req.cmd = 0;
}
void SerialCheck() {//串口模式的loop函数
switch (sliderserial_readreq()) {
case SLIDER_CMD_SET_LED:
slider_set_led();
break;
case SLIDER_CMD_AUTO_SCAN_START:
slider_scan_start();
break;
case SLIDER_CMD_AUTO_SCAN_STOP:
slider_scan_stop();
break;
case SLIDER_CMD_RESET:
slider_reset();
break;
case SLIDER_CMD_GET_BOARD_INFO:
slider_get_board_info();
break;
default:
slider_scan();
}
sliderserial_writeresp();
}
void LEDset() {//灯光初始化
FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, LED_NUM);
FastLED.addLeds<WS2812B, air_right_pin, GRB>(AIR_RIGHT, air_right_num);
FastLED.addLeds<WS2812B, air_left_pin, GRB>(AIR_LEFT, air_left_num);
}
////主进程函数////
void setup() {
//串口启动//
SerialUSB.begin(115200);
SerialUSB.setTimeout(0);
LEDset();//灯带添加
TouchSetup();//触摸启动
AirSetup();//Air启动
AirLED = CloudboardAirLED;
TouchCheck = K32Check;
AirCalibrate();//Air校准
}
void loop() {
SerialCheck();//主循环
}
@@ -0,0 +1,58 @@
#ifndef _MPR121_CONFIG_H
#define _MPR121_CONFIG_H
#include "mpr121-helper.h"
// Thresholds
#define MPR121CONF_TTH 6///< 触发阈值
#define MPR121CONF_RTH 3///< 释放阈值
// De-bounce
#define MPR121CONF_DR 3 ///< 松开样本采集数
#define MPR121CONF_DT 2 ///< 按下样本采集数
// AFE Configurations
#define MPR121CONF_FFI MPR121_FFI_6 ///< 一层过滤采样数
#define MPR121CONF_CDC 16 ///< 充放电电流
#define MPR121CONF_CDT MPR121_CDT_500NS ///< 充放电时间
#define MPR121CONF_SFI MPR121_SFI_4 ///< 二层过滤
#define MPR121CONF_ESI MPR121_ESI_1MS ///< 二层过滤采样间隔时间
// ECR Configurations
#define MPR121CONF_CL MPR121_CL_INIT1 ///< 启用基线动态校准
#define MPR121CONF_ELEPROX MPR121_ELEPROX_0 ///< 接近检测电极,禁用
#define MPR121CONF_ELE 12 ///< touch detection electrodes
// 基线动态校准
#define MPR121CONF_MHDR 1 ///< 上升最大变化值
#define MPR121CONF_NHDR 8 ///< 上升幅度
#define MPR121CONF_NCLR 1 ///< 上升修正样本个数
#define MPR121CONF_FDLR 0 ///< 修正前等待样本个数
#define MPR121CONF_MHDF 1 ///< 下降最大变化值
#define MPR121CONF_NHDF 1 ///< 下降幅度
#define MPR121CONF_NCLF 16 ///< 下降修正样本个数
#define MPR121CONF_FDLF 2 ///< 修正前等待样本个数
#define MPR121CONF_NHDT 0 ///< Touched Noise Half Delta
#define MPR121CONF_NCLT 0 ///< Touched Noise Count Limit
#define MPR121CONF_FDLT 0 ///< Touched Filter Delay Count Limit
// 自动初始化
// #define MPR121CONF_USL 200 ///< 上限,MPR121_UPLIMIT,((Vdd - 0.7)/Vdd) * 256,200
// #define MPR121CONF_LSL 130 ///< 下限,MPR121_LOWLIMIT,UPLIMIT * 0.65,130
// #define MPR121CONF_TL 180 ///< 目标,MPR121_TARGETLIMIT,UPLIMIT * 0.9,180
#define MPR121CONF_USL 156 ///< 上限,MPR121_UPLIMIT,((Vdd - 0.7)/Vdd) * 256
#define MPR121CONF_LSL 101 ///< 下限,MPR121_LOWLIMIT,UPLIMIT * 0.65
#define MPR121CONF_TL 140 ///< 目标,MPR121_TARGETLIMIT,UPLIMIT * 0.9
// #define MPR121CONF_USL 166 ///< 上限,MPR121_UPLIMIT,((Vdd - 0.7)/Vdd) * 256,200
// #define MPR121CONF_LSL 108 ///< 下限,MPR121_LOWLIMIT,UPLIMIT * 0.65,130
// #define MPR121CONF_TL 149 ///< 目标,MPR121_TARGETLIMIT,UPLIMIT * 0.9,180
#define MPR121CONF_AFES MPR121CONF_FFI ///< 必须设置为FFI
#define MPR121CONF_RETRY MPR121_RETRY_0 ///< 重试次数
#define MPR121CONF_BVA MPR121CONF_CL ///< 必须设置为CL
#define MPR121CONF_ARE 1 ///< 开启自动重配置
#define MPR121CONF_ACE 1 ///< 开启自动配置
#define MPR121CONF_SCTS 1 ///< 跳过充电时间
//中断用,全部关闭
#define MPR121CONF_ACFIE 0 ///< Auto-configuration fail interrupt enable
#define MPR121CONF_ARFIE 0 ///< Auto-reconfiguration fail interrupt enable
#define MPR121CONF_OORIE 0 ///< Out-of-range interrupt enable
#endif
@@ -0,0 +1,134 @@
/*
Support class for MPR121, giving full control over the device efficiently.
Modifications licensed under University of Illinois/NCSA Open Source License
Copyright (c) 2020 Fang Lu
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal with the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
- Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimers.
- Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimers in the documentation
and/or other materials provided with the distribution.
- Neither the names of Fang Lu, nor the names of its contributors may be
used to endorse or promote products derived from this Software without
specific prior written permission.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
WITH THE SOFTWARE.
Original license text from Adafruit
@file Adafruit_MPR121.cpp
This is a library for the MPR121 12-Channel Capacitive Sensor
Designed specifically to work with the MPR121 board.
Pick one up today in the adafruit shop!
------> https://www.adafruit.com/product/1982
These sensors use I2C to communicate, 2+ pins are required to interface
Adafruit invests time and resources providing this open source code,
please support Adafruit andopen-source hardware by purchasing products
from Adafruit!
Limor Fried/Ladyada (Adafruit Industries).
BSD license, all text above must be included in any redistribution
*/
#include "mpr121-helper.h"
#include "mpr121-config.h"
void MPR121::begin(uint8_t addr, TwoWire *wire) {
_i2caddr = addr;
_wire = wire;
_wire->begin();
}
void MPR121::init() {
// 软件重置
reset();
delay(1);
stop();
writeRegisterRaw(MPR121_MHDR, MPR121CONF_MHDR, false);
writeRegisterRaw(MPR121_NHDR, MPR121CONF_NHDR, false);
writeRegisterRaw(MPR121_NCLR, MPR121CONF_NCLR, false);
writeRegisterRaw(MPR121_FDLR, MPR121CONF_FDLR, false);
writeRegisterRaw(MPR121_MHDF, MPR121CONF_MHDF, false);
writeRegisterRaw(MPR121_NHDF, MPR121CONF_NHDF, false);
writeRegisterRaw(MPR121_NCLF, MPR121CONF_NCLF, false);
writeRegisterRaw(MPR121_FDLF, MPR121CONF_FDLF, false);
writeRegisterRaw(MPR121_NHDT, MPR121CONF_NHDT, false);
writeRegisterRaw(MPR121_NCLT, MPR121CONF_NCLT, false);
writeRegisterRaw(MPR121_FDLT, MPR121CONF_FDLT, false);
// Skip ELEPROX baseline controls
for (int i = 0; i < 12; i++) {//设置触发阈值和充放电流时间
writeRegisterRaw(MPR121_TOUCHTH(i), MPR121CONF_TTH, false);
writeRegisterRaw(MPR121_RELEASETH(i), MPR121CONF_RTH, false);
writeRegisterRaw(MPR121_CDC(i), 0, false);
writeRegisterRaw(MPR121_CDT(i), 0, false);
}
writeRegisterRaw(MPR121_DEBOUNCE, (MPR121CONF_DR << 4) | MPR121CONF_DT, false); //设置采样数
writeRegisterRaw(MPR121_AFE1, (MPR121CONF_FFI << 6) | MPR121CONF_CDC, false);
writeRegisterRaw(MPR121_AFE2, (MPR121CONF_CDT << 5) | (MPR121CONF_SFI << 3) | MPR121CONF_ESI, false);
_ecr = (MPR121CONF_CL << 6) | (MPR121CONF_ELEPROX << 4) | MPR121CONF_ELE; // Write when start
// Skip GPIO configurations
writeRegisterRaw(MPR121_AUTOCONF0,
(MPR121CONF_AFES << 6) | (MPR121CONF_RETRY << 4) | (MPR121CONF_BVA << 2) | (MPR121CONF_ARE << 1) | MPR121CONF_ACE,
false);
writeRegisterRaw(MPR121_AUTOCONF1,
(MPR121CONF_SCTS << 7) | (MPR121CONF_OORIE << 2) | (MPR121CONF_ARFIE << 1) | MPR121CONF_ACFIE,
false);
writeRegisterRaw(MPR121_USL, MPR121CONF_USL, false);
writeRegisterRaw(MPR121_LSL, MPR121CONF_LSL, false);
writeRegisterRaw(MPR121_TL, MPR121CONF_TL, false);
// Manually call run to start
}
void MPR121::writeRegister(uint8_t reg, uint8_t value) {//相同
// MPR121 must be put in Stop Mode to write to most registers
bool stop_required = true;
if (reg == MPR121_ECR || (0x73 <= reg && reg <= 0x7A)) {
stop_required = false;
}
if (stop_required) {
_wire->beginTransmission(_i2caddr);
_wire->write(MPR121_ECR);
_wire->write(0x00); // clear this register to set stop modus
_wire->endTransmission(false);
}
_wire->beginTransmission(_i2caddr);
_wire->write((uint8_t)reg);
_wire->write((uint8_t)value);
_wire->endTransmission(!stop_required);
if (stop_required) {
_wire->beginTransmission(_i2caddr);
_wire->write(MPR121_ECR);
_wire->write(_ecr); // restore ECR
_wire->endTransmission(true);
}
}
//#endif
@@ -0,0 +1,227 @@
/*
Support class for MPR121, giving full control over the device efficiently.
Modifications licensed under University of Illinois/NCSA Open Source License
Copyright (c) 2020 Fang Lu
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal with the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
- Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimers.
- Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimers in the documentation
and/or other materials provided with the distribution.
- Neither the names of Fang Lu, nor the names of its contributors may be
used to endorse or promote products derived from this Software without
specific prior written permission.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
WITH THE SOFTWARE.
Original license text from Adafruit
@file Adafruit_MPR121.h
This is a library for the MPR121 12-Channel Capacitive Sensor
Designed specifically to work with the MPR121 board.
Pick one up today in the adafruit shop!
------> https://www.adafruit.com/product/1982
These sensors use I2C to communicate, 2+ pins are required to interface
Adafruit invests time and resources providing this open source code,
please support Adafruit andopen-source hardware by purchasing products
from Adafruit!
Limor Fried/Ladyada (Adafruit Industries).
BSD license, all text above must be included in any redistribution
*/
#ifndef _MPR121_HELPER_H
#define _MPR121_HELPER_H
#include "Arduino.h"
#include <Wire.h>
// Configuration values
#define MPR121_FFI_6 0
#define MPR121_FFI_10 1
#define MPR121_FFI_18 2
#define MPR121_FFI_34 3
#define MPR121_CDT_INHERIT 0
#define MPR121_CDT_500NS 1
#define MPR121_CDT_1US 2
#define MPR121_CDT_2US 3
#define MPR121_CDT_4US 4
#define MPR121_CDT_8US 5
#define MPR121_CDT_16US 6
#define MPR121_CDT_32US 7
#define MPR121_SFI_4 0
#define MPR121_SFI_6 0
#define MPR121_SFI_10 0
#define MPR121_SFI_18 0
#define MPR121_ESI_1MS 0
#define MPR121_ESI_2MS 1
#define MPR121_ESI_4MS 2
#define MPR121_ESI_8MS 3
#define MPR121_ESI_16MS 4
#define MPR121_ESI_32MS 5
#define MPR121_ESI_64MS 6
#define MPR121_ESI_128MS 7
#define MPR121_CL_NONE 0
#define MPR121_CL_LOCK 1
#define MPR121_CL_INIT1 2
#define MPR121_CL_INTI2 3
#define MPR121_ELEPROX_0 0
#define MPR121_ELEPROX_2 1
#define MPR121_ELEPROX_4 2
#define MPR121_ELEPROX_12 3
#define MPR121_AFES_6 0
#define MPR121_AFES_10 1
#define MPR121_AFES_18 2
#define MPR121_AFES_34 3
#define MPR121_RETRY_0 0
#define MPR121_RETRY_2 1
#define MPR121_RETRY_4 2
#define MPR121_RETRY_8 3
// Device register map
#define MPR121_TOUCHSTATUS_L 0x00
#define MPR121_TOUCHSTATUS_H 0x01
#define MPR121_OOR_L 0x02
#define MPR121_OOR_R 0x03
#define MPR121_FILTDATA(ch) (0x04 + 2*(ch))
#define MPR121_BASELINE(ch) (0x1E + (ch))
#define MPR121_MHDR 0x2B
#define MPR121_NHDR 0x2C
#define MPR121_NCLR 0x2D
#define MPR121_FDLR 0x2E
#define MPR121_MHDF 0x2F
#define MPR121_NHDF 0x30
#define MPR121_NCLF 0x31
#define MPR121_FDLF 0x32
#define MPR121_NHDT 0x33
#define MPR121_NCLT 0x34
#define MPR121_FDLT 0x35
#define MPR121_MHDPROXR 0x36
#define MPR121_HHDPROXR 0x37
#define MPR121_NCLPROXR 0x38
#define MPR121_FDLPROXR 0x39
#define MPR121_MHDPROXF 0x3A
#define MPR121_NHDPROXF 0x3B
#define MPR121_NCLPROXF 0x3C
#define MPR121_FDLPROXF 0x3D
#define MPR121_NHDPROXT 0x3E
#define MPR121_NCLPROXT 0x3F
#define MPR121_FDLPROXT 0x40
#define MPR121_TOUCHTH(ch) (0x41 + 2*(ch))
#define MPR121_RELEASETH(ch) (0x42 + 2*(ch))
#define MPR121_DEBOUNCE 0x5B
#define MPR121_AFE1 0x5C
#define MPR121_AFE2 0x5D
#define MPR121_ECR 0x5E
#define MPR121_CDC(ch) (0x5F + (ch))
#define MPR121_CDT(ch) (0x6C + ((ch)>>1))
#define MPR121_CTL0 0x73
#define MPR121_CTL1 0x74
#define MPR121_DAT 0x75
#define MPR121_DIR 0x76
#define MPR121_EN 0x77
#define MPR121_SET 0x78
#define MPR121_CLR 0x79
#define MPR121_TOG 0x7A
#define MPR121_AUTOCONF0 0x7B
#define MPR121_AUTOCONF1 0x7C
#define MPR121_USL 0x7D
#define MPR121_LSL 0x7E
#define MPR121_TL 0x7F
#define MPR121_SRST 0x80
#define MPR121_I2CADDR_DEFAULT 0x5A
class MPR121 {
public:
MPR121() {}
void begin(uint8_t addr = MPR121_I2CADDR_DEFAULT, TwoWire *wire = &Wire);
void init();
uint8_t readRegister8(uint8_t rs) {//相同
_wire->beginTransmission(_i2caddr);
_wire->write(rs);
_wire->endTransmission(false);
_wire->requestFrom(_i2caddr, 1);
if (_wire->available() < 1)
return 0;
return _wire->read();
}
uint16_t readRegister16(uint8_t rs) {//相同
_wire->beginTransmission(_i2caddr);
_wire->write(rs);
_wire->endTransmission(false);
_wire->requestFrom(_i2caddr, 2);
if (_wire->available() < 2)
return 0;
uint16_t v = _wire->read();
v |= ((uint16_t)_wire->read()) << 8;
return v;
}
void writeRegister(uint8_t rd, uint8_t value);
void writeRegisterRaw(uint8_t rd, uint8_t value, bool stop = true) {
_wire->beginTransmission(_i2caddr);
_wire->write(rd);
_wire->write(value);
_wire->endTransmission(stop);
}
void stop() {
writeRegisterRaw(MPR121_ECR, 0x00);
}
void run() {
writeRegisterRaw(MPR121_ECR, _ecr);
}
void reset() {
writeRegisterRaw(MPR121_SRST, 0x63);
}
uint16_t filteredData(uint8_t ch) {
return readRegister16(MPR121_FILTDATA(ch));
}
uint16_t baselineData(uint8_t ch) {
return ((uint16_t)readRegister8(MPR121_BASELINE(ch))) << 2;
}
uint16_t touched() {
return readRegister16(MPR121_TOUCHSTATUS_L);
}
private:
int8_t _i2caddr;
TwoWire *_wire;
uint8_t _ecr;
};
#endif
@@ -0,0 +1,111 @@
#include "serial.h"
#include <Arduino.h>
slider_packet_t slider_req, slider_resp;
int slider_tx_pending = 0;
// int checkcom = 0;
uint8_t sliderserial_readreq() {
static short ptr = 0;
static uint8_t checksum;
static bool esc = false;
uint8_t c;
while (SerialUSB.available()) {
// checkcom = SLIDER_CMD_AUTO_SCAN;
c = SerialUSB.read();
// SYN
if (c == 0xff) {
// SerialUSB.println("SYN");
ptr = 0;
slider_req.syn = c;
slider_req.cmd = 0; // Unset cmd
slider_req.size = 0xff; // Unset size
checksum = 0xff;
esc = false;
continue;
}
// Escape
if (esc) {
esc = false;
c++;
} else if (c == 0xfd) {
esc = true;
continue;
}
// Checksum
checksum += c;
// Byte 2 (opcode)
if (!slider_req.cmd) {
// SerialUSB.print("Cmd: ");
// SerialUSB.println(c, HEX);
slider_req.cmd = c;
continue;
}
// Byte 3 (size)
if (slider_req.size == 0xff) {
// SerialUSB.print("Size: ");
// SerialUSB.println(c);
slider_req.size = c;
ptr = 3;
continue;
}
// Payload Body
if (ptr >= 128) {
// Buffer full. Invalidate. Wait for next SYN.
continue;
}
slider_req.data[ptr++] = c;
if (ptr-3 == slider_req.size+1) {
// End
if (checksum == 0) {
// SerialUSB.println("OK");
return slider_req.cmd;
}
// SerialUSB.println("Checksum Error!");
}
}
return 0;
}
void sliderserial_writeresp() {
static short ptr = 0;
static uint8_t checksum;
// Detect new response
if (!slider_tx_pending) {
if (slider_resp.cmd) {
slider_tx_pending = slider_resp.size + 4;
ptr = 0;
checksum = 0;
} else {
return;
}
}
while (slider_tx_pending) {
uint8_t c;
if (slider_tx_pending == 1) {
c = -checksum;
} else {
c = slider_resp.data[ptr];
}
checksum += c;
if ((ptr != 0 && c == 0xff) || c == 0xfd) {
// Escape required
if (SerialUSB.availableForWrite() < 2)
return;
SerialUSB.write(0xfd);
c--;
} else {
// Normal
if (SerialUSB.availableForWrite() < 1)
return;
}
SerialUSB.write(c);
ptr++;
slider_tx_pending--;
}
slider_resp.cmd = 0;
}
@@ -0,0 +1,64 @@
#ifndef SERIAL_H
#define SERIAL_H
#include <stdint.h>
enum {
SLIDER_CMD_AUTO_SCAN = 0x01,
SLIDER_CMD_SET_LED = 0x02,
SLIDER_CMD_AUTO_SCAN_START = 0x03,
SLIDER_CMD_AUTO_SCAN_STOP = 0x04,
SLIDER_CMD_DIVA_UNK_09 = 0x09,
SLIDER_CMD_DIVA_UNK_0A = 0x0A,
SLIDER_CMD_RESET = 0x10,
SLIDER_CMD_GET_BOARD_INFO = 0xF0
};
typedef union slider_packet {
struct {
uint8_t syn;
uint8_t cmd;
uint8_t size;
union {
struct {
uint8_t led_unk;
uint8_t leds[96];
};
char version[32];
uint8_t pressure[32];
};
};
uint8_t data[128];
} slider_packet_t;
/// Request and response data
extern slider_packet_t slider_req, slider_resp;
/// A message is being sent. Serial buffers should not be changed. FastLED or
/// any other library should not mask interrupts.
extern int slider_tx_pending;
// extern int checkcom;
/**
* Read slider request from serial
*
* Reads from `Serial` and decodes the incoming request when a complete packet
* is correctly received. Writes the decoded request into `slider_req`. Call to
* this function will invalidate `slider_req` until a valid opcode is returned.
* @note This function is stateful! Carefully examine its implementation if you
* wish to reuse it!
* @return The opcode, or 0 if a complete request is not yet received.
*/
uint8_t sliderserial_readreq();//读取数据
/**
* Send response to host
*
* Encodes the response stored in `slider_resp` and send over `Serial`.
* `slider_resp` should not be modified until `slider_tx_pending` is zeroed.
* This function should be called on each loop iteration.
* @note This function is stateful! Carefully examine its implementation if you
* wish to reuse it!
*/
void sliderserial_writeresp();//写入数据
#endif
@@ -0,0 +1,11 @@
This directory is intended for PlatformIO Unit Testing and project tests.
Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.
More information about PlatformIO Unit Testing:
- https://docs.platformio.org/page/plus/unit-testing.html