Compare commits

...

2 Commits

Author SHA1 Message Date
Savanni D'Gerinel 0971859f46 Add calibration code 2023-07-12 22:32:53 -04:00
Savanni D'Gerinel ed3c2a3c86 Set up an experimental touch sensor app 2023-07-11 23:09:42 -04:00
2 changed files with 118 additions and 0 deletions

View File

@ -284,6 +284,30 @@
];
};
packages."x86_64-linux"."touch-sensor_" =
let
pkgs = import nixpkgs { system = "x86_64-linux"; };
avr = pkgs.pkgsCross.avr.buildPackages;
in packages."x86_64-linux"."touch-sensor" { gcc = "${avr.gcc}/bin/avr-gcc"; cflags = mcu_cflags attiny85; avr = true; };
packages."x86_64-linux"."touch-sensor" =
{ gcc, cflags, avr }:
let
pkgs = import nixpkgs { system = "x86_64-linux"; };
in mkProgram {
pkgs = pkgs;
gcc = gcc;
cflags = cflags;
pname = "touch-sensor";
psrc = ./touch-sensor;
inherit avr;
pbuildInputs = [
(packages."x86_64-linux"."dio" { inherit gcc cflags; })
(packages."x86_64-linux"."display" { inherit gcc cflags; })
(packages."x86_64-linux"."shift-register" { inherit gcc cflags; })
];
};
devShell."x86_64-linux" =
let
pkgs = import nixpkgs { system = "x86_64-linux"; };

94
touch-sensor/main.c Normal file
View File

@ -0,0 +1,94 @@
#include <dio.h>
#include <stdio.h>
#include <display.h>
uint32_t read_capacitance(dio_t *dio) {
uint32_t i;
dio_set_direction(dio, LINE_OUT);
dio_set(dio, 1);
i = 0;
dio_set_direction(dio, LINE_IN);
while (dio_read(dio) > 0) i++;
return i;
}
uint32_t calibrate(dio_t *dio) {
uint32_t max = 0;
for (uint8_t i = 0; i < 100; i++) {
uint8_t cap = read_capacitance(dio);
max = cap > max ? cap : max;
_delay_ms(10);
}
return max;
}
int main(void) {
dio_t sensor = (dio_t){ .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 0 };
display_t display = {
.reg = {
.output = { .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 4 },
.shift_clock = { .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 3 },
.latch_clock = { .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 2 },
},
};
display_init(&display);
display_enable(&display);
display_clear(&display);
// calibration
//
// 100 times:
// Output 1
// Switch to Input
// measure in a loop until the input is 0
// save the measurement
//
// normal function
// Output 1
// Switch to input
// measure in a loop until the input is 0
// check against the saved measurement
// enable pin if significantly higher than the saved measurement
// update the average
MCUCR |= _BV(PUD);
uint8_t calibration_countdown = 0;
uint32_t calibration = 0;
bool touch = false;
while (1) {
if (calibration_countdown == 0 && !touch) {
calibration = calibrate(&sensor);
calibration_countdown = 100;
char msg[20];
snprintf(msg, 20, "calib: %6ld", calibration);
display_set_location(&display, 0, 0);
display_write_message(&display, msg);
}
uint32_t cap = read_capacitance(&sensor);
if (cap > calibration) {
display_set_location(&display, 1, 0);
display_write_message(&display, "touch!");
touch = true;
} else if (touch) {
display_set_location(&display, 1, 0);
display_write_message(&display, " ");
touch = false;
}
if (calibration_countdown > 0) {
calibration_countdown--;
}
_delay_ms(100);
}
}