A0 not responding

I have 6 NO push buttons on A0 with each having a resistor all in series. Pushing the button ties that resistor to ground. This has an analog value that is a command to be used by the controller. The resistors are 10K and work quite well but only when the led on the board is hi. Pushing a button causes this to turn on, digital pin 14. Bootup takes a minute or more to start working in the calibrate mode, numbers sent to the IDE monitor. I disabled the calibrate mode, pushed all 6 buttons and the voltage on A0 changes but the MCU does not respond. Looking for ways to trouble shoot this so maybe I can figure this out on my own.

Thanks in advance Duck50

There is no 'digital pin 14' on a Nano. (Or rather, "pin 14" is the same as A0, so if you're doing a digitalWrite(14,..) or pinMode(14,..), you're turning OFF the analog functionality...)

My mistake it is A1
#define button_pin A1 // Input pullup pin for reading all 6 buttons

This is what is in the sketch.
Should this be deleted and a 10k pullup resistor be added?
The first resistor is hooked to A1. In the calibrate mode it would work only if the light on the Nano board lit (L), that is when the analog value for that button would display on the monitor.

Post a drawing and your sketch to make

Same problem as with A0. Post a hand drawn wiring diagram.

Do you want all of the main sketch and the included ones.

The sketch starts goes to the welcome screen on the lcd then go to the memory game where i think it is waiting for a command from the buttons pushing them does nothing as the voltage changes on A1.

Could it be a bad Nano

Duck50

Thanks for posting the schematic diagram, but it is not complete, and makes little sense. With all switches open, the A1 input is floating, so analogRead() will return random values.

Please post a complete schematic, including the LEDs, power and GND.

Power Supply


Nano wiring

D2, D3 are not used. A1 has 6 buttons instead of 4 as the Nano pic showes.
LED's are hooked to D5 to Red, D6 to Blue, D7 to Yellow, D8 to Green not as shown in picture
pin 27 of the Nano is hooked to Positive of the boost chip, set to 5VDC. Pin 4 of the Nano is hooked to the Neg of the boost chip
One side of the N. O. switches all are tied to Neg on the Boost PCB as well as the cathodes of the LEDs
I am trying to make the Arduino Music and Game box as described at Instructibles.com .
I have some knowledge of Basic and most of my knowledge is PLC's.

Hope this helps
Duck50

This is the ino file.

// Arduino Nano pin definitions
#define RED_LED 5 // Pin number for the red LED, Assuming succeeding pins R, B, Y, G
#define button_pin A1 // Input pullup pin for reading all 6 buttons
byte button_state = 6; // See read_buttons()

// Awesome calibration table: (Old prototype ver)
/* //      Button   Analog Value [LSB]
#define red_val        42 
#define yellow_val    245               
#define green_val     378
#define blue_val      465 
String button2str[] = {"Red", "Yellow", "Green", "Blue"}; */

// Awesome calibration table: (Final)
//      Button   Analog Value [LSB]
#define white_val     589
#define red_val       535
#define blue_val      466
#define yellow_val    376  
#define black_val     246
#define green_val      41  //235
String button2str[] = {"Red", "Blue", "Yellow", "Green", "White", "Black"};
#define val_tol         8 // +- How many LSB the measurement can be far from the calibrated value
#define N_avg           15 // Number of analog reads to average for a button value - minimize jitter

// External libraries
#include <Tone.h> // https://github.com/bhagman/Tone/ (V1.0.0)
#include <LiquidCrystal_I2C.h> // https://github.com/fmalpartida/New-LiquidCrystal (V1.5.0)
#include <EEPROM.h> // Arduino built-in

// Speaker stuff
#define PIN_PLAYER_1 10
#define PIN_PLAYER_2 11
int tronca = 15; // Increasing this value separates notes from each other. [OPTIONAL]
bool isMute = false; // Global sound switch, stored @ EEPROM, address "isMute_addr".
Tone player_1; // Speaker 1 object
Tone player_2; // Speaker 2 object

