Hi all,
I've just posted a query about LEDs in another part of the forum, but I'm new around here so hopefully forgiven for asking another (different) question here...
I have an Adafruit Circuit Playground Classic and I am using the three axis accelerometer to control parameters within MaxMSP (or I'm trying to...)
At the moment, all three axis give me +/- numerical data, but I want to confine this to a specific range, and when the sensors are giving off data outside of that range, it is fixed to the high/low of the range. For example: A range of 0.1 - 10, whereby any measurement below 0.1 is fixed at 0.1, and anything above 10 is fixed at 10, until the sensor starts generating data within the aforementioned range.
I've found some example code from Adafruit which scales the data for use as a mouse, but in trying to remove the mouse functionality, I thought my laptop was going to explode, such were the number of error messages!
Code below for info. The second code is long and as I say, I'm just trying to replicate the scaling bit, without any of the mouse functionality.
Three Axis Accelerometer/Taps:
#include <Adafruit_CircuitPlayground.h>
#include <Wire.h>
#include <SPI.h>
float X, Y, Z;
#define CLICKTHRESHHOLD 80
void setup(void) {
while (!Serial);
Serial.begin(9600);
CircuitPlayground.begin();
CircuitPlayground.setAccelRange(LIS3DH_RANGE_8_G); //(2/4/8/16)
CircuitPlayground.setAccelTap(1, CLICKTHRESHHOLD);
attachInterrupt(digitalPinToInterrupt(CPLAY_LIS3DH_INTERRUPT), tapTime, FALLING);
}
void tapTime(void) {
// do something :)
Serial.print(" High ");
Serial.println(" ");
}
void loop() {
X = CircuitPlayground.motionX();
Y = CircuitPlayground.motionY();
Z = CircuitPlayground.motionZ();
Serial.print(" ");
Serial.print(X);
Serial.print(" ");
Serial.print(Y);
Serial.print(" ");
Serial.println(Z);
delay(100);
Adafruit AccelMouse Example code
#include <Adafruit_CircuitPlayground.h>
#include <Mouse.h>
#include <Wire.h>
#include <SPI.h>
// Configuration values to adjust the sensitivity and speed of the mouse.
// X axis (left/right) configuration:
#define XACCEL_MIN 0.1 // Minimum range of X axis acceleration, values below
// this won't move the mouse at all.
#define XACCEL_MAX 8.0 // Maximum range of X axis acceleration, values above
// this will move the mouse as fast as possible.
#define XMOUSE_RANGE 25.0 // Range of velocity for mouse movements. The higher
// this value the faster the mouse will move.
#define XMOUSE_SCALE 1 // Scaling value to apply to mouse movement, this is
// useful to set to -1 to flip the X axis movement.
// Y axis (up/down) configuration:
// Note that the meaning of these values is exactly the same as the X axis above,
// just applied to the Y axis and up/down mouse movement. You probably want to
// keep these values the same as for the X axis (which is the default, they just
// read the X axis values but you can override with custom values).
#define YACCEL_MIN XACCEL_MIN
#define YACCEL_MAX XACCEL_MAX
#define YMOUSE_RANGE XMOUSE_RANGE
#define YMOUSE_SCALE 1
// Set this true to flip the mouse X/Y axis with the board X/Y axis (what you want
// if holding with USB cable facing up).
#define FLIP_AXES true
// Floating point linear interpolation function that takes a value inside one
// range and maps it to a new value inside another range. This is used to transform
// each axis of acceleration to mouse velocity/speed. See this page for details
// on the equation: https://en.wikipedia.org/wiki/Linear_interpolation
float lerp(float x, float x0, float x1, float y0, float y1) {
// Check if the input value (x) is outside its desired range and clamp to
// those min/max y values.
if (x <= x0) {
return y0;
}
else if (x >= x1) {
return y1;
}
// Otherwise compute the value y based on x's position within its range and
// the desired y min & max.
return y0 + (y1-y0)*((x-x0)/(x1-x0));
}
void setup() {
// Initialize Circuit Playground library.
CircuitPlayground.begin();
// Initialize Arduino mouse library.
Mouse.begin();
}
void loop() {
// Check if the slide switch is enabled (on +) and if not then just exit out
// and run the loop again. This lets you turn on/off the mouse movement with
// the slide switch.
if (!CircuitPlayground.slideSwitch()) {
return;
}
// Grab initial left & right button states to later check if they are pressed
// or released. Do this early in the loop so other processing can take some
// time and the button state change can be detected.
boolean left_first = CircuitPlayground.leftButton();
boolean right_first = CircuitPlayground.rightButton();
// Grab x, y acceleration values (in m/s^2).
float x = CircuitPlayground.motionX();
float y = CircuitPlayground.motionY();
// Use the magnitude of acceleration to interpolate the mouse velocity.
float x_mag = abs(x);
float x_mouse = lerp(x_mag, XACCEL_MIN, XACCEL_MAX, 0.0, XMOUSE_RANGE);
float y_mag = abs(y);
float y_mouse = lerp(y_mag, YACCEL_MIN, YACCEL_MAX, 0.0, YMOUSE_RANGE);
// Change the mouse direction based on the direction of the acceleration.
if (x < 0) {
x_mouse *= -1.0;
}
if (y < 0) {
y_mouse *= -1.0;
}
// Apply any global scaling to the axis (to flip it for example) and truncate
// to an integer value.
x_mouse = floor(x_mouse*XMOUSE_SCALE);
y_mouse = floor(y_mouse*YMOUSE_SCALE);
// Move mouse.
if (!FLIP_AXES) {
// Non-flipped axes, just map board X/Y to mouse X/Y.
Mouse.move((int)x_mouse, (int)y_mouse, 0);
}
else {
// Flipped axes, swap them around.
Mouse.move((int)y_mouse, (int)x_mouse, 0);
}
// Small delay to wait for button state changes and slow down processing a bit.
delay(10);
// Grab a second button state reading to check if the buttons were pressed or
// released.
boolean left_second = CircuitPlayground.leftButton();
boolean right_second = CircuitPlayground.rightButton();
// Check for left button pressed / released.
if (!left_first && left_second) {
// Low then high, button was pressed!
Mouse.press(MOUSE_LEFT);
}
else if (left_first && !left_second) {
// High then low, button was released!
Mouse.release(MOUSE_LEFT);
}
// Check for right button pressed / released.
if (!right_first && right_second) {
// Low then high, button was pressed!
Mouse.press(MOUSE_RIGHT);
}
else if (right_first && !right_second) {
// High then low, button was released!
Mouse.release(MOUSE_RIGHT);
}
}