Skip to content

Commit ed3df92

Browse files
authored
Add files via upload
1 parent f61a7cd commit ed3df92

File tree

2 files changed

+228
-0
lines changed

2 files changed

+228
-0
lines changed
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// SPDX-FileCopyrightText: 2018 Mikey Sklar for Adafruit Industries
2+
//
3+
// SPDX-License-Identifier: MIT
4+
5+
/* Trinket/Gemma compatible IR read sketch
6+
This sketch/program uses an Adafruit Trinket or Gemma
7+
ATTiny85 based mini microcontroller and a PNA4602 or TSOP38238 to
8+
read an IR code and perform a function. In this
9+
test program, tones are generated to a piezo speaker
10+
but you can use codes to trigger any function you wish.
11+
Based on Adafruit tutorial http://learn.adafruit.com/ir-sensor/using-an-ir-sensor
12+
and http://learn.adafruit.com/trinket-gemma-mini-theramin-music-maker
13+
*/
14+
15+
// We need to use the 'raw' pin reading methods because timing is very important here
16+
// and the digitalRead() procedure is slower!
17+
#define IRpin_PIN PINB // ATTiny85 had Port B pins
18+
#define IRpin 2 // IR sensor - TSOP38238 on Pin GPIO #2 / D2
19+
#define SPEAKERPIN 1 // Piezo speaker on Trinket/Gemma Pin GPIO #1/D1
20+
21+
#define MAXPULSE 5000 // the maximum pulse we'll listen for - 5 milliseconds
22+
#define NUMPULSES 100 // max IR pulse pairs to sample
23+
#define RESOLUTION 2 // // time between IR measurements
24+
25+
// we will store up to 100 pulse pairs (this is -a lot-, reduce if needed)
26+
uint16_t pulses[100][2]; // pair is high and low pulse
27+
uint16_t currentpulse = 0; // index for pulses we're storing
28+
uint32_t irCode = 0;
29+
30+
void setup() {
31+
pinMode(IRpin, INPUT); // Listen to IR receiver on Trinket/Gemma pin D2
32+
pinMode(SPEAKERPIN, OUTPUT); // Output tones on Trinket/Gemma pin D1
33+
}
34+
35+
void loop() {
36+
37+
irCode=listenForIR(); // Wait for an IR Code
38+
39+
// Process the pulses to get our code
40+
for (int i = 0; i < 32; i++) {
41+
irCode=irCode<<1;
42+
if((pulses[i][0] * RESOLUTION)>0&&(pulses[i][0] * RESOLUTION)<500) {
43+
irCode|=0;
44+
} else {
45+
irCode|=1;
46+
}
47+
}
48+
if(irCode==0xe0c8A2DD) { // "1" on my remote, USE YOUR CODE HERE
49+
beep(SPEAKERPIN,400,500); } // Make a 400 Hz beep
50+
else if (irCode==0xe0c8a3dc) { // "2", USE YOUR OWN HEX CODE HERE
51+
beep(SPEAKERPIN,500,500); } // Make a 500 Hz beep
52+
else if (irCode==0xe0c8a41b) { // "3", USE YOUR OWN HEX CODE HERE
53+
beep(SPEAKERPIN,600, 500); } // Make a 600 Hz beep
54+
else if (irCode==0xe0c8a29d) { // "4", USE YOUR OWN HEX CODE HERE
55+
beep(SPEAKERPIN, 700, 500); // Make a 700 Hz beep
56+
}
57+
58+
} // end loop
59+
60+
61+
uint16_t listenForIR() { // IR receive code
62+
currentpulse = 0;
63+
while (1) {
64+
unsigned int highpulse, lowpulse; // temporary storage timing
65+
highpulse = lowpulse = 0; // start out with no pulse length
66+
67+
while (IRpin_PIN & _BV(IRpin)) { // got a high pulse
68+
highpulse++;
69+
delayMicroseconds(RESOLUTION);
70+
if (((highpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) {
71+
return currentpulse;
72+
}
73+
}
74+
pulses[currentpulse][0] = highpulse;
75+
76+
while (! (IRpin_PIN & _BV(IRpin))) { // got a low pulse
77+
lowpulse++;
78+
delayMicroseconds(RESOLUTION);
79+
if (((lowpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) {
80+
return currentpulse;
81+
}
82+
}
83+
pulses[currentpulse][1] = lowpulse;
84+
currentpulse++;
85+
}
86+
}
87+
88+
// Generate a tone on speakerPin - Trinket/Gemma/ATTiny85 compatible
89+
void beep (unsigned char speakerPin, int frequencyInHertz, long timeInMilliseconds)
90+
{ // http://web.media.mit.edu/~leah/LilyPad/07_sound_code.html
91+
int x;
92+
long delayAmount = (long)(1000000/frequencyInHertz);
93+
long loopTime = (long)((timeInMilliseconds*1000)/(delayAmount*2));
94+
for (x=0;x<loopTime;x++)
95+
{
96+
digitalWrite(speakerPin,HIGH);
97+
delayMicroseconds(delayAmount);
98+
digitalWrite(speakerPin,LOW);
99+
delayMicroseconds(delayAmount);
100+
}
101+
}
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# SPDX-FileCopyrightText: 2018 Mikey Sklar for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
"""
6+
IR codes for button 0, 1, 2, 3 these were acquired from the
7+
Adafruit Mini Remote Control #389
8+
https://www.adafruit.com/product/389
9+
stored as a 2D list
10+
these codes were collected from running IR_reader.py
11+
and watching the output on the REPL console
12+
"""
13+
14+
import time
15+
16+
import adafruit_irremote
17+
import board
18+
import pulseio
19+
import simpleio
20+
21+
speaker_pin = board.D0 # speaker connected to digital pin
22+
ir_pin = board.D2 # pin connected to IR receiver.
23+
24+
fuzzyness = 0.2 # IR remote timing must be within 20% tolerance
25+
26+
button_presses = [
27+
28+
[
29+
9073, 4504, 575, 589, 557, 581, 546, 592, 553, 585, 542, 595,
30+
550, 588, 552, 588, 544, 591, 549, 1671, 579, 1669, 572, 1675,
31+
577, 1671, 570, 1678, 574, 1673, 579, 559, 572, 1676, 575, 589,
32+
542, 596, 546, 1674, 577, 1671, 571, 567, 574, 590, 552, 586,
33+
545, 593, 548, 1672, 569, 1678, 574, 591, 550, 588, 550, 1670,
34+
575, 1673, 579, 1671, 570, 1675, 586
35+
],
36+
37+
[
38+
9075, 4498, 571, 566, 575, 562, 569, 569, 573, 564, 577, 587, 544,
39+
567, 577, 587, 551, 586, 545, 1675, 577, 1671, 575, 1672, 574, 1674,
40+
580, 1668, 572, 1675, 576, 589, 542, 1678, 574, 564, 577, 588, 543,
41+
594, 547, 591, 551, 1669, 572, 592, 553, 585, 542, 595, 550, 1671,
42+
577, 1670, 571, 1677, 575, 1673, 569, 576, 565, 1675, 577, 1670, 572,
43+
1676, 575
44+
],
45+
46+
[
47+
9070, 4505, 574, 563, 578, 559, 572, 566, 575, 562, 569, 569, 573, 564,
48+
577, 561, 570, 567, 575, 1674, 578, 1669, 577, 1670, 577, 1670, 571,
49+
1677, 575, 1672, 569, 569, 573, 1674, 577, 1671, 571, 566, 575, 562,
50+
569, 575, 566, 1675, 577, 560, 571, 567, 574, 563, 568, 569, 573, 1675,
51+
576, 1671, 571, 1681, 571, 562, 569, 1679, 575, 1672, 578, 1670, 570
52+
],
53+
54+
[
55+
9080, 4500, 569, 568, 573, 564, 577, 561, 570, 567, 574, 564, 578, 559,
56+
577, 561, 575, 562, 579, 1669, 572, 1675, 577, 1671, 570, 1677, 575,
57+
1673, 578, 1672, 570, 570, 571, 1671, 574, 564, 574, 1678, 573, 560,
58+
571, 568, 574, 1671, 570, 568, 573, 564, 577, 561, 570, 1677, 575, 563,
59+
578, 1669, 572, 1676, 576, 561, 570, 1677, 574, 1674, 578, 1669, 572
60+
]
61+
62+
]
63+
64+
65+
def fuzzy_pulse_compare(received):
66+
# Did we receive a full IR code?
67+
# Should be 67 timings for this remote
68+
if len(received) == len(button_presses[0]):
69+
70+
# compare received IR code with our stored button_press list
71+
# remote control button codes for : [0-3]
72+
for b_index, button_press in enumerate(button_presses):
73+
74+
# compare individual timings for each IR code
75+
# confirm that every entry is within fuzzyness 20% accuracy
76+
for i, press in enumerate(button_press):
77+
78+
threshold = int(press * fuzzyness)
79+
80+
if abs(press - received[i]) < threshold:
81+
match_count[b_index] += 1
82+
83+
84+
def play_tone():
85+
""" half second tones based on button selection [0-3] """
86+
if remote_control_press == 0:
87+
simpleio.tone(speaker_pin, 400, .5) # 400Hz beep, 1/2 sec
88+
89+
elif remote_control_press == 1:
90+
simpleio.tone(speaker_pin, 500, .5) # 500Hz beep, 1/2 sec
91+
92+
elif remote_control_press == 2:
93+
simpleio.tone(speaker_pin, 600, .5) # 600Hz beep, 1/2 sec
94+
95+
elif remote_control_press == 3:
96+
simpleio.tone(speaker_pin, 700, .5) # 700Hz beep, 1/2 sec
97+
98+
99+
# Create pulse input and IR decoder.
100+
pulses = pulseio.PulseIn(ir_pin, maxlen=200, idle_state=True)
101+
decoder = adafruit_irremote.GenericDecode()
102+
103+
# Loop waiting to receive pulses.
104+
while True:
105+
# total count of IR code matches for each button {0, 1, 2, 3}
106+
match_count = [0] * len(button_presses)
107+
108+
# make sure pulses is empty
109+
pulses.clear()
110+
pulses.resume()
111+
time.sleep(.1)
112+
113+
# Wait for a pulse to be detected.
114+
detected = decoder.read_pulses(pulses)
115+
116+
fuzzy_pulse_compare(detected)
117+
118+
# confirm that we know this button
119+
# received IR code compared with saved button_presses
120+
# 100% match (+/- fuzziness)
121+
# otherwise we don't know this button pressed
122+
if max(match_count) == len(button_presses[0]):
123+
remote_control_press = match_count.index(max(match_count))
124+
play_tone()
125+
print(match_count.index(max(match_count)))
126+
else:
127+
print("unknown button")

0 commit comments

Comments
 (0)