// Internal headers
#include "lcd_functions.h"
#include "tone_functions.h"
#include "global_functions.h"
#include "memory_game.h"
#include "reaction_game.h"

void setup(){
	pinMode(button_pin,INPUT_PULLUP);
//	pinMode(LED_BUILTIN, OUTPUT);
	for(int i=0; i<4; i++){
		pinMode(RED_LED+i,OUTPUT);

//    digitalWrite(LED_BUILTIN, LOW);
	}	
	lcd.begin(SCREEN_WIDTH,SCREEN_HEIGHT);
	// Switch on the backlight
	lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
	lcd.setBacklight(HIGH);
	setup_progressbar();	
	#if defined(debug_flag)
	lcd.home(); lcd.print(F("Waiting for")); lcd.setCursor(0,1); lcd.print(F("serial..."));
	Serial.begin(9600);
	delay(100);
	while(!Serial);
	Serial.println("Welcome to Lou's Arcade!\nPlayer 1 Ready...");
	#endif
	
	lcd.home();
	lcd.print(F(" LOU'S ARCADE! ")); 	lcd.setCursor(0,1);
	lcd.print(F("    READY?  ;)  "));
	
	// Load settings
	EEPROM.get(isMute_addr, isMute); // Get Sound settings from the last time
	EEPROM.get(N_times_played_addr, N_times_played);
	if (N_times_played == 65536) {N_times_played = 0;} // init value in EEPROM
	randomSeed(N_times_played);
	EEPROM.get(reaction_initial_timeout_addr, reaction_initial_timeout);
	if (reaction_initial_timeout == 65536) {reaction_initial_timeout = 3000;} // init value
	EEPROM.get(memory_letters_delay_ms_addr, memory_letters_delay_ms);
	if (memory_letters_delay_ms == 65536) {memory_letters_delay_ms = 250;} // init value
	
	// Init Speakers
	player_1.begin(PIN_PLAYER_1);
	player_2.begin(PIN_PLAYER_2);
	
	introduzione();
	delay(200);	
	memory_game();
}

void listen_serial(){
	if (Serial.available() > 0) {
		receivedChar = Serial.read();
		
		if (receivedChar == 'a'){ // Add a sequence letter
			add_letter();
		}
		
		if (receivedChar == 'p'){ // Play sequence!
			play_sequence();
		}
		
		if (receivedChar == 'i'){ // Reset EEPROM
			EEPROM.put(memory_highscore_addr, 0);
			EEPROM.put(reaction_highscore_addr, 0);
			lcd.clear(); lcd.print(F("   Highscore    ")); lcd.setCursor(0,1); lcd.print("    Cleared.    ");
			delay(1000);
			menu();
		}
		if (receivedChar == 'm'){ // Play all music
			playAllMusic();
		}
		
		if (receivedChar == 's'){ // Start memory_game play!
			free_play = false;
			memory_game();
		}
		
		if (receivedChar == 'r'){ // Start reaction_game play!
			free_play = false;
			reaction_game();
		}
		
		if (receivedChar == 'f'){ // Free button pressing
			debugln("Welcome to Free Play! Press buttons and have fun!");
			free_play = true;
		}	
		if (receivedChar == 'v'){ // Volume toggle			
			toggle_volume();
		}
		
		if (receivedChar == 'c'){ // Button calibration
			free_play = false;

			while (!Serial.available()){
				debugln(analogRead(button_pin));
				delay(refresh_interval);
			}
		}
	}
}

