Close

Testing the Fully Populated State PCB

A project log for TMD-3: Turing Machine Demonstrator Mark 3

They say that the third time's a charm. Let's find out.

michael-gardiMichael Gardi 08/18/2023 at 17:440 Comments

I finally got around to fully populating the state table PCB. Using the technique posted in a previous log, I carefully soldered the 16 linear hall effect sensors, then the header, multiplexor, and ADC chips to the board.

Remember that the red wire is to connect the primary input/output pin of the multiplexor to channel 0 of the ADC for this board.  The other 5 boards forming the state transition table will be wired individually to channels 1-5 of this same ADC via the “bus”. I have added the sensor numbers as labels to the PCB photo for clarity. I also added the rectangular indentation to the bottom of the printed panel to accommodate the soldered pins of the ICs and header as I found that the panel would not sit flush against the PCB and sensors otherwise. 

First I wanted to test the variance between sensors. I wrote a small script to measure each of the sensors in turn. Things to note:

import time
import busio
import digitalio
import board
import adafruit_mcp3xxx.mcp3008 as MCP
from adafruit_mcp3xxx.analog_in import AnalogIn
import pigpio

# Access the gpio pins.
GPIO = pigpio.pi()

# Select pins for the CD4067BE.
S0 = 23
S1 = 27  
S2 = 17
S3 = 18

# Selct pins are all OUTPUT.
GPIO.set_mode(S0, pigpio.OUTPUT)
GPIO.set_mode(S1, pigpio.OUTPUT)
GPIO.set_mode(S2, pigpio.OUTPUT)
GPIO.set_mode(S3, pigpio.OUTPUT)

# Select the C8 pin.
GPIO.write(S0, 0)
GPIO.write(S1, 0)
GPIO.write(S2, 0)
GPIO.write(S3, 0)

# Create the spi bus.
spi = busio.SPI(clock=board.SCK, MISO=board.MISO, MOSI=board.MOSI)

# cCreate the cs (chip select).
cs = digitalio.DigitalInOut(board.D22)

# Create the mcp object.
mcp = MCP.MCP3008(spi, cs)

# Create an analog input channel on pin 0.
chan0 = AnalogIn(mcp, MCP.P0)

def selectPin(pin):
    if pin & 0b00000001:
        GPIO.write(S0, 1)
    else:
        GPIO.write(S0, 0)
    if pin & 0b00000010:
        GPIO.write(S1, 1)
    else:
        GPIO.write(S1, 0)
    if pin & 0b00000100:
        GPIO.write(S2, 1)
    else:
        GPIO.write(S2, 0)
    if pin & 0b00001000:
        GPIO.write(S3, 1)
    else:
        GPIO.write(S3, 0)

# The hall effect sensor will read in the middle of the range
# someplace. Get the middle values for all 16 sensors.
mids = []
for i in range(0,16):
    selectPin(i)
    time.sleep(0.01)
    mids.append(chan0.value)
print(mids)

while True:

    for i in range(0,16):
        selectPin(i)
        time.sleep(0.01)
        val = chan0.value-mids[i]
        if abs(val) > 200:
            print("C",i,"=",round(val/100))
    time.sleep(0.5)

For each magnet distance from 1 mm to 4 mm I recorded the values from all 16 sensors. The same magnet was used for all readings.

C0C1C2C3C4C5C6C7C8C9C10C11C12C13C14C15
1 mm52494749524948505652505358514951
2 mm31292929312929303331303133302931
3 mm22212020222120212321212224212022
4 mm14131313141313141514131415131314

I was pretty happy with the results. For each distance the values grouped fairly well although I would note that the difference between the lowest and highest values read was worst for the 1 mm values (11) but got better as the distance increased, 2 mm difference (4), 3 mm difference (4), and 4 mm difference (2).

In a second set of tests, for each distance, I measured the values returned from 10 different magnets. In all cases the C0 sensor was used.

M1M2M3M4M5M6M7M8M9M10
1 mm35495251535251
515149
2 mm22313332313231313130
3 mm15152219222222222221
4 mm10131413131313131310

Again fairly good grouping although I have highlighted a number of cases where the value for a particular magnet diverged quite a bit from the "norm". The magnets that I am using are cheap and suspect not even neodymium. To try and mitigate these divergences, I have ordered some better neodymium magnets from a reputable dealer. 

Although it will be a pain in the butt, I suspect given these findings that for the best results I may have to calibrate each sensor against the all tiles that will be placed at that position. We'll see. The good news it that I should only have to do this once. 

Discussions