Hi folks,
I'm very much a beginner to Arduino's and microcontrollers in general.
I'm trying combine two bits of code. I've actually popped it all into one patch to see if it compiles as is, and it does. What I'm trying to achieve is noted below...
The code collects accelerometer data from 3 Axis and also outputs 'tap' data. Single taps are fine for what I'm doing.
Example code from Adafruit which uses the Neopixels as a UV meter, in combination with the in-built microphone. The microphone level dictates the UV meter level as you might expect.
I'd like to use the accelerometer measurements from one of the axis (doesn't matter which right now) to trigger the UV rather than the microphone. I don't know if this is possible, but if it is, I suspect this is the forum to find out.
#include <Adafruit_CircuitPlayground.h>
#include <Wire.h>
#include <SPI.h>
#include <math.h>
float X, Y, Z; // Accelerometers
#define CLICKTHRESHHOLD 80 // Tap Threshold
#define MIC_PIN A4 // Microphone is attached to this analog pin (A4 for circuit playground)
#define SAMPLE_WINDOW 10 // Sample window for average level
#define PEAK_HANG 24 // Time of pause before peak dot falls
#define PEAK_FALL 4 // Rate of falling peak dot
#define INPUT_FLOOR 10 // Lower range of analogRead input
#define INPUT_CEILING 500 // Max range of analogRead input, the lower the value the more sensitive (1023 = max)
byte peak = 16; // Peak level of column; used for falling dots
unsigned int sample;
byte dotCount = 0; //Frame counter for peak dot
byte dotHangCount = 0; //Frame counter for holding peak dot
float fscale(float originalMin, float originalMax, float newBegin, float newEnd, float inputValue, float curve);
void setup(void) {
while (!Serial);
Serial.begin(9600);
CircuitPlayground.begin();
CircuitPlayground.setAccelRange(LIS3DH_RANGE_8_G); // TAPS (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);
int numPixels = CircuitPlayground.strip.numPixels();
unsigned long startMillis= millis(); // Start of sample window
float peakToPeak = 0; // peak-to-peak level
unsigned int signalMax = 0;
unsigned int signalMin = 1023;
unsigned int c, y;
// collect data for length of sample window (in mS)
while (millis() - startMillis < SAMPLE_WINDOW)
{
sample = analogRead(MIC_PIN);
if (sample < 1024) // toss out spurious readings
{
if (sample > signalMax)
{
signalMax = sample; // save just the max levels
}
else if (sample < signalMin)
{
signalMin = sample; // save just the min levels
}
}
}
peakToPeak = signalMax - signalMin; // max - min = peak-peak amplitude
// Serial.println(peakToPeak);
//Fill the strip with rainbow gradient
for (int i=0;i<=numPixels-1;i++){
CircuitPlayground.strip.setPixelColor(i,Wheel(map(i,0,numPixels-1,30,150)));
}
//Scale the input logarithmically instead of linearly
c = fscale(INPUT_FLOOR, INPUT_CEILING, numPixels, 0, peakToPeak, 2);
// Turn off pixels that are below volume threshold.
if(c < peak) {
peak = c; // Keep dot on top
dotHangCount = 0; // make the dot hang before falling
}
if (c <= numPixels) { // Fill partial column with off pixels
drawLine(numPixels, numPixels-c, CircuitPlayground.strip.Color(0, 0, 0));
}
// Set the peak dot to match the rainbow gradient
y = numPixels - peak;
CircuitPlayground.strip.setPixelColor(y-1,Wheel(map(y,0,numPixels-1,30,150)));
CircuitPlayground.strip.show();
// Frame based peak dot animation
if(dotHangCount > PEAK_HANG) { //Peak pause length
if(++dotCount >= PEAK_FALL) { //Fall rate
peak++;
dotCount = 0;
}
}
else {
dotHangCount++;
}
}
//Used to draw a line between two points of a given color
void drawLine(uint8_t from, uint8_t to, uint32_t c) {
uint8_t fromTemp;
if (from > to) {
fromTemp = from;
from = to;
to = fromTemp;
}
for(int i=from; i<=to; i++){
CircuitPlayground.strip.setPixelColor(i, c);
}
}
float fscale( float originalMin, float originalMax, float newBegin, float
newEnd, float inputValue, float curve){
float OriginalRange = 0;
float NewRange = 0;
float zeroRefCurVal = 0;
float normalizedCurVal = 0;
float rangedValue = 0;
boolean invFlag = 0;
// condition curve parameter
// limit range
if (curve > 10) curve = 10;
if (curve < -10) curve = -10;
curve = (curve * -.1) ; // -
curve = pow(10, curve); //
// Check for out of range inputValues
if (inputValue < originalMin) {
inputValue = originalMin;
}
if (inputValue > originalMax) {
inputValue = originalMax;
}
// Zero Refference the values
OriginalRange = originalMax - originalMin;
if (newEnd > newBegin){
NewRange = newEnd - newBegin;
}
else
{
NewRange = newBegin - newEnd;
invFlag = 1;
}
zeroRefCurVal = inputValue - originalMin;
normalizedCurVal = zeroRefCurVal / OriginalRange; // normalize to 0 - 1 float
// Check for originalMin > originalMax - the math for all other cases i.e. negative numbers seems to work out fine
if (originalMin > originalMax ) {
return 0;
}
if (invFlag == 0){
rangedValue = (pow(normalizedCurVal, curve) * NewRange) + newBegin;
}
else // invert the ranges
{
rangedValue = newBegin - (pow(normalizedCurVal, curve) * NewRange);
}
return rangedValue;
}
uint32_t Wheel(byte WheelPos) {
if(WheelPos < 85) {
return CircuitPlayground.strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
else if(WheelPos < 170) {
WheelPos -= 85;
return CircuitPlayground.strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
else {
WheelPos -= 170;
return CircuitPlayground.strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
delay(100);
}