void menu(){
  //sensorValue = analogRead(sensorPin);
	const String menu_choices[] PROGMEM = {"Memory Game", "Reaction Game", "Free Play", "Music"};
	button_state = 6;
	int current_choice = 0;
	lcd.clear(); lcd.print(menu_choices[current_choice] + "?");
	while (true){    
		button_state = read_buttons();   //analogRead
		if (button_state == 4){ // Change selection
			current_choice++;
			if (current_choice == mylength(menu_choices)){
				current_choice = 0;
			}
			lcd.clear(); lcd.print(menu_choices[current_choice] + "?");
		}
		if (button_state == 5){ // Execute selection
			break;
		}
		if (button_state == 0){ // Double click for settings (child proof)
			if (is_double_click(button_state)){	
				settings();
				lcd.clear(); lcd.print(menu_choices[current_choice] + "?");
			}
		}
		if (Serial.available() > 0) {return;}
	}
	
	// Execute!
	lcd.clear(); lcd.print("Execute!");
	
	switch (current_choice){
		case 0:
		free_play = false;
		memory_game();
		break;
		case 1:
		free_play = false;
		reaction_game();
		break;
		case 2:
		free_play = true;
		lcd.clear(); lcd.print(menu_choices[current_choice] + "!");
		break;
		case 3:
		playAllMusic();
		break;
	}
}

void display_parameter(byte current_setting){
	//{"Memory speed", "Reaction speed", "Times played", "Memory score", "Reaction score"}
	switch (current_setting){
		case 0:
		lcd_print(1, String(memory_letters_delay_ms));
		break;
		case 1:
		lcd_print(1, String(reaction_initial_timeout));	
		break;
		case 2:
		lcd_print(1, String(N_times_played));	
		break;
		case 3:
		lcd_print(1, String(EEPROM.read(memory_highscore_addr)));	
		break;
		case 4:
		lcd_print(1, String(EEPROM.read(reaction_highscore_addr)));
		break;
		case 5:
		lcd_print(1,"");
		lcd.write(byte(6));
		lcd.print((isMute) ? "x":"v");
		break;
	}
}

void change_up_setting(byte current_setting){
	switch (current_setting){
		case 0:
		memory_letters_delay_ms = min(2500,round(((float)memory_letters_delay_ms) * 1.15));
		break;
		case 1:
		reaction_initial_timeout = min(5000,round(((float)reaction_initial_timeout) * 1.15));
		break;
		case 5:
		toggle_volume();
		break;
		case 6:
		clear_EEPROM();
		menu();
		break;
	}
	display_parameter(current_setting);
}

void change_down_setting(byte current_setting){
	switch (current_setting){
		case 0:
		memory_letters_delay_ms = max(100,round(((float)memory_letters_delay_ms) / 1.15));
		break;
		case 1:
		reaction_initial_timeout = max(100,round(((float)reaction_initial_timeout) / 1.15));
		break;
		case 5:
		toggle_volume();
		break;
		case 6:
		clear_EEPROM();
		menu();
		break;
	}
	display_parameter(current_setting);	
}

void settings(){
	const String settings_choices[] PROGMEM = {"Memory [ms]", "Reaction [ms]", "Times played", "Memory score", "Reaction score", "Volume", "Clear EEPROM"};
	byte current_setting = 0;
	lcd_print(0, settings_choices[current_setting]);
	display_parameter(current_setting);
	while (true){
		button_state = read_buttons();
		if (button_state == 4){ // Change selection
			current_setting++;
			if (current_setting == mylength(settings_choices)){
				current_setting = 0;
			}lcd_print(0, settings_choices[current_setting]);
			display_parameter(current_setting);
		}
		if (button_state == 5){ // Save and quit this sub-menu
			EEPROM.put(memory_letters_delay_ms_addr,memory_letters_delay_ms);		
			EEPROM.put(reaction_initial_timeout_addr,reaction_initial_timeout);
			return;
		}
		if (button_state == 2){ // Mute/ Unmute
			toggle_volume();
		}
		if (button_state == 0){ // Change up
			change_up_setting(current_setting);
		}
		if (button_state == 1){ // Change down
			change_down_setting(current_setting);
		}
		if (Serial.available() > 0) {return;}
	}
}

