Skip to content

Instantly share code, notes, and snippets.

@JobLeonard
Created February 1, 2015 09:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JobLeonard/5d946760ced655ef41aa to your computer and use it in GitHub Desktop.
Save JobLeonard/5d946760ced655ef41aa to your computer and use it in GitHub Desktop.
LED-as-sensor sketch enhanced with sine-like pulse (using a lookup table)
// Lookup table for precalculated sine values - basically LUT[t % 512] == (byte)(255 * sin(2 * Pi * t / 512))
byte LUT[512] = {
0, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 2, 2, 2, 2, 3, 3,
3, 4, 4, 4, 5, 5, 6, 6,
6, 7, 7, 8, 9, 9, 10, 10,
11, 11, 12, 13, 13, 14, 15, 16,
16, 17, 18, 19, 20, 20, 21, 22,
23, 24, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38,
39, 40, 41, 43, 44, 45, 46, 47,
49, 50, 51, 52, 54, 55, 56, 57,
59, 60, 61, 63, 64, 65, 67, 68,
70, 71, 72, 74, 75, 77, 78, 80,
81, 82, 84, 85, 87, 88, 90, 91,
93, 94, 96, 97, 99, 100, 102, 104,
105, 107, 108, 110, 111, 113, 114, 116,
118, 119, 121, 122, 124, 125, 127, 128,
129, 131, 132, 134, 135, 137, 138, 140,
142, 143, 145, 146, 148, 149, 151, 152,
154, 156, 157, 159, 160, 162, 163, 165,
166, 168, 169, 171, 172, 174, 175, 176,
178, 179, 181, 182, 184, 185, 186, 188,
189, 191, 192, 193, 195, 196, 197, 199,
200, 201, 202, 204, 205, 206, 207, 209,
210, 211, 212, 213, 215, 216, 217, 218,
219, 220, 221, 222, 223, 224, 225, 226,
227, 228, 229, 230, 231, 232, 233, 234,
235, 236, 236, 237, 238, 239, 240, 240,
241, 242, 243, 243, 244, 245, 245, 246,
246, 247, 247, 248, 249, 249, 250, 250,
250, 251, 251, 252, 252, 252, 253, 253,
253, 254, 254, 254, 254, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 254, 254, 254, 254, 253, 253,
253, 252, 252, 252, 251, 251, 250, 250,
250, 249, 249, 248, 247, 247, 246, 246,
245, 245, 244, 243, 243, 242, 241, 240,
240, 239, 238, 237, 236, 236, 235, 234,
233, 232, 231, 230, 229, 228, 227, 226,
225, 224, 223, 222, 221, 220, 219, 218,
217, 216, 215, 213, 212, 211, 210, 209,
207, 206, 205, 204, 202, 201, 200, 199,
197, 196, 195, 193, 192, 191, 189, 188,
186, 185, 184, 182, 181, 179, 178, 176,
175, 174, 172, 171, 169, 168, 166, 165,
163, 162, 160, 159, 157, 156, 154, 152,
151, 149, 148, 146, 145, 143, 142, 140,
138, 137, 135, 134, 132, 131, 129, 128,
127, 125, 124, 122, 121, 119, 118, 116,
114, 113, 111, 110, 108, 107, 105, 104,
102, 100, 99, 97, 96, 94, 93, 91,
90, 88, 87, 85, 84, 82, 81, 80,
78, 77, 75, 74, 72, 71, 70, 68,
67, 65, 64, 63, 61, 60, 59, 57,
56, 55, 54, 52, 51, 50, 49, 47,
46, 45, 44, 43, 41, 40, 39, 38,
37, 36, 35, 34, 33, 32, 31, 30,
29, 28, 27, 26, 25, 24, 23, 22,
21, 20, 20, 19, 18, 17, 16, 16,
15, 14, 13, 13, 12, 11, 11, 10,
10, 9, 9, 8, 7, 7, 6, 6,
6, 5, 5, 4, 4, 4, 3, 3,
3, 2, 2, 2, 2, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1};
class Firefly {
public:
unsigned int N, P, measurements, totalmeasurements;
unsigned long count, totalcount, lastval;
boolean measuring;
Firefly(unsigned int _N, unsigned int _P, int tm):
N(_N),
P(_P),
measurements(0), // To make the measurements more stable, average over a number of them - measurements keeps track of how many have been made
totalmeasurements(tm), // indicates total amoun of measurements to be made.
count(0), // count = totalcount/totalmeasurements
totalcount(0), // cumulative count of loops measured since the beginning of a set of measurements
lastval(0), // lastval = previous result of a finished measurement (so previous final count value)
measuring(false) // whether we are measuring or pulsing
{
}
void initmeasurement(){
count = totalcount = measurements = 0;
chargeLED();
measuring = true;
}
unsigned long measure(){
// Keep counting while N hasn't emptied out it's charge yet
if (digitalRead(N) != 0){
count++;
}
else {
// add the counted loops of this measurement to totalcount
totalcount += count;
if (++measurements < totalmeasurements){ //Yes, the prefix increment is on purpose
chargeLED();
count = 0;
}
else {
// we've measured as much as we need for this cycle, so average out the results
count = lastval = totalcount/totalmeasurements;
measuring = false;
// Set the pins to LED mode
digitalWrite(P,LOW);
pinMode(P,OUTPUT);
digitalWrite(N,LOW);
pinMode(N,OUTPUT);
}
}
// always return the last stable finished average measurement cycle
return lastval;
}
// Set the pins to Measuring mode
void chargeLED(){
// Apply reverse voltage, charge up the pin and led capacitance
pinMode(N,OUTPUT);
pinMode(P,OUTPUT);
digitalWrite(N,HIGH);
digitalWrite(P,LOW);
// Isolate the pin 2 end of the diode
pinMode(N,INPUT);
// turn off internal pull-up resistor
digitalWrite(P,LOW);
}
void pulse(){
// count starts equivalent to lastval. We pulse once by decrementing to zero once per loop,
// meaning the pulse lasts longer the bigger count is
// 'count*511/lastval' scales count to the period of the LUT
analogWrite(P, LUT[count*511/lastval]);
if (count-- == 0){ //Yes, the postfix decrement is on purpose
initmeasurement();
}
}
void update(){
if (measuring){
measure();
}
else {
pulse();
}
}
};
#define LED_N_SIDE 2
#define LED_P_SIDE 3
Firefly blinker = Firefly(LED_N_SIDE, LED_P_SIDE, 8);
void setup()
{
}
void loop()
{
blinker.update();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment