8x8 Matrix - Hall sensor error

Hi all, new here - first time programming, soldering, and playing with an Arduino so please forgive my ignorance. I'm humbled by all of this.

I dove in with hopes of building an interactive chess board. I couldn't wrap my head around shift registers or multiplexers so I wired all 64 hall effect sensors to it's own pin on an Arduino Mega (aware of how silly this was - if you'd like to explain shift registers in plain english) Wiring took a while but I was able to write some code and test each sensor using the LedControl library on a MAX7219 LED matrix.

I have three questions.

  1. The very last square on my 8x8 board is turning the LED on even without a magnet. does anyone know why this might be happening? The wiring is correct, I've checked for shorts using a multimeter, I've swapped out the sensor.. If I delete the code for that last square the light turns off. I used the same code for all the other 63 squares and they work fine.

  2. Any suggestions to make this code more efficient? I'm sure the approach I took will hurt someones soul... apologies

  3. Does anyone know how to link these squares to a chess library so I can track moves?

:pray: thank you in advance

chess_matrix_hallPinH7_error.ino (23.0 KB)





You could reduce your code size by about 90% if you take a bit of time and learn about arrays rather than the massive amount of duplication reading/reacting to each pin.

/* Include the LedControl library */
#include "LedControl.h"
// Create a LedControl for the first 8 devices...
LedControl lc1 = LedControl(16, 18, 17, 1);

const byte pins[] = {
  6, 5, 38, 36, A7, A8, 37, 39, // A
  7, 4, 40, 34, A6, A9, 35, 41, // B
  8, 3, 42, 32, A5, A10, 33, 43, // C
  9, 2, 44, 30, A4, A11, 31, 45, // D
  10, 1, 46, 28, A3, A12, 29, 47, // E
  11, 0, 48, 26, A2, A13, 27, 49, // F
  12, 14, 50, 24, A1, A14, 25, 51, // G
  13, 15, 52, 22, A0, A15, 23, 53, // H
}

const byte nPins = sizeof(pins) / sizeof(pins[0]);

void setup() {

  // all pins are INPUT by default

  for (int index = 0; index < lc1.getDeviceCount(); index++) {
    lc1.shutdown(index, false);
  }
}

void loop() {

  for ( int i = 0; i < nPins; ++i ) {
    int hallState = digitalRead( pins[i] );
    int state = false;
    int row =  i / 8;
    int col = i % 8;
    if (hallState == LOW) {
      state = true;
    }
    lc1.setLed(0, row, col, state);
  }
}

But then you still have the problem of the pins used for the lcd control
LedControl lc1 = LedControl(16, 18, 17, 1); can NOT be used for your inputs.

2 Likes

I see from your list you are using pins 0 and 1, these are used by the serial port, so if there is any serial printing going on in your code this will mess up the reading of these pins. I can’t tell because you posted a .ino file. These can’t be read on mobile devices. While it is not shown as the bottom right it could matter.
What is shown is pin 13. This is connected to the on board LED and it could be that this pin is being left as an output, or input with a unwanted pull up resistor.

A schematic showing the wiring for a few of the hall sensors along with their part number would help to clarify matters.

2 Likes

Did you check the pull-up resistor at the sensor? (Note: The MEGA can enable internal pull-up resistors on each input so external pull-ups are not necessary.)

Check the voltage on Pin 53 (H7) with and without the magnet. If the input doesn't change or is a value that is not close to 0.0V or 5.0V then something is probably wrong with the wiring. If you can't fit a little probe into the top of the cable connector, probe the bottom of the pin on the underside of the MEGA board.

If the signal looks weird, try unplugging the cable from the MEGA and probing the cable alone. If the signal then looks good, the problem is something in the MEGA.

@blh64
:sweat_smile: does this get me some kind of noob award?

I really appreciate your help, even if it was an easy problem for you. this code wouldn't compile and I couldn't begin to tell you why.. apologies.

Can you explain what you mean? Currently the sensors are turning the LEDs on and off using pins 16, 18 & 17.

@johnwasser

So I didn't need to add a resistor to each sensor? How would I enable these internal resistors? I guess I can research that but any simple terms/explanations you have would be helpful.

I checked the voltage on pin 53, 39, 6 (all the corners, not sure if that was significant) They all read 4.77V without a magnet and 20mV (basically zero?) with a magnet.

@Grumpy_Mike


attaching a a diagram for the A3144 Hall effect sensor and 10K ohm resistor.

Sounds perfect. I can't figure out why the LED for Pin 53 is not ON when the magnet is present (input LOW) and OFF when the magnet is not present (input HIGH). :frowning:

To enable the internal pullup, use pinMode(pin, INPUT_PULLUP); instead of pinMode(pin, INPUT); The 10k pull-ups you have are fine and you can use both if you like.

I guess you've tried just running the 8_X_8 to buzz out each segment or at least, the troublesome dot in the corner?

I sure haven't. What's that mean :grimacing: ??

My bad. I thought you were using those pins for both the driver and your connections. I just saw '1' and assumed it was a pin number. Should have looked closer.

As for the code, it is missing one semicolon after the pins declaration. Hardly insurmountable.

const byte pins[] = {
  6, 5, 38, 36, A7, A8, 37, 39, // A
  7, 4, 40, 34, A6, A9, 35, 41, // B
  8, 3, 42, 32, A5, A10, 33, 43, // C
  9, 2, 44, 30, A4, A11, 31, 45, // D
  10, 1, 46, 28, A3, A12, 29, 47, // E
  11, 0, 48, 26, A2, A13, 27, 49, // F
  12, 14, 50, 24, A1, A14, 25, 51, // G
  13, 15, 52, 22, A0, A15, 23, 53, // H
};

Thanks, that looks fine to me, apart from my usual gripe about having no decoupling capacitors. I would put a few on the chained power and ground lines. A 0.1uF ceramic between power and ground close to the sensors on each corner will do.

If you are measuring those voltages on the sensors then I think that is OK. So the problem would seem to be either reading that specific pin or translating that pin to the correct position on the LED matrix.

When I encounter this sort of problem I use a technique I call hit the jelly and see how it wobbles. Jelly in English means jellow in America.
That means make a change and see if the resulting behaviour exists makes sense.
So for example invert the mapping between the sensor pin and the LED position and see if the not working corner stays with the pin or moves to a new position. That narrows down where the problem is.

1 Like

Forget about the hall sensoring and everything else → make a test sketch that just runs the 'matrix', one that turns on/off each LED sequentially.

1 Like

@runaway_pancake @johnwasser @Grumpy_Mike @blh64

Thanks guys!

Going to go...

BRB.

Edit: When I uploaded the code from @blh64 the light turned on but at the other end of the column. Guess that rules out the LED matrix??? The problem light that's on still represents the same square on my chessboard (squareH1 or pin13) So I decided to shift some pins around to rule out the potential serial port problems (pin1&2). I shifted those down and it didn't help. Then I moved pin13 to see if the on board MegaLED was interfering. I moved it to Pin 18 (which was now available due to the previous shift of pins.

It works!

To sum up, pin13 was the culprit. I don't know why, and that bothers me. Here is the final code with updated pin locations. Any ideas why pin 13 would light up with & without a magnet? I did read the voltage at the sensor before moving the hall sensor to pin18 and it read -2V. Thought that was weird.

Guess I should mention I wired everything to a shield because I assumed my soldering would be messy. It was :expressionless:

/* Include the LedControl library */
#include "LedControl.h"
// Create a LedControl for the first 8 devices...
LedControl lc1 = LedControl(19, 21, 20, 1);

const byte pins[] = {
  6, 5, 38, 36, A7, A8, 37, 39, // A
  7, 4, 40, 34, A6, A9, 35, 41, // B
  8, 3, 42, 32, A5, A10, 33, 43, // C
  9, 2, 44, 30, A4, A11, 31, 45, // D
  10, 14, 46, 28, A3, A12, 29, 47, // E
  11, 15, 48, 26, A2, A13, 27, 49, // F
  12, 16, 50, 24, A1, A14, 25, 51, // G
  18, 17, 52, 22, A0, A15, 23, 53, // H
};  

const byte nPins = sizeof(pins) / sizeof(pins[0]);

void setup() {

  // all pins are INPUT by default

  for (int index = 0; index < lc1.getDeviceCount(); index++) {
    lc1.shutdown(index, false);
  }
}

void loop() {

  for ( int i = 0; i < nPins; ++i ) {
    int hallState = digitalRead( pins[i] );
    int state = false;
    int row =  i / 8;
    int col = i % 8;
    if (hallState == LOW) {
      state = true;
    }
    lc1.setLed(0, row, col, state);
  }
}

I think I might have found the bug:

I suspect the bootloader doesn't set Pin 13 back to being an INPUT after it uses it to blink the LED.
Try putting "pinMode(LED_BUILTIN, INPUT);" after that line and see if the old code works.

Hmmm.. that sounded logical to me but it didn't work. Tried splicing it in under void setup, void loop, and the beginning.. Pin 13 is still on.

Would like to solve the mystery pin13.

Any ideas how to label the square correctly and print each move to the serial plotter/monitor?

There's a standard format for recording moves in chess. I'd love to play a game on this proto board and upload the Portable Game Notation (PGN) to Lichess for analysis after.

char *chesssquare[] = {"A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8",
                      "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8"
                    };

Is this a real Mega board or a clone? The reference design has other circuitry associated with pin 13 to power the on-board LED, which could be interfering with the sensor. If it is some clone, then there is no guarantee they followed the reference design and may have eliminated/changed things.

Yet another lesson in why Pin 13 should not be for first choice for use...

As for the standard chess notation, all those strings "A1", "A2", etc will take up a ton of memory. It would be much better to use uint8_t and have row 1 be 0..7, row 2 be 10..17, etc. and then when you go to actually print them out, convert them to the standard notation.

Did you put it inside the setup, and use a pinMode(13, INPUT)

Given int index;, an index into your 64-pin array:

The column digit is: (char) ((index % 8) + '1')
The row letter is: (char) ((index / 8) + 'A')

so:

Serial.print((char) ((index / 8) + 'A'));
Serial.print((char) ((index % 8) + '1'));

Is there a button to tell you the move is over, like on a chess clock? Or do you intend to watch all changes and infer the end of a move from the sequence of changes?

You may need to keep track of where each piece is. You may need to keep track of whose turn it is. You will certainly need to keep track of the previous state of the 64 sensors. That can be done in a single 64-bit integer or 8 bytes. You may need to keep track of the order of individual changes.