void loop(){
	listen_serial();
	if ( (button_state == 4) || read_buttons() == 4){
		menu();
	}
	if (free_play){read_buttons();}
	delay(refresh_interval);	
}			

This is global functions


// Timings
#define refresh_interval 1000/40    // [ms] Used for calibration and free play
#define highscore_disp_timeout 4000 // [ms] Time to display highscore before switching to the menu.
#define click_window_ms 1000        // [ms] Max delay between clicks in a double click

// Debug header definition
#ifdef debug_flag
	#define debug(str)       Serial.print   (str);
	#define debug_dec(num)   Serial.print   (num, DEC)
  #define debugln_dec(num) Serial.println (num, DEC)
	#define debug_bin(num)   Serial.print   (num,BIN)
	#define debugln(str)     Serial.println (str)
	#else
	#define debug(str) 
	#define debug_dec(num) 
	#define debug_bin(num) 
	#define debugln(str) 
#endif

// Count an array's length
#define mylength(array) ((unsigned int) (sizeof (array) / sizeof (array [0])))

bool game_over; // This is the break condition of while loops within the various games. False returns to menu.
byte level = 0; // Level variable used for all games
uint16_t N_times_played;

char receivedChar; // Serial port incoming
bool free_play = false; // AKA toddler mode

// EEPROM Stuff                                  // Length (bytes)
#define isMute_addr 0                            //      1 
#define memory_highscore_addr 1                  //      1
#define reaction_highscore_addr 2                //      1
#define N_times_played_addr 3                    //      2
#define reaction_initial_timeout_addr 5          //      2
#define memory_letters_delay_ms_addr  7          //      2

void turn_off_LEDs(){
	for (int i=0; i<4; i++){digitalWrite(RED_LED+i,LOW);};
}

void turn_on_LEDs(){
	for (int i=0; i<4; i++){digitalWrite(RED_LED+i,HIGH);};
}

void flash_LEDs(int n=3){
	for(int i=1; i<=n; i++){
		turn_on_LEDs();
		lcd.setBacklight(LOW);
		delay(150);
		turn_off_LEDs();
		lcd.setBacklight(HIGH);
		delay(150);
	}
}

byte which_button_pressed(int measured_val){
	// Apply the calibration table
	if (      measured_val > 1000                   ){ return(6); } // Nothing pressed
  if ( abs( measured_val - red_val    ) < val_tol ){ return(0); }
	if ( abs( measured_val - blue_val   ) < val_tol ){ return(1); }
	if ( abs( measured_val - yellow_val ) < val_tol ){ return(2); }
	if ( abs( measured_val - green_val  ) < val_tol ){ return(3); }
	if ( abs( measured_val - white_val  ) < val_tol ){ return(4); }
	if ( abs( measured_val - black_val  ) < val_tol ){ return(5); }
	return(7); // Error measuring - ignore.
}

uint16_t read_analog(){
	float measured_val = 0;
	for (int i = 0; i < N_avg; i++){ // Try overcoming jitter
	  measured_val += float(analogRead(button_pin))/N_avg;
    delay(1);
	}
  measured_val = round(measured_val);
  #ifdef debug_flag
    if (measured_val < 1000) {debugln_dec(measured_val);}
  #endif
	return( measured_val );
}

byte read_buttons(){
	// Output:
  // 7 Measurement error - ignore
	// 6 : nothing's pressed
	// 0-3 : R, B, Y, G Buttons
	// 4 : White
	// 5 : Black
	byte intermediate_button_state = which_button_pressed(read_analog());
	
	if (intermediate_button_state <=5) {// Debouncing function
		button_state = intermediate_button_state;
    if (which_button_pressed(read_analog()) == button_state){ // Validate its not jitter
  		if (intermediate_button_state <=3) {// Play the respective button's tone. Play an indefinite tone but stop it once button was released.
			  digitalWrite(RED_LED+button_state,HIGH);
			  PlayColor(button_state, 1000);
      }
      debugln(button2str[button_state] + "!");
    }
    else { // Jitter?
        button_state = 6;
    }
		while (intermediate_button_state != 6 ){
			intermediate_button_state = which_button_pressed(read_analog());
		}
	}
	else { // Pressed nothing.
		button_state = 6;
	}
	turn_off_LEDs();
	player_1.stop();
	player_2.stop();
	
	return(button_state);
}	

