synth_panel/tests/arduino_touchscreen_test/arduino_touchscreen_test.ino
2019-12-16 00:00:41 +01:00

165 lines
3.0 KiB
C++

uint8_t duty = 50; // start @ 50 % duty
float freq = 0.44; // start @ 440 hz
void set_duty(uint8_t d) {
duty = 100- d;
update_freq();
}
void set_freq(float f) {
freq = f;
update_freq();
}
void update_freq() {
uint16_t top = freq/0.440*142/2;
OCR2A = (top>0xFF)?0xFF:top;
OCR2B = top * duty / 100;
}
void setup_timer() {
// setup timer
update_freq();
TCCR2A= (1<<COM2B1) | (1<<WGM20);
TCCR2B= (1<<WGM22) | (1<<CS02); // 64 prescaler ( 5khz == TOP of 50, 1khz = 250 )
DDRD |= (1<<PD3);
}
void setup() {
setup_timer();
Serial.begin(9600);
Serial.println("setup complete");
interrupts();
}
#include <EEPROM.h>
class Panel {
int maxVals[2];
struct limits {
int touchThreas;
int minVals[2];
float range[2];
bool caldone;
} limits;
public:
Panel():maxVals{1,1} {
// declare pins as input
DDRC &= ~((1<<PC0) | (1<<PC1) | (1<<PC2) | (1<<PC3));
EEPROM.get(0, limits);
}
enum Axis {
X = 0,
Y
};
int operator()(Axis axis) {
int result = -1;
switch(axis) {
case X:
DDRC |= (1<<PC0) | (1<<PC2);
PORTC |= (1<<PC0) | (1<<PC1) ;
delay(1);
result = analogRead(A1);
break;
case Y:
DDRC |= (1<<PC1) | (1<<PC3);
PORTC |= (1<<PC0) | (1<<PC1) ;
delay(1);
result = analogRead(A2);
break;
}
PORTC = 0;
DDRC = 0;
return result;
}
float normalized(Axis axis) {
if (!limits.caldone)
return 0;
return ((*this)(axis)- limits.minVals[axis] )/ limits.range[axis];
}
void calibrate() {
static int state = 0;
switch(state++) {
case 0:
limits.touchThreas = (*this)(X) - 10;
break;
case 1:
limits.minVals[X] = (*this)(X);
limits.minVals[Y] = (*this)(Y);
break;
case 2:
maxVals[X] = (*this)(X);
maxVals[Y] = (*this)(Y);
default:
limits.range[X] = maxVals[X] - limits.minVals[X];
limits.range[Y] = maxVals[Y] - limits.minVals[Y];
limits.caldone = 1;
Serial.println("calibration complete");
EEPROM.put(0, limits);
state = 0;
}
}
operator bool() {
return ((*this)(X) < limits.touchThreas) || ((*this)(Y) < limits.touchThreas);
}
} panel;
bool newline = true;
int sigmal = 0;
int mu = 0;
void loop() {
// put your main code here, to run repeatedly:
if (panel) {
float x = panel.normalized(Panel::X),
y = panel.normalized(Panel::Y);
int n = x*12;
//float freq = powf(1.0595, n - 9) * 0.440;
float freq = powf(1.0905, n - 6) * 0.440;
// Serial.print(n);
// Serial.print("\t");
// Serial.println(freq);
//analogWrite(11, 255*panel.normalized(Panel::X));
set_freq(freq);
set_duty(y*100);
} else {
set_duty(100);
}
while(Serial.available()) {
char c = Serial.read();
if (newline && c == 'c') {
panel.calibrate();
newline = false;
} else if (!newline && c == '\n') {
newline = true;
}
}
//delay(100);
}