Ce serveur Gitlab sera éteint le 30 juin 2020, pensez à migrer vos projets vers les serveurs gitlab-research.centralesupelec.fr et gitlab-student.centralesupelec.fr !

Commit 5d3a953a authored by Depasse Arthur's avatar Depasse Arthur

commit 1

parents
class Button {
public:
//ctor
Button(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t radius,
uint16_t color, uint16_t clickedColor,
String text, uint16_t textColor, uint16_t textSize,
uint16_t textX, uint16_t textY,
void (* callback)()) {
_x = x;
_y = y;
_width = width;
_height = height;
_radius = radius;
_color = color;
_clickedColor = clickedColor;
_textColor = textColor;
_textSize = textSize;
_text = text;
_textX = textX;
_textY = textY;
_callback = callback;
}
bool collided(int x, int y){
return x >= _x && x <= (_x + _width) && y >= _y && y <= (_y + _height);
}
void draw(Adafruit_ILI9341* tft) {
tft->fillRoundRect(_x, _y, _width, _height, _radius , _color);
tft->setCursor(_x + _textX, _y + _textY);
tft->setTextColor(_textColor);
tft->setTextSize(_textSize);
tft->print(_text);
}
void handleClick(Adafruit_ILI9341* tft, TS_Point p)
{
if (collided(p.x, p.y)) {
uint16_t temp = _color;
_color = _clickedColor;
draw(tft);
delay(200);
_color = temp;
draw(tft);
_callback();
}
}
private:
uint16_t _x;
uint16_t _y;
uint16_t _width;
uint16_t _height;
uint16_t _radius;
uint16_t _color;
uint16_t _clickedColor;
uint16_t _textColor;
uint16_t _textSize;
uint16_t _textX;
uint16_t _textY;
String _text;
void (* _callback)();
};
class ButtonPP {
public:
//ctor
ButtonPP(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t radius,
uint16_t upColor, uint16_t downColor,
String text, uint16_t textColor, uint16_t textSize,
uint16_t textX, uint16_t textY,
void (* callback1)(),
void (* callback2)()) {
_x = x;
_y = y;
_width = width;
_height = height;
_radius = radius;
_color = upColor;
_upColor = upColor;
_downColor = downColor;
_textColor = textColor;
_textSize = textSize;
_text = text;
_textX = textX;
_textY = textY;
_callback1 = callback1;
_callback2 = callback2;
_down = false;
}
bool getState() {
return _down;
}
bool collided(int x, int y){
return x >= _x && x <= (_x + _width) && y >= _y && y <= (_y + _height);
}
void draw(Adafruit_ILI9341* tft) {
tft->fillRoundRect(_x, _y, _width, _height, _radius , _color);
tft->setCursor(_x + _textX, _y + _textY);
tft->setTextColor(_textColor);
tft->setTextSize(_textSize);
tft->print(_text);
}
void handleClick(Adafruit_ILI9341* tft, TS_Point p)
{
if (collided(p.x, p.y)) {
if (_down) {
_down = false;
_color = _upColor;
draw(tft);
_callback2();
}
else {
_down = true;
_color = _downColor;
draw(tft);
_callback1();
}
}
}
private:
uint16_t _x;
uint16_t _y;
uint16_t _width;
uint16_t _height;
uint16_t _radius;
uint16_t _color;
uint16_t _downColor;
uint16_t _upColor;
uint16_t _textColor;
uint16_t _textSize;
uint16_t _textX;
uint16_t _textY;
String _text;
bool _down = false;
void (* _callback1)();
void (* _callback2)();
};
// This is calibration data for the raw touch data to the screen coordinates
#define TS_MINX 150
#define TS_MINY 130
#define TS_MAXX 3800
#define TS_MAXY 4000
// The STMPE610 uses hardware SPI on the shield, and #8
#define STMPE_CS 8
Adafruit_STMPE610 touch = Adafruit_STMPE610(STMPE_CS);
// The display also uses hardware SPI, plus #9 & #10
#define TFT_CS 10
#define TFT_DC 9
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
// Color definitions
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
// ScreenDefs
enum ScreenType
{
Splash,
Main,
};
ScreenType screenType = ScreenType::Splash;
// redraw the resonance value on the screen
void redrawResonance()
{
int x = tft.width() * 2 / 3;
tft.fillRect(100, x + 10, 120 + 50, x + 10, BLACK);
tft.setTextSize(1);
tft.setTextColor(ILI9341_WHITE);
tft.setCursor(120, x + 10);
tft.print(lpfResonance);
}
// draw the ON/OFF message on the screen
void drawOn(bool o)
{
tft.fillRect(200, tft.width() * 1 / 3 - 40, 200 + 50, tft.width() * 1 / 3 + 10, BLACK);
if (o)
{
tft.setTextSize(3);
tft.setTextColor(RED);
tft.setCursor(200, tft.width() * 1 / 3 - 40);
tft.print("ON");
}
else
{
tft.setTextSize(3);
tft.setTextColor(RED);
tft.setCursor(200, tft.width() * 1 / 3 - 40);
tft.print("OFF");
}
}
// MainScreen definitions
void b1callback1()
{
Serial.println("B1 was clicked : now down !");
f1active = true;
drawOn(true);
}
void b1callback2()
{
Serial.println("B1 was clicked : now up !");
f1active = false;
drawOn(false);
}
/*void b2callback1()
{
Serial.println("B2 was clicked ! : now down");
f2active = true;
}
void b2callback2()
{
Serial.println("B2 was clicked ! : now up");
f2active = false;
}*/
void b3callback()
{
Serial.println("B3 was clicked !");
lpfResonance += 50;
lpfResonance %= 250;
lpf.setResonance(lpfResonance);
redrawResonance();
}
#define MAINBUTTONS 1 //1
#define MAINBUTTONSPP 1 //2
ButtonPP mainButtonsPP[MAINBUTTONSPP] = {
ButtonPP(10, 10, 140, 30, 2, GREEN, BLUE, "Low Pass", RED, 2, 10, 8, b1callback1, b1callback2)
//ButtonPP(10, 50, 120, 30, 2, GREEN, BLUE, "Delay", RED, 2, 10, 8, b2callback1, b2callback2)
};
Button mainButtons[MAINBUTTONS] = {
Button(10, 90, 140, 30, 2, GREEN, BLUE, "Cycle Reso", RED, 2, 10, 8, b3callback)};
TS_Point retrievePoint()
{
while (!touch.bufferSize() > 0)
{
touch.getPoint();
}
TS_Point p_raw = touch.getPoint();
//Serial.print("X = "); Serial.print(p_raw.x);
//Serial.print("\tY = "); Serial.print(p_raw.y);
//Serial.print("\tPressure = "); Serial.println(p_raw.z);
TS_Point p = p_raw;
// Scale from ~0->4000 to tft.width using the calibration #'s
p_raw.x = map(p_raw.x, TS_MINX, TS_MAXX, 0, tft.height());
p_raw.y = map(p_raw.y, TS_MINY, TS_MAXY, 0, tft.width());
//Serial.print("("); Serial.print(p_raw.x);
//Serial.print(", "); Serial.print(p_raw.y);
//Serial.println(")");
p.x = p_raw.y;
p.y = tft.height() - p_raw.x;
//Serial.print("("); Serial.print(p.x);
//Serial.print(", "); Serial.print(p.y);
//Serial.println(")");
return p;
}
void emptyTouchBuffer()
{
while (!touch.bufferEmpty())
{
touch.getPoint();
}
}
void drawSplash()
{
tft.fillScreen(ILI9341_BLACK);
tft.setCursor(tft.width() / 2 - 70, tft.height() / 2 - 30);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
tft.println("MusicBox");
tft.setCursor(tft.width() / 2 - 70, tft.height() / 2);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(1);
tft.println("By G.De Viry & A.Depasse");
}
void drawMain()
{
tft.fillScreen(ILI9341_BLACK);
for (uint16_t i = 0; i < MAINBUTTONS; i++)
{
mainButtons[i].draw(&tft);
}
for (uint16_t i = 0; i < MAINBUTTONSPP; i++)
{
mainButtonsPP[i].draw(&tft);
}
int x = tft.width() * 2 / 3;
tft.drawLine(0, x - 20, tft.width(), x - 20, WHITE);
tft.setTextSize(1);
tft.setTextColor(ILI9341_WHITE);
tft.setCursor(10, x);
tft.print("LPF Cutoff Freq");
tft.setCursor(10, x + 10);
tft.print(lpfCutoffFreq * 24000 / 255);
tft.print(" Hz");
tft.setCursor(120, x);
tft.print("LPF Resonance");
tft.setCursor(120, x + 10);
tft.print(lpfResonance);
}
// Redraw the cutoff frequency
void redrawMainNumbers()
{
int x = tft.width() * 2 / 3;
tft.fillRect(10, x + 10, 10 + 50, x + 10, BLACK);
tft.setTextSize(1);
tft.setTextColor(ILI9341_WHITE);
tft.setCursor(10, x + 10);
tft.print(lpfCutoffFreq * 24000 / 255);
tft.print(" Hz");
yield();
}
#define LED1 23
#define LED2 25
#define LED3 27
#define LED4 29
#define LED5 31
#define LED6 33
#define LED7 35
void allLedsOn()
{
digitalWrite(LED1, HIGH);
digitalWrite(LED2, HIGH);
digitalWrite(LED3, HIGH);
digitalWrite(LED4, HIGH);
digitalWrite(LED5, HIGH);
digitalWrite(LED6, HIGH);
digitalWrite(LED7, HIGH);
}
void allLedsOff()
{
digitalWrite(LED1, LOW);
digitalWrite(LED2, LOW);
digitalWrite(LED3, LOW);
digitalWrite(LED4, LOW);
digitalWrite(LED5, LOW);
digitalWrite(LED6, LOW);
digitalWrite(LED7, LOW);
}
void ledSetup()
{
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
pinMode(LED4, OUTPUT);
pinMode(LED5, OUTPUT);
pinMode(LED6, OUTPUT);
pinMode(LED7, OUTPUT);
allLedsOff();
}
int LEDS[7] = {LED1, LED2, LED3, LED4, LED5, LED6, LED7};
void allumerLeds(uint16_t leds)
{
for (int i = 0; i < 7; i++)
{
// use a simple bit mask to manage all leds
if (leds & (0b1 << i))
{
digitalWrite(LEDS[i], HIGH);
}
}
}
inline void ledInput(int val)
{
allLedsOff();
if (val > 3900) //rouge
{
allumerLeds(0b1111111);
delay(20);
}
else if (val > 3000) //jaune 2
{
allumerLeds(0b0111111);
delay(20);
}
else if (val > 2648) //jaune 1
{
allumerLeds(0b0011111);
delay(20);
}
else if (val > 2576) //vert 4
{
allumerLeds(0b0001111);
delay(20);
}
else if (val > 2503) //vert 3
{
allumerLeds(0b0000111);
delay(20);
}
else if (val > 2358) //vert 2
{
allumerLeds(0b0000011);
delay(20);
}
else if (val > 2048 + 20) // vert 1
{
allumerLeds(0b0000001);
delay(20);
}
else // rien
{
delay(5);
}
delay(5);
}
/*
* LowPassFilter.h
*
* Copyright 2012 Tim Barrass
*
* This file is part of Mozzi.
*
* Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
*
*/
#ifndef LOWPASS_H_
#define LOWPASS_H_
/*
simple resonant filter posted to musicdsp.org by Paul Kellett http://www.musicdsp.org/archive.php?classid=3#259
// set feedback amount given f and q between 0 and 1
fb = q + q/(1.0 - f);
// for each sample...
buf0 = buf0 + f * (in - buf0 + fb * (buf0 - buf1));
buf1 = buf1 + f * (buf0 - buf1);
out = buf1;
fixed point version of the filter
"dave's blog of art and programming" http://www.pawfal.org/dave/blog/2011/09/
*/
// we are using .n fixed point (n bits for the fractional part)
#define FX_SHIFT 8
#define SHIFTED_1 ((uint8_t)255)
/** A resonant low pass filter for audio signals.
*/
class LowPassFilter
{
public:
/** Constructor.
*/
LowPassFilter()
{
;
}
/** Set the cut off frequency,
@param cutoff use the range 0-255 to represent 0-8192 Hz (AUDIO_RATE/2).
Be careful of distortion at the lower end, especially with high resonance.
*/
void setCutoffFreq(uint8_t cutoff)
{
f = cutoff;
fb = q + ucfxmul(q, SHIFTED_1 - cutoff);
}
/** Set the resonance. If you hear unwanted distortion, back off the resonance.
@param resonance in the range 0-255, with 255 being most resonant.
*/
void setResonance(uint8_t resonance)
{
q = resonance;
}
/** Calculate the next sample, given an input signal.
@param in the signal input.
@return the signal output.
@note Timing: about 11us.
*/
// 10.5 to 12.5 us, mostly 10.5 us (was 14us)
inline int next(int in)
{
//setPin13High();
buf0 += fxmul(((in - buf0) + fxmul(fb, buf0 - buf1)), f);
buf1 += ifxmul(buf0 - buf1, f); // could overflow if input changes fast
//setPin13Low();
return buf1;
}
private:
uint8_t q;
uint8_t f;
unsigned int fb;
int buf0, buf1;
// // multiply two fixed point numbers (returns fixed point)
// inline
// long fxmul(long a, long b)
// {
// return (a*b)>>FX_SHIFT;
// }
// multiply two fixed point numbers (returns fixed point)
inline unsigned int ucfxmul(uint8_t a, uint8_t b)
{
return (((unsigned int)a * b) >> FX_SHIFT);
}
// multiply two fixed point numbers (returns fixed point)
inline int ifxmul(int a, uint8_t b)
{
return ((a * b) >> FX_SHIFT);
}
// multiply two fixed point numbers (returns fixed point)
inline long fxmul(long a, int b)
{
return ((a * b) >> FX_SHIFT);
}
};
/**
@example 10.Audio_Filters/LowPassFilter/LowPassFilter.ino
This example demonstrates the LowPassFilter class.
*/
#endif /* LOWPASS_H_ */
#define POT1 8
#define POT2 9
#define POT3 10
int sensorValue1 = 0; //initialization of sensor variable, equivalent to EMA Y
float EMA_a1 = 0.8; //initialization of EMA alpha
int EMA_S1 = 0;
int sensorValue2 = 0; //initialization of sensor variable, equivalent to EMA Y
float EMA_a2 = 0.6; //initialization of EMA alpha
int EMA_S2 = 0;
int sensorValue3 = 0; //initialization of sensor variable, equivalent to EMA Y
float EMA_a3 = 0.6; //initialization of EMA alpha
int EMA_S3 = 0;
void setupPotards()
{
// setup potards
EMA_S1 = analogRead(POT1);
EMA_S2 = analogRead(POT2);
EMA_S3 = analogRead(POT3);
}
float readPot(int i)
{
switch (i)
{
case 1:
sensorValue1 = analogRead(POT1); //read the sensor value using ADC
//Serial.print(sensorValue1);
EMA_S1 = (EMA_a1 * sensorValue1) + ((1 - EMA_a1) * EMA_S1); //run the EMA
Serial.print(",");
Serial.println(EMA_S1);
return ((float)EMA_S1) / 1024.0; //the value read are between 1024 and 0, so return between 0 and 1
break;
case 2:
sensorValue2 = analogRead(POT2); //read the sensor value using ADC
EMA_S2 = (EMA_a2 * sensorValue2) + ((1 - EMA_a2) * EMA_S2); //run the EMA
return ((float)EMA_S2) / 1024.0;
break;
case 3:
sensorValue3 = analogRead(POT3); //read the sensor value using ADC
EMA_S3 = (EMA_a3 * sensorValue3) + ((1 - EMA_a3) * EMA_S3); //run the EMA
return ((float)EMA_S3) / 1024.0;
break;
default:
return 0;
break;
}
}
#include <Scheduler.h>
// Circular buffer, power of two.
#define BUFSIZE 4096 // environ 85ms de buffer à 48kHz //0x400
#define BUFMASK 4096 //taille tampon - 1
volatile int samples[BUFSIZE];
volatile int sptr = 0;
#include "LowPassFilter.h"
#include <SPI.h>
#include <Wire.h>
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include "Adafruit_STMPE610.h"
bool f1active = false;
LowPassFilter lpf;
volatile int lpfCutoffFreq = 8000;
volatile int lpfResonance = 100;
#include "Button.h"
#include "Ecran.h"
#include "Leds.h"
#include "Potards.h"
void setup()
{
Serial.begin(9600);
// setup the filter, the leds and the pots
lpf.setResonance(100);
lpf.setCutoffFreq(lpfCutoffFreq * 255 / (48000 / 2));
ledSetup();
setupPotards();
allLedsOn();
adc_setup(); // setup ADC
// setup the clock module that will set the timing for all interrupts
pmc_enable_periph_clk(TC_INTERFACE_ID + 0 * 3 + 0); // clock the TC0 channel 0
TcChannel *t = &(TC0->TC_CHANNEL)[0]; // pointer to TC0 registers for its channel 0
t->TC_CCR = TC_CCR_CLKDIS; // disable internal clocking while setup regs
t->TC_IDR = 0xFFFFFFFF; // disable interrupts
t->TC_SR; // read int status reg to clear pending
t->TC_CMR = TC_CMR_TCCLKS_TIMER_CLOCK1 | // use TCLK1 (prescale by 2, = 42MHz)
TC_CMR_WAVE | // waveform mode
TC_CMR_WAVSEL_UP_RC | // count-up PWM using RC as threshold
TC_CMR_EEVT_XC0 | // Set external events from XC0 (this setup TIOB as output)
TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_CLEAR |
TC_CMR_BCPB_CLEAR | TC_CMR_BCPC_CLEAR;
t->TC_RC = 1000; //875 ; // counter resets on RC, so sets period in terms of 42MHz clock
t->TC_RA = 500; //440 ; // roughly square wave
t->TC_CMR = (t->TC_CMR & 0xFFF0FFFF) | TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_SET; // set clear and set from RA and RC compares
t->TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG; // re-enable local clocking and switch to hardware trigger source.
dac_setup(); // setup up DAC auto-triggered at 48kHz
// setup of the TFT touch screen
pinMode(10, OUTPUT);
if (!touch.begin())
{
Serial.println("STMPE not found!");
while (1)
;
}
tft.begin();
tft.setRotation(1);
Serial.print("TFT screen dimensions : w:");
Serial.print(tft.width());
Serial.print(" h:");
Serial.println(tft.height());
// read diagnostics (optional but can help debug problems)
uint8_t x = tft.readcommand8(ILI9341_RDMODE);
Serial.print("Display Power Mode: 0x");
Serial.println(x, HEX);
x = tft.readcommand8(ILI9341_RDMADCTL);
Serial.print("MADCTL Mode: 0x");
Serial.println(x, HEX);
x = tft.readcommand8(ILI9341_RDPIXFMT);
Serial.print("Pixel Format: 0x");
Serial.println(x, HEX);
x = tft.readcommand8(ILI9341_RDIMGFMT);
Serial.print("Image Format: 0x");
Serial.println(x, HEX);
x = tft.readcommand8(ILI9341_RDSELFDIAG);
Serial.print("Self Diagnostic: 0x");
Serial.println(x, HEX);
//displaying the good screen type
switch (screenType)
{
case ScreenType::Splash:
drawSplash();
break;
case ScreenType::Main:
drawMain();
break;
}
Serial.println("");
emptyTouchBuffer();
Scheduler.startLoop(loopUI);
Scheduler.startLoop(loopPotard);
//Scheduler.startLoop(loopPotard2);
allLedsOff();
}
void dac_setup()
{
pmc_enable_periph_clk(DACC_INTERFACE_ID); // start clocking DAC
DACC->DACC_CR = DACC_CR_SWRST; // reset DAC
DACC->DACC_MR =
DACC_MR_TRGEN_EN | DACC_MR_TRGSEL(1) | // trigger 1 = TIO output of TC0
(0 << DACC_MR_USER_SEL_Pos) | // select channel 0
DACC_MR_REFRESH(0x0F) | // bit of a guess... I'm assuming refresh not needed at 48kHz
(24 << DACC_MR_STARTUP_Pos); // 24 = 1536 cycles which I think is in range 23..45us since DAC clock = 42MHz
DACC->DACC_IDR = 0xFFFFFFFF; // no interrupts
DACC->DACC_CHER = DACC_CHER_CH0 << 0; // enable chan0
}
void adc_setup()
{
NVIC_EnableIRQ(ADC_IRQn); // enable ADC interrupt vector
ADC->ADC_IDR = 0xFFFFFFFF; // disable interrupts
ADC->ADC_IER = (1 << 1); //0x80 ; // enable AD1 End-Of-Conv interrupt (Arduino pin A6)
ADC->ADC_CHDR = 0xFFFF; // disable all channels
ADC->ADC_CHER = (1 << 1); //0x80 ; // enable just A6