bool is_double_click(byte first_click){
	long t_start = millis();
	button_state = 6;
	while ((button_state==6) && ((millis()-t_start)<click_window_ms)){
		button_state = read_buttons();
	}
	return(button_state == first_click);
}

void end_game(){
	button_state = 5; // Signal the main sketch to go to the menu
	N_times_played++;
	EEPROM.put(N_times_played_addr,N_times_played);
}

void new_high_score(int level){
	const String str1 PROGMEM = "NEW HIGH SCORE: ";
	lcd_print(0,str1);
	lcd_print(1,String(level));
	COIN(level);
	flash_LEDs(3);
	FLAGPOLEFANFARE();
	long time = millis();
	while ((read_buttons()==6) && ((millis()-time) < 2*highscore_disp_timeout)) { delay(refresh_interval); }
	end_game();
}

void show_high_score(int level, byte highscore_addr){
	const String str1 PROGMEM = "Game over ;)";
	const String str2 PROGMEM = "Level ";
	const String str3 PROGMEM = "High score:";
	lcd_print(0,str1); lcd_print(1,str2 + String(level));
	DEATH();
	lcd_print(0,str3); lcd_print(1,String(EEPROM.read(highscore_addr)));
	GAMEOVER();
	long time = millis();
	while ((read_buttons()==6) && ((millis()-time) < 1*highscore_disp_timeout)){delay(refresh_interval);}
	end_game();
}	

void toggle_volume(){
	//lcd.scrollDisplayLeft();
	lcd_print(1,""); lcd.write(byte(6)); // Speaker character 
	if (isMute){
		isMute = false;
		lcd.write("v");
	}else
	{
		isMute = true;
		lcd.write("x");
	}
	debugln("Mute = " + String(isMute));
	EEPROM.put(isMute_addr, isMute);
}

void clear_EEPROM(){
	const String str1 PROGMEM = "2X click black";
	const String str2 PROGMEM = "clear EEPROM";
	const String str3 PROGMEM = "Done!";
	
	button_state = 6;
	lcd_print(0,str1);
	lcd_print(1,str2);
	while (button_state == 6){
		button_state = read_buttons();
		delay(refresh_interval);
	}
	if (button_state == 5){ // First click on white
		if (is_double_click(5)){
			// Clear stuff
			EEPROM.put(memory_highscore_addr, byte(0));
			EEPROM.put(reaction_highscore_addr, byte(0));
			N_times_played = uint16_t(0);
			EEPROM.put(N_times_played_addr, N_times_played);
			lcd.clear();
			lcd_print(0,str3);
			delay(750);
		}
	}
}	

This is memory game

#define max_level 128 // Must be multiple of 4
uint16_t memory_letters_delay_ms = 300;

byte sequence[max_level/4];

const byte sequence_theme = 1; // 1: pseudo random
// In the future - can be 2: "Mary had a little lamb" :)
//const PROGMEM	
byte current_letter_index = 0; // Stores the index of letter just pressed by the player

void play_sequence(){
	byte word;
	byte letter;
	debug("Level " + String(level) + ". Playing sequence (start -> end):");
	delay(memory_letters_delay_ms);
	for (int i_letter=0; i_letter<level; i_letter++){
		if (i_letter%4 == 0){
			word = sequence[(int)(i_letter/4)];
			debug(" ");
		}
		// Play a word, starting from 2 LSBs
		letter = 0;
		letter = bitRead(word,1)<<1 | bitRead(word,0)<<0; 		
		digitalWrite(RED_LED+letter,HIGH);
		// Play the respective button's tone
		PlayColor(letter, memory_letters_delay_ms/inputTempo());
		while(player_1.isPlaying()){delay(5);}
		
		debug_dec(letter);
		word = word >> 2;
		digitalWrite(RED_LED+letter,LOW);
		delay(memory_letters_delay_ms);		
	}	
	debugln("");
}

