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.

Easy remote control

Remotely control an LED with ease. Devices and components Arduino Nano 33 BLE with headers Box 525 Resistors precision 1% - 17 values Breadb...