QC

Storage of tape recorder data

Modify a tape recorder to allow data to be saved and replayed. (concept)

Devices and components

Arduino Uno Rev3

NHD-0216K1Z-FS(RGB)-FBW-REV1-ND

Shoebox tape recorder

Software and tools

Arduino IDE

Project description

The tape recorder!

Set up

Using the included functions

Recorder code

For arduino uno rev3

1#include <LiquidCrystal.h>
2
3const int BUTTON = 13; //user interface button
4const int PLAY = 10; //motor that allows the tape to play
5const int MICROPHONEOUT = 9; //the connection to the recorder's microphone
6const int SPEAKERIN = A0; //the connection to the recorder's speaker
7
8const String SPACES = " "; //allows formatting of line position to be easier
9const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2; //pin inputs for lcd
10const String modes[] = //string of different modes for displaying
11{"Wave Test", "Write Test", "Read Test", "Allow Play", "Set Write String"};
12
13
14LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
15
16void setup() {
17 pinMode(BUTTON, INPUT); //button is user input
18 pinMode(PLAY, OUTPUT); //outputs signal for recorder to play
19 pinMode(SPEAKERIN, INPUT); //allows input from recorder's speaker
20 pinMode(MICROPHONEOUT, OUTPUT); //outputs to recorder's microphone
21
22 Serial.begin(9600); //begin serial for debugging
23 Serial.println("");
24 lcd.begin(16, 2); //begin lcd for text output
25
26 lcd.print("hello, world!"); //template text
27 digitalWrite(MICROPHONEOUT,LOW); //keep microphone as low
28}
29
30String outputdata = ""; //string of currently outputted data
31double bitTotal = 0; //total of signalStrengths read during this second
32long currentMillis = 0; //last recorded time in Milliseconds
33int buttonVal = LOW; //state of button input
34int speakerValOld; //last speaker output
35int speakerValNew = 0; //current speaker output
36int speakerIn; //speaker input
37int modeIndex = 0; //a temporary useVal for the use of mode select
38int lastButtonVal = LOW; //used to detect falling edge
39long buttonHeldStart = 0; //used to detect length of button hold
40bool changemode = false; //used to allow falling edge change mode
41
42long timestamp = 0;
43int useVal = -1; //Value that determines what function should be used (Wave Test, Record Data, Read Data)
44long timer = 0;
45bool runSequence = false;
46
47String player = "1110100100001001001"; //values to be written when writing data, default is internal values.
48
49//formats output by Wave Test
50void waveformPrint(int av, int l) {
51 lcd.setCursor(0, l);
52 if (av < 0) {
53 lcd.print(SPACES.substring(0,8+av) + "x ");
54 }
55 else {
56 lcd.print(SPACES + SPACES.substring(0,av) + "x ");
57 }
58}
59
60//called every possible time while attempting to read data
61void datapointadd(int add) {
62 //if 1 second has passed
63 if (millis() - 1000 > currentMillis) {
64 lcd.setCursor(0, 1);
65 outputdata+=String(round(bitTotal/60)); //add 1 to outputdata if over the last second the total value of summed signals is >= 30, else add 0
66 if (outputdata.length() > 16) outputdata.remove(0, 1); //if outputdata is longer than 16 bits, remove the "first" bit.
67 bitTotal = 0; //reset count of bits to 0
68 currentMillis = millis(); //start next 1 second count by updating currentMillis
69 }
70 bitTotal+=add*1; //(called every possible chance) add current outputed value to bitTotal
71}
72
73//used to activate or deactivate playing when required
74void play(int play) {
75 if (play == HIGH) {
76 digitalWrite(PLAY,HIGH); //start playing
77 }
78 else {
79 digitalWrite(PLAY,LOW); //stop playing
80 }
81}
82
83
84
85//looped functions
86void allowPlay() {
87 digitalWrite(MICROPHONEOUT,LOW); //keep microphone as low
88 lcd.setCursor(0, 0);
89 lcd.print("Play Mode"); //display current mode
90 play(buttonVal); //if button pushed, play, else dont
91}
92
93void waveTest() {
94 //lcd.setCursor(0, 0);
95 //lcd.print("Audio Wave Mode"); //display current mode
96 play(buttonVal); //activate play based on user button input
97
98 speakerValOld = speakerValNew;
99 waveformPrint(speakerValOld, 0);
100 delay(100);
101
102 speakerIn = speakerValNew = analogRead(SPEAKERIN)-513; //-513 centers rectified ac signal input
103 waveformPrint(speakerValNew, 1);
104 delay(100);
105}
106
107void writeTest() {
108 lcd.setCursor(0, 0);
109 lcd.print("Record Data Mode"); //display current mode
110 lcd.setCursor(0, 1);
111
112 if (buttonVal == HIGH && !runSequence) runSequence = true; //if button is pressed and not recording, start recording
113
114 if (runSequence && timestamp < player.length()) { //while recording, and there is more data to write
115 play(HIGH); //allow tape to play
116 Serial.print(player[timestamp]-'0'); //print the bit written
117 lcd.print(player[timestamp]); //display the written bit
118 digitalWrite(MICROPHONEOUT,player[timestamp]-'0'); //write bit to recorder's microphone
119 delay(1000); //write for 1 second
120 timestamp+=1; //increment place in bitstring
121 }
122 else if (timestamp >= player.length()) { //if no more data to write
123 runSequence = false; //stop recording
124 play(LOW); //stop playing
125 digitalWrite(MICROPHONEOUT,LOW); //stop writing
126 useVal = -1; //exit mode
127 }
128}
129
130void readTest() {
131 lcd.setCursor(0, 0);
132 lcd.print("Read Data Mode"); //display current mode
133 play(buttonVal); //activate play based on user button input
134
135 ////Read Test if playing
136 if(buttonVal == HIGH) {
137 //if given speaker output > 10, declare 1 was read, else declare 0, and print outputdata formatted by datapointadd to the lcd
138 lcd.setCursor(0, 1);
139 if (abs(analogRead(SPEAKERIN)-513) > 10) {
140 datapointadd(1);
141 }
142 else
143 {
144 datapointadd(0);
145 }
146 lcd.print(outputdata);
147 }
148}
149
150void setString() {
151 lcd.setCursor(0, 0);
152 lcd.print("Set Write Mode"); //display current mode
153 if (!runSequence) { //Reset player only once
154 player = "";
155 runSequence = true;
156 }
157 lcd.setCursor(0, 1);
158 if (player.length() <= 16) lcd.print(player); //display current inputted value
159 else lcd.print(player.substring(player.length()-16)); //display only 16 most recent values of player
160
161 ////
162 if (buttonVal == LOW && lastButtonVal == HIGH) { //on falling edge
163 if (changemode) player+="1"; //if button was last held, add a 1 to the player
164 else player+="0"; //else add a 0 on falling edge
165 }
166 changemode = false;
167 if (buttonVal == HIGH && lastButtonVal == LOW) { //on rising edge
168 buttonHeldStart = millis(); //start count
169 }
170 //while button is held, and if the button has been held for more than .5 seconds, allow 1 written on falling edge
171 if (buttonVal == HIGH && millis()-500 > buttonHeldStart && millis() > 500) {
172 changemode = true;
173 }
174 //while button is held, and if the button has been held for more than 5 seconds, exit mode
175 if (buttonVal == HIGH && millis()-5000 > buttonHeldStart && millis() > 5000) {
176 useVal = -1; //switch back to other mode
177 buttonHeldStart = millis(); //make sure program doesn't instantly switch back after reset
178 return; //exit this execution here
179 }
180 lastButtonVal = buttonVal;
181 ////
182
183}
184
185void modeSelect() {
186 runSequence = false;
187 lcd.setCursor(0, 0);
188 lcd.print(modes[modeIndex] + " "); //display current mode
189 lcd.setCursor(0, 1);
190 if (modeIndex < sizeof(modes) / sizeof(modes[0]) - 1) {lcd.print(modes[modeIndex+1] + " ");} //display next mode
191 else {lcd.print(modes[0] + " ");} //if next mode loops, loop
192
193 if (buttonVal == LOW && lastButtonVal == HIGH) { //on falling edge
194 if (changemode) {
195 useVal = modeIndex; //if button was last held, change the mode
196 lcd.clear(); //and clear the lcd
197 }
198 else {
199 modeIndex+=1; //increase mode index
200 if (modeIndex == sizeof(modes) / sizeof(modes[0])) modeIndex = 0; //and loop if needed
201 }
202 }
203
204 changemode = false;
205
206 if (buttonVal == HIGH && lastButtonVal == LOW) { //on rising edge
207 buttonHeldStart = millis();
208 }
209 //while button is held, and if the button has been held for more than 2 seconds, change mode to selected mode on falling edge
210 if (buttonVal == HIGH && millis()-2000 > buttonHeldStart && millis() > 2000) {
211 changemode = true;
212 }
213
214 lastButtonVal = buttonVal;
215}
216
217//loop
218void loop() {
219 buttonVal = digitalRead(BUTTON); //read user button input
220
221 ////Mode Select
222 if (useVal == -1) modeSelect();
223
224 ////Wave Test
225 if (useVal == 0) waveTest();
226
227 ////Write Test
228 if (useVal == 1) writeTest();
229
230 ////Read Test always
231 if(useVal == 2) readTest();
232
233 ////allow play
234 if (useVal == 3) allowPlay();
235
236 ////Write String
237 if (useVal == 4) setString();
238
239}

Documentation

Tinker Cad Circuit Diagram

Tinker Cad Circuit Diagram, Code, and Notes

https://www.tinkercad.com/things/eGUmPQWNuvY




Note: Content and images are from: https://projecthub.arduino.cc/, with some modifications.
If you want it removed due to copyright reasons, please leave a comment. Thank you.
I want to share this article more widely so that everyone knows about Arduino and your project.

SendData

Điều khiển trạng thái qua Firebase Trạng thái hiện tại: Đang tải... ĐỔI TRẠNG THÁI