void add_letter(){
	// Add 1 letter to the global var called "sequence"
	byte letter;
	
	switch (sequence_theme){
		case 1: //1: pseudo random
		letter = random(4); // 0, 1, 2, 3 : R, Y, G, B, Respectively		
		break;
		
		case 2: //2: Mary had a little lamb - To be developed
		//letter = random(4); // 0, 1, 2, 3 : R, Y, G, B, Respectively		
		
		break;
	}
	// Write the addition to the sequence
	bitWrite(sequence[level/4], 2*(level % 4) + 0 , bitRead(letter,0));
	bitWrite(sequence[level/4], 2*(level % 4) + 1 , bitRead(letter,1));
	
	level++;	
	
	#if defined(debug_flag)
		Serial.print("Level " + String(level) + ". Added letter: " + String(letter) + ". Sequence (end -> start): ");
		for (int i=((level-1)/4); i>=0; i--){
			for (int j=7; j>=0; j--){
				Serial.print(bitRead(sequence[i],j));
				}
			Serial.print(" ");
		}
		Serial.println("");
	#endif
}

bool is_correct_letter(byte button_state){
	byte word = sequence[(int)(current_letter_index/4)];
	byte expected_letter = bitRead(word,2*(current_letter_index%4) + 1)<<1 | bitRead(word,2*(current_letter_index%4) +0)<<0; 		
	debug("Current word: ");
	debug_bin(word);
	debug(", Button expected: " + String(expected_letter) + ". Button pressed: " + String(button_state) + "\n");
	return button_state == expected_letter;
}

void memory_game(){
	debugln("Good luck, Player 1!");
	game_over = false;
	lcd.clear(); lcd.print(F("      Go        ")); lcd.setCursor(0,1); lcd.print(" Memory Game!!! ");
	ONEUP();	
	current_letter_index = 0;
	level = 0;	
	add_letter();
	play_sequence();
	
	while (!game_over){
		button_state = read_buttons();
		if (button_state<=3) // If pressed on one of the color buttons
		{
			
			if (is_correct_letter(button_state)){
				// Player got the right letter. Check if it was the end of the sequence
				if (current_letter_index == level-1){
					debugln("Correct! Level " + String(level) + " cleared!");
					lcd.clear(); lcd.print("    Level " + String(level)); lcd.setCursor(0,1); lcd.print(F("   completed!   "));
					current_letter_index = 0;
					POWERUP();
					
					delay(memory_letters_delay_ms);					
					add_letter();
					play_sequence();
				}
				else{ // Player pressed the correct button, in the middle of the sequence
					current_letter_index++;
					debugln("Go on!!!");
				}
				turn_off_LEDs();
			}
			else{ // Player got the wrong letter
				if (level > EEPROM.read(memory_highscore_addr)) { // NEW HIGH SCORE!
					EEPROM.put(memory_highscore_addr, level);
					new_high_score(level);
				}
				else {
					game_over = true;
					debugln("Failed on letter " + String(current_letter_index) + ", level " + String(level) + "\n:()" );
					show_high_score(level,memory_highscore_addr);
				}
			}
		}
		else if (button_state == 4){ // Go to the menu
			game_over = true;
		}
		if (Serial.available() > 0) {return;}
	}
}

in the calibrate mode the white button will scroll the lcd display through all of the options. When the power is applied the sketch go to "Go Memory Game! ! !" and stops pushing the white or black buttons does nothing. After a short time the speakers have a constant tone emitted from them. I uploaded the example code ananlogin serial out and the Nano replied back a value for each button pushed. Any thing else needed i will be happy to supply it. Thanks Duck 50

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.