Created
June 24, 2022 09:48
-
-
Save micuat/1b0012581e4cb760f4626f3e8fb4cefb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Wire.h> | |
#include "Adafruit_MPR121.h" | |
#ifndef _BV | |
#define _BV(bit) (1 << (bit)) | |
#endif | |
// You can have up to 4 on one i2c bus but one is enough for testing! | |
Adafruit_MPR121 cap = Adafruit_MPR121(); | |
// Keeps track of the last pins touched | |
// so we know when buttons are 'released' | |
uint16_t lasttouched = 0; | |
uint16_t currtouched = 0; | |
#include <Adafruit_PWMServoDriver.h> | |
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); | |
#define SERVOMIN 150 // This is the 'minimum' pulse length count (out of 4096) | |
#define SERVOMAX 600 // This is the 'maximum' pulse length count (out of 4096) | |
#define USMIN 600 // This is the rounded 'minimum' microsecond length based on the minimum pulse of 150 | |
#define USMAX 2400 // This is the rounded 'maximum' microsecond length based on the maximum pulse of 600 | |
#define SERVO_FREQ 50 // Analog servos run at ~50 Hz updates | |
void setup() { | |
Serial.begin(9600); | |
while (!Serial) { // needed to keep leonardo/micro from starting too fast! | |
delay(10); | |
} | |
Serial.println("Adafruit MPR121 Capacitive Touch sensor test"); | |
// Default address is 0x5A, if tied to 3.3V its 0x5B | |
// If tied to SDA its 0x5C and if SCL then 0x5D | |
if (!cap.begin(0x5A)) { | |
Serial.println("MPR121 not found, check wiring?"); | |
while (1); | |
} | |
Serial.println("MPR121 found!"); | |
pwm.begin(); | |
/* | |
In theory the internal oscillator (clock) is 25MHz but it really isn't | |
that precise. You can 'calibrate' this by tweaking this number until | |
you get the PWM update frequency you're expecting! | |
The int.osc. for the PCA9685 chip is a range between about 23-27MHz and | |
is used for calculating things like writeMicroseconds() | |
Analog servos run at ~50 Hz updates, It is importaint to use an | |
oscilloscope in setting the int.osc frequency for the I2C PCA9685 chip. | |
1) Attach the oscilloscope to one of the PWM signal pins and ground on | |
the I2C PCA9685 chip you are setting the value for. | |
2) Adjust setOscillatorFrequency() until the PWM update frequency is the | |
expected value (50Hz for most ESCs) | |
Setting the value here is specific to each individual I2C PCA9685 chip and | |
affects the calculations for the PWM update frequency. | |
Failure to correctly set the int.osc value will cause unexpected PWM results | |
*/ | |
pwm.setOscillatorFrequency(27000000); | |
pwm.setPWMFreq(SERVO_FREQ); // Analog servos run at ~50 Hz updates | |
delay(10); | |
} | |
// You can use this function if you'd like to set the pulse length in seconds | |
// e.g. setServoPulse(0, 0.001) is a ~1 millisecond pulse width. It's not precise! | |
void setServoPulse(uint8_t n, double pulse) { | |
double pulselength; | |
pulselength = 1000000; // 1,000,000 us per second | |
pulselength /= SERVO_FREQ; // Analog servos run at ~60 Hz updates | |
Serial.print(pulselength); Serial.println(" us per period"); | |
pulselength /= 4096; // 12 bits of resolution | |
Serial.print(pulselength); Serial.println(" us per bit"); | |
pulse *= 1000000; // convert input seconds to us | |
pulse /= pulselength; | |
Serial.println(pulse); | |
pwm.setPWM(n, 0, pulse); | |
} | |
void loop() { | |
// Get the currently touched pads | |
currtouched = cap.touched(); | |
int servonum = -1; | |
for (uint8_t i = 0; i < 12; i++) { | |
// it if *is* touched and *wasnt* touched before, alert! | |
if ((currtouched & _BV(i)) && !(lasttouched & _BV(i)) ) { | |
Serial.print(i); Serial.println(" touched"); | |
servonum = i; | |
} | |
// if it *was* touched and now *isnt*, alert! | |
if (!(currtouched & _BV(i)) && (lasttouched & _BV(i)) ) { | |
Serial.print(i); Serial.println(" released"); | |
} | |
} | |
if (servonum >= 0) { | |
// Drive each servo one at a time using setPWM() | |
Serial.println(servonum); | |
for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) { | |
pwm.setPWM(servonum, 0, pulselen); | |
} | |
delay(500); | |
for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) { | |
pwm.setPWM(servonum, 0, pulselen); | |
} | |
delay(500); | |
// Drive each servo one at a time using writeMicroseconds(), it's not precise due to calculation rounding! | |
// The writeMicroseconds() function is used to mimic the Arduino Servo library writeMicroseconds() behavior. | |
for (uint16_t microsec = USMIN; microsec < USMAX; microsec++) { | |
pwm.writeMicroseconds(servonum, microsec); | |
} | |
delay(500); | |
for (uint16_t microsec = USMAX; microsec > USMIN; microsec--) { | |
pwm.writeMicroseconds(servonum, microsec); | |
} | |
delay(500); | |
} | |
// reset our state | |
lasttouched = currtouched; | |
// comment out this line for detailed data from the sensor! | |
return; | |
// debugging info, what | |
Serial.print("\t\t\t\t\t\t\t\t\t\t\t\t\t 0x"); Serial.println(cap.touched(), HEX); | |
Serial.print("Filt: "); | |
for (uint8_t i = 0; i < 12; i++) { | |
Serial.print(cap.filteredData(i)); Serial.print("\t"); | |
} | |
Serial.println(); | |
Serial.print("Base: "); | |
for (uint8_t i = 0; i < 12; i++) { | |
Serial.print(cap.baselineData(i)); Serial.print("\t"); | |
} | |
Serial.println(); | |
// put a delay so it isn't overwhelming | |
delay(100); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment