Components and supplies
4051 multiplexer 8-channel IC
10 kOhm bussed resistive network (4 or 5 lines + common)
Arduino UNO
Dip Switch package (4 lines)
Project description
Code
Arduino sketch to read the 8-Byte ROM and show its content on an LCD display
arduino
1/* 2 3DIP/DIL Switch-based 8-Byte ROM via daisy-chained 4051 multiplexers and Arduino 4 5Circuit and comments: 6See http://www.cesarebrizio.it/Arduino/DIP_Switch_ROM.html 7Circuit is as illustrated here:http://www.cesarebrizio.it/Arduino/Final%20Fritzing%20Schema.jpg 8 9 created 03 Feb 2019 10 by Cesare Brizio 11 modified ---- 12 13This example code is in the public domain. 14 15Originally conceived as a tribute to the hand-sewn Core Rope memories of the Apollo Guidance Computer, 16my idea was successively simplified to “find a way to store a short character string in a series of 17DIP switches, then retrieve and display that text via an Arduino UNO”. 18 19I was inspired by (or better: I plagiarized) the schematics by PaulRB and the project described here: 20https://forum.arduino.cc/index.php?topic=446780.0 21 22I have 64 DIP switches, each one capable of storing a bit of information, in eaght groups of eight switches 23(closed = non-null voltage reading = binary 1 - opened = null voltage reading = binary 0) 24 25Each group of eight switches, that I will call a "Byte", is connected to the eight I/O channels of a 26separate "slave" 4051. 27 28The three address lines S0/S1/S2 of all the slave multiplexers are common: one S0, one S1, and one S2 address all 29the slave multiplexers simultaneously 30 31I am using a master multiplexer 4051 whose I/O channels are connected to the com out/in of each slave multiplexer 32Thus, by a two-step process: 33a) select the "byte" (=slave multiplexer) to read via the S0/S1/S2 of the master 4051 34b) select which "bit" to read from each slave via the common S0/S1/S2 of the slave 4051's 35I can access one switch at a time and make individual reading. 36 37As each byte is meant to store an 8-bit ASCII character, I compose the bytes by the successive readings from 38their bits, and translate them into ASCII values, that are added to the string. 39 40The string obtained is displayed on an LCD display driven by Arduino. 41 42By changing the open/closed DIP switch configuration, I can vary the displayed string in real time. 43 44 45 ========================== 46 The circuit for LCD board: 47 ========================== 48 * LCD RS pin to digital pin 15 49 * LCD Enable pin to digital pin 14 50 * LCD D4 pin to digital pin 5 51 * LCD D5 pin to digital pin 4 52 * LCD D6 pin to digital pin 3 53 * LCD D7 pin to digital pin 2 54 * LCD R/W pin to ground 55 * LCD VSS pin to ground 56 * LCD VCC pin to 5V 57 * 10K resistor: 58 * ends to +5V and ground 59 * wiper to LCD VO pin (pin 3) 60 61*/ 62// include the library code: 63#include <LiquidCrystal.h> 64 65// initialize the library with the numbers of the interface pins 66const int rs = 13, en = 12, d4 = 11, d5 = 10, d6 = 9, d7 = 8; 67LiquidCrystal lcd(rs, en, d4, d5, d6, d7); 68 69// "Slave" 4051 ADDRESS PINS : 70int slave_S0 = 2; 71int slave_S1 = 3; 72int slave_S2 = 4; 73 74// "Master" 4051 ADDRESS PINS : 75int master_S0 = 5; 76int master_S1 = 6; 77int master_S2 = 7; 78 79// 80int analogPin = A0; 81 82int ReadVolt = 0; 83 84int bitValue; 85 86int asciiCode; 87 88char asciiChar =""; 89 90int powerOfTwo = 0; 91 92char asciiString[8]; 93 94 95 96void setup() { 97 // set up the LCD's number of columns and rows: 98 lcd.begin(16, 2); 99 // Print a message to the LCD. 100 lcd.print("8-bit ROM says: "); 101 // CONFIGURE ADDRESS PINS 102 pinMode(master_S0, OUTPUT); 103 pinMode(master_S1, OUTPUT); 104 pinMode(master_S2, OUTPUT); 105 pinMode(slave_S0, OUTPUT); 106 pinMode(slave_S1, OUTPUT); 107 pinMode(slave_S2, OUTPUT); 108 109 Serial.begin(9600); 110 111} 112 113 114void loop() { 115 116 for( int x = 0; x < 8; ++x ) 117 asciiString[x] = (char)0; 118 119 120 // For each "Byte" 121 for (int i = 0; i < 8; i++) { 122 123 // Select current Byte 124 cycle4051('M',i); 125 126 delay(5); 127 128 //Serial.print("Byte "); 129 //Serial.print(i); 130 //Serial.println(" readings:"); 131 //Serial.print(">"); 132 133 asciiCode=0; 134 135 for (int j = 7; j >=0; j--) { 136 137 // Select current bit 138 cycle4051('S',j); 139 140 delay(5); 141 142 ReadVolt = analogRead(analogPin); 143 144 if(ReadVolt>500) // check if current is running 145 { 146 bitValue=1; // Switch closed, bit high 147 asciiCode = asciiCode + powerOfTwo; 148 } 149 else 150 { 151 bitValue=0; // Switch open, bit low 152 } 153 154 //Serial.print(bitValue); 155 //Serial.print(ReadVolt); 156 //Serial.print("|"); 157 158 } 159 160 //Serial.print(asciiCode); 161 //Serial.println("|"); 162 asciiString[i]=asciiCode; 163 164 165 } 166 //Serial.println("--- End series"); 167 //Serial.println(asciiString); 168 169 for( int z = 0; z < 8; ++z ) 170 { 171 // (note: line 1 is the second row, since counting begins with 0): 172 lcd.setCursor(z, 1); 173 // print on the LCD the current character from the string: 174 lcd.print(asciiString[z]); 175 // print it also on the Serial Monitor 176 Serial.print(asciiString[z]); 177 } 178 Serial.println(""); 179 delay(10); 180} 181 182 183void cycle4051(char master_slave, int stepNumber) { 184 // It's very obvious that this subprogram could have been written in 185 // a much more compact form. I prefer to use a more verbose style 186 // for clarity, readability and ease of maintenance. 187 // I do know that there are may valid alternatives to the stratagem of 188 // using the powerOfTwo variable - the native POW() exponentiation function 189 // that I could well have used has its drawbacks. 190 switch (master_slave) { 191 case 'M': 192 //Next "Byte" (= next slave 4051) 193 //Select the next slave 4051, connected to one of the channels of the master 4051 194 switch (stepNumber) { 195 case 0: 196 //Select Channel 0 of the master 4051 197 digitalWrite(master_S2, LOW); 198 digitalWrite(master_S1, LOW); 199 digitalWrite(master_S0, LOW); 200 break; 201 case 1: 202 //Select Channel 1 of the master 4051 203 digitalWrite(master_S2, LOW); 204 digitalWrite(master_S1, LOW); 205 digitalWrite(master_S0, HIGH); 206 break; 207 case 2: 208 //Select Channel 2 of the master 4051 209 digitalWrite(master_S2, LOW); 210 digitalWrite(master_S1, HIGH); 211 digitalWrite(master_S0, LOW); 212 break; 213 case 3: 214 //Select Channel 3 of the master 4051 215 digitalWrite(master_S2, LOW); 216 digitalWrite(master_S1, HIGH); 217 digitalWrite(master_S0, HIGH); 218 break; 219 case 4: 220 //Select Channel 4 of the master 4051 221 digitalWrite(master_S2, HIGH); 222 digitalWrite(master_S1, LOW); 223 digitalWrite(master_S0, LOW); 224 break; 225 case 5: 226 //Select Channel 5 of the master 4051 227 digitalWrite(master_S2, HIGH); 228 digitalWrite(master_S1, LOW); 229 digitalWrite(master_S0, HIGH); 230 break; 231 case 6: 232 //Select Channel 6 of the master 4051 233 digitalWrite(master_S2, HIGH); 234 digitalWrite(master_S1, HIGH); 235 digitalWrite(master_S0, LOW); 236 break; 237 case 7: 238 //Select Channel 7 of the master 4051 239 digitalWrite(master_S2, HIGH); 240 digitalWrite(master_S1, HIGH); 241 digitalWrite(master_S0, HIGH); 242 break; 243 } 244 break; 245 case 'S': 246 //Next "bit" (= next channel in the currently selected slave 4051) 247 //Select the next channel of the slave 4051, connected to one of the dip switches 248 switch (stepNumber) { 249 case 0: 250 //Select Channel 0 of the slave 4051 251 digitalWrite(slave_S2, LOW); 252 digitalWrite(slave_S1, LOW); 253 digitalWrite(slave_S0, LOW); 254 powerOfTwo=1; 255 break; 256 case 1: 257 //Select Channel 1 of the slave 4051 258 digitalWrite(slave_S2, LOW); 259 digitalWrite(slave_S1, LOW); 260 digitalWrite(slave_S0, HIGH); 261 powerOfTwo=2; 262 break; 263 case 2: 264 //Select Channel 2 of the slave 4051 265 digitalWrite(slave_S2, LOW); 266 digitalWrite(slave_S1, HIGH); 267 digitalWrite(slave_S0, LOW); 268 powerOfTwo=4; 269 break; 270 case 3: 271 //Select Channel 3 of the slave 4051 272 digitalWrite(slave_S2, LOW); 273 digitalWrite(slave_S1, HIGH); 274 digitalWrite(slave_S0, HIGH); 275 powerOfTwo=8; 276 break; 277 case 4: 278 //Select Channel 4 of the slave 4051 279 digitalWrite(slave_S2, HIGH); 280 digitalWrite(slave_S1, LOW); 281 digitalWrite(slave_S0, LOW); 282 powerOfTwo=16; 283 break; 284 case 5: 285 //Select Channel 5 of the slave 4051 286 digitalWrite(slave_S2, HIGH); 287 digitalWrite(slave_S1, LOW); 288 digitalWrite(slave_S0, HIGH); 289 powerOfTwo=32; 290 break; 291 case 6: 292 //Select Channel 6 of the slave 4051 293 digitalWrite(slave_S2, HIGH); 294 digitalWrite(slave_S1, HIGH); 295 digitalWrite(slave_S0, LOW); 296 powerOfTwo=64; 297 break; 298 case 7: 299 //Select Channel 7 of the slave 4051 300 digitalWrite(slave_S2, HIGH); 301 digitalWrite(slave_S1, HIGH); 302 digitalWrite(slave_S0, HIGH); 303 powerOfTwo=128; 304 break; 305 } 306 break; 307 } 308 309 310}
Arduino sketch to read the 8-Byte ROM and show its content on an LCD display
arduino
1/* 2 3DIP/DIL Switch-based 8-Byte ROM via daisy-chained 4051 multiplexers 4 and Arduino 5 6Circuit and comments: 7See http://www.cesarebrizio.it/Arduino/DIP_Switch_ROM.html 8Circuit 9 is as illustrated here:http://www.cesarebrizio.it/Arduino/Final%20Fritzing%20Schema.jpg 10 11 12 created 03 Feb 2019 13 by Cesare Brizio 14 modified ---- 15 16This example 17 code is in the public domain. 18 19Originally conceived as a tribute to the hand-sewn 20 Core Rope memories of the Apollo Guidance Computer, 21my idea was successively 22 simplified to “find a way to store a short character string in a series of 23DIP 24 switches, then retrieve and display that text via an Arduino UNO”. 25 26I was 27 inspired by (or better: I plagiarized) the schematics by PaulRB and the project 28 described here: 29https://forum.arduino.cc/index.php?topic=446780.0 30 31I 32 have 64 DIP switches, each one capable of storing a bit of information, in eaght 33 groups of eight switches 34(closed = non-null voltage reading = binary 1 - opened 35 = null voltage reading = binary 0) 36 37Each group of eight switches, that I 38 will call a "Byte", is connected to the eight I/O channels of a 39separate "slave" 40 4051. 41 42The three address lines S0/S1/S2 of all the slave multiplexers are 43 common: one S0, one S1, and one S2 address all 44the slave multiplexers simultaneously 45 46I 47 am using a master multiplexer 4051 whose I/O channels are connected to the com out/in 48 of each slave multiplexer 49Thus, by a two-step process: 50a) select the "byte" 51 (=slave multiplexer) to read via the S0/S1/S2 of the master 4051 52b) select which 53 "bit" to read from each slave via the common S0/S1/S2 of the slave 4051's 54I 55 can access one switch at a time and make individual reading. 56 57As each byte 58 is meant to store an 8-bit ASCII character, I compose the bytes by the successive 59 readings from 60their bits, and translate them into ASCII values, that are added 61 to the string. 62 63The string obtained is displayed on an LCD display driven 64 by Arduino. 65 66By changing the open/closed DIP switch configuration, I can vary 67 the displayed string in real time. 68 69 70 ========================== 71 The 72 circuit for LCD board: 73 ========================== 74 * LCD RS pin to digital 75 pin 15 76 * LCD Enable pin to digital pin 14 77 * LCD D4 pin to digital pin 5 78 79 * LCD D5 pin to digital pin 4 80 * LCD D6 pin to digital pin 3 81 * LCD D7 pin 82 to digital pin 2 83 * LCD R/W pin to ground 84 * LCD VSS pin to ground 85 * LCD 86 VCC pin to 5V 87 * 10K resistor: 88 * ends to +5V and ground 89 * wiper to LCD 90 VO pin (pin 3) 91 92*/ 93// include the library code: 94#include <LiquidCrystal.h> 95 96// 97 initialize the library with the numbers of the interface pins 98const int rs = 99 13, en = 12, d4 = 11, d5 = 10, d6 = 9, d7 = 8; 100LiquidCrystal lcd(rs, en, d4, 101 d5, d6, d7); 102 103// "Slave" 4051 ADDRESS PINS : 104int slave_S0 = 2; 105int 106 slave_S1 = 3; 107int slave_S2 = 4; 108 109// "Master" 4051 ADDRESS PINS : 110int 111 master_S0 = 5; 112int master_S1 = 6; 113int master_S2 = 7; 114 115// 116int analogPin 117 = A0; 118 119int ReadVolt = 0; 120 121int bitValue; 122 123int asciiCode; 124 125char 126 asciiChar =""; 127 128int powerOfTwo = 0; 129 130char asciiString[8]; 131 132 133 134void 135 setup() { 136 // set up the LCD's number of columns and rows: 137 lcd.begin(16, 138 2); 139 // Print a message to the LCD. 140 lcd.print("8-bit ROM says: "); 141 142 // CONFIGURE ADDRESS PINS 143 pinMode(master_S0, OUTPUT); 144 pinMode(master_S1, 145 OUTPUT); 146 pinMode(master_S2, OUTPUT); 147 pinMode(slave_S0, OUTPUT); 148 149 pinMode(slave_S1, OUTPUT); 150 pinMode(slave_S2, OUTPUT); 151 152 Serial.begin(9600); 153 154 155} 156 157 158void loop() { 159 160 for( int x = 0; x < 8; ++x ) 161 162 asciiString[x] = (char)0; 163 164 165 // For each "Byte" 166 for 167 (int i = 0; i < 8; i++) { 168 169 // Select current Byte 170 cycle4051('M',i); 171 172 173 delay(5); 174 175 //Serial.print("Byte "); 176 177 //Serial.print(i); 178 //Serial.println(" readings:"); 179 //Serial.print(">"); 180 181 182 asciiCode=0; 183 184 for (int j = 7; j >=0; j--) { 185 186 187 // Select current bit 188 cycle4051('S',j); 189 190 191 delay(5); 192 193 ReadVolt = analogRead(analogPin); 194 195 196 if(ReadVolt>500) // check if current is running 197 198 { 199 bitValue=1; // Switch closed, bit high 200 asciiCode 201 = asciiCode + powerOfTwo; 202 } 203 else 204 { 205 206 bitValue=0; // Switch open, bit low 207 } 208 209 210 //Serial.print(bitValue); 211 //Serial.print(ReadVolt); 212 213 //Serial.print("|"); 214 215 } 216 217 //Serial.print(asciiCode); 218 219 //Serial.println("|"); 220 asciiString[i]=asciiCode; 221 222 223 224 } 225 //Serial.println("--- End series"); 226 //Serial.println(asciiString); 227 228 229 for( int z = 0; z < 8; ++z ) 230 { 231 // (note: line 232 1 is the second row, since counting begins with 0): 233 lcd.setCursor(z, 234 1); 235 // print on the LCD the current character from the string: 236 lcd.print(asciiString[z]); 237 238 // print it also on the Serial Monitor 239 Serial.print(asciiString[z]); 240 241 } 242 Serial.println(""); 243 delay(10); 244} 245 246 247void 248 cycle4051(char master_slave, int stepNumber) { 249 // It's very obvious that 250 this subprogram could have been written in 251 // a much more compact form. 252 I prefer to use a more verbose style 253 // for clarity, readability and ease 254 of maintenance. 255 // I do know that there are may valid alternatives to the 256 stratagem of 257 // using the powerOfTwo variable - the native POW() exponentiation 258 function 259 // that I could well have used has its drawbacks. 260 switch 261 (master_slave) { 262 case 'M': 263 //Next "Byte" (= next slave 264 4051) 265 //Select the next slave 4051, connected to one of the channels 266 of the master 4051 267 switch (stepNumber) { 268 case 269 0: 270 //Select Channel 0 of the master 4051 271 digitalWrite(master_S2, 272 LOW); 273 digitalWrite(master_S1, LOW); 274 digitalWrite(master_S0, 275 LOW); 276 break; 277 case 1: 278 //Select 279 Channel 1 of the master 4051 280 digitalWrite(master_S2, LOW); 281 282 digitalWrite(master_S1, LOW); 283 digitalWrite(master_S0, 284 HIGH); 285 break; 286 case 2: 287 //Select 288 Channel 2 of the master 4051 289 digitalWrite(master_S2, LOW); 290 291 digitalWrite(master_S1, HIGH); 292 digitalWrite(master_S0, 293 LOW); 294 break; 295 case 3: 296 //Select 297 Channel 3 of the master 4051 298 digitalWrite(master_S2, LOW); 299 300 digitalWrite(master_S1, HIGH); 301 digitalWrite(master_S0, 302 HIGH); 303 break; 304 case 4: 305 //Select 306 Channel 4 of the master 4051 307 digitalWrite(master_S2, HIGH); 308 309 digitalWrite(master_S1, LOW); 310 digitalWrite(master_S0, 311 LOW); 312 break; 313 case 5: 314 //Select 315 Channel 5 of the master 4051 316 digitalWrite(master_S2, HIGH); 317 318 digitalWrite(master_S1, LOW); 319 digitalWrite(master_S0, 320 HIGH); 321 break; 322 case 6: 323 //Select 324 Channel 6 of the master 4051 325 digitalWrite(master_S2, HIGH); 326 327 digitalWrite(master_S1, HIGH); 328 digitalWrite(master_S0, 329 LOW); 330 break; 331 case 7: 332 //Select 333 Channel 7 of the master 4051 334 digitalWrite(master_S2, HIGH); 335 336 digitalWrite(master_S1, HIGH); 337 digitalWrite(master_S0, 338 HIGH); 339 break; 340 } 341 break; 342 case 343 'S': 344 //Next "bit" (= next channel in the currently selected slave 345 4051) 346 //Select the next channel of the slave 4051, connected to one 347 of the dip switches 348 switch (stepNumber) { 349 case 350 0: 351 //Select Channel 0 of the slave 4051 352 digitalWrite(slave_S2, 353 LOW); 354 digitalWrite(slave_S1, LOW); 355 digitalWrite(slave_S0, 356 LOW); 357 powerOfTwo=1; 358 break; 359 case 360 1: 361 //Select Channel 1 of the slave 4051 362 digitalWrite(slave_S2, 363 LOW); 364 digitalWrite(slave_S1, LOW); 365 digitalWrite(slave_S0, 366 HIGH); 367 powerOfTwo=2; 368 break; 369 370 case 2: 371 //Select Channel 2 of the slave 4051 372 373 digitalWrite(slave_S2, LOW); 374 digitalWrite(slave_S1, 375 HIGH); 376 digitalWrite(slave_S0, LOW); 377 powerOfTwo=4; 378 379 break; 380 case 3: 381 //Select 382 Channel 3 of the slave 4051 383 digitalWrite(slave_S2, LOW); 384 385 digitalWrite(slave_S1, HIGH); 386 digitalWrite(slave_S0, 387 HIGH); 388 powerOfTwo=8; 389 break; 390 391 case 4: 392 //Select Channel 4 of the slave 4051 393 394 digitalWrite(slave_S2, HIGH); 395 digitalWrite(slave_S1, 396 LOW); 397 digitalWrite(slave_S0, LOW); 398 powerOfTwo=16; 399 400 break; 401 case 5: 402 //Select 403 Channel 5 of the slave 4051 404 digitalWrite(slave_S2, HIGH); 405 406 digitalWrite(slave_S1, LOW); 407 digitalWrite(slave_S0, 408 HIGH); 409 powerOfTwo=32; 410 break; 411 412 case 6: 413 //Select Channel 6 of the slave 4051 414 415 digitalWrite(slave_S2, HIGH); 416 digitalWrite(slave_S1, 417 HIGH); 418 digitalWrite(slave_S0, LOW); 419 powerOfTwo=64; 420 421 break; 422 case 7: 423 //Select 424 Channel 7 of the slave 4051 425 digitalWrite(slave_S2, HIGH); 426 427 digitalWrite(slave_S1, HIGH); 428 digitalWrite(slave_S0, 429 HIGH); 430 powerOfTwo=128; 431 break; 432 433 } 434 break; 435 } 436 437 438}
Downloadable files
Fritzing schematics (with only one 4051 attached to its 8 switches)
A full overview of the project, but with many obvious connections omitted for clarity
Fritzing schematics (with only one 4051 attached to its 8 switches)
Comments
Only logged in users can leave comments
CesareBrizio
0 Followers
•0 Projects
Table of contents
Intro
4
0