4 days ago •
So the whole thing works (at least one of the two prototypes) but I have to admit that I had to "cheat" because after many difficulties with a lousy design, I finally caved and added a PIC16F818... It simplifies many things but creates its own problems.
But it works.
One conclusion is : there is no simple or easy TTL/SSI/MSI chip that helps with building a decent Finite State Machine or a simple automaton. The MC14500B would require several companion chips, including some sort of PROM, which would be overkill for a simple design.
Overall, I see now why microcontrollers have emerged and are a market by themselves. Yet I wish there was a simpler, smaller solution for the trivial functions...
04/14/2019 at 22:02 •
My initial idea was simple, simplistic and optimistic... I had to change everything and here is the result after I rewired the power supplies :
At first I wanted to power everything from a single 5V source : motor, relays, logic. I realised that they had very different requirements and I had to split the rails, starting from a single 12V input:
- The relays are powered from a DC/DC module
- The DC/DC also powers the motor through a crude current limiter (2 diodes, a resistor and a BD237 NPN transistor with gain around 100) to keep the peak under 400mA
- A separate 7805 provides some tens of mA to the logic
The whole circuit should be more stable and hence predictable... Right ?
04/13/2019 at 22:51 •
After I redesigned the power supplies (the system can be powered from 12Vdc) and added a current limiter to the motor supply, the design shifts to digital (more or less). I added a 4-bits counter (74HC193 inherited from the #Discrete YASEP project), and a detector for the timer, based on a plain 74HC04. That's where things got really funky, because I built 1) an oscillator 2) a flip-flop 3) a level corrector, just with this 6×inverters chip.
I try to keep my schematics up to date and I should scan them but I use many transistors, diodes, capacitors and resistors to get things done. I have chosen the "discrete parts" route, because I don't want to write a single line of code. It's both ugly and beautiful, from all the LEDs I have sprinkled all over the board to show the operation of the system...
The schematics need some cleanup before I publish them...
03/08/2019 at 22:14 •
Now do you see what I mean ? :-)
03/04/2019 at 00:47 •
The "user interface" to the "trap chess" board is (beyond a "start" switch) the classic chess dual-timer that each player taps to record the elapsed decision time.
Bob got a cheap but nice looking timer that I reverse-engineered to get to the useful signals, mainly the top switch, which triggers my machinery when it changes state.
First, the timer operates on a single 1.5V AA battery. There is no point in having it installed inside the timer so I power the timer with a ... "shunt regulator". 1.5V is more or less the drop of 2 silicon diodes so here we go : 2× 1N4148 in series, driven by the main 5V supply. Now, usually, you use a resistor to limit the current, but I also used an old red LED in series, to show that the circuit is powered.
The timer draws very very little current but the diodes need to pass quite a lot of current in order to get a suitable drop. The resistor in series with the LED sets the current at around 10mA, and most of it is lost.
The LED also acts as a reverse-blocking diode for when the voltage drops (due to electromechanical activity). A capacitor (100µF) keeps some charge during the transients. Actually, the diodes' leakage and the timer's consumption are so low that the timer won't reset by itself... I need to really remove the connection with 1.5V for the timer to restart correctly later.
The top switch (lap switch ?) has no physical contact (to avoid wear). A reed magnetic switch does the work though. Now, the switch is not powered on permenently : it's polled during 2ms every 32ms. I could patch a wire that sends a train of pulses when the switch is closed, and no pulses when open.
I reused the previous circuit, using 2 × BJT, to filter that low-level signal, but development was not as easy as expected. Using my scopes, I could trace and understand my various mistakes and false assumptions. Now a LED is on when the top switch is in one position :-)
(scanned schematics to follow soon)
02/18/2019 at 04:20 •
I finally solved the problem with the current limit detector. It takes not one but 3 transistors...
The first transistor detects when the shunt resistor exceeds 0.7V.
The second one short-circuits a 33µF capacitor to ground. When the current exceeds 200mA, the capacitor charges slowly.
The 3rd transistor is another "detector" that turns the LED on when the capacitor reaches 0.7V (it gives a nice level instead of an analog value).
The trick was to determine the RC constant... but back-of-the-envelope estimates worked well on the first try !
The ULN2003A is also wired so the relays can be driven by weak CMOS signals.
02/12/2019 at 00:39 •
Board #2 is built and I added more switches to control the current. This makes 6 control signals with fanouts 4, 3, 3, 1, 1, 1. I'll have to wire the ULN2003s...
Now the problem is to detect the end of course through the current in the motor, which is measured by a 3.3 Ohms shunt resistor connected to the base of a transistor. The oscilloscope shows that the generated signal is far from the one I expected... End of course should be set after 50ms of "overcurrent" but should be reset as soon as the current drops under the 0.2A. I try to do a discrete version but it's not as easy as I thought.
01/21/2019 at 02:42 •
I finally decided to use relays to distribute the power to one selected servo.
The path of the power goes through an unbalanced binary tree, made of parallel 8-tree and 4-tree, with a control vector of [1, 2, 4, 4] (total is 11, which is 12-1 as expected).
The relays have a 160 ohms coil, or 32mA @ 5V. The driving requirements for the tree are 32, 64, 128, 128 mA. This is well within the range of a ULN2003 and the total draw (worst case) is about 0.35A.
The reverse side is the usual mess:
The 16-positions knob selects one of the 12 outputs, 4 outputs have a duplicate code. I can test the behaviour by hand and the manual control is really helpful during prototyping and later for installation and troubleshooting.
The hex encoder must be disabled during normal operation, which is selected by a small slider switch. This requires anti-feedback diodes on the knob's inputs, hence an increase of the power voltage.
Oh and of course, there is a lot of work to do because now, the servo's motor must be wired directly (the control PCB must be removed). But for now I must focus on controlling the current's direction and detecting the increase of current when the servo has reached its limits. Hint: a 3.3 Ohm resistor develops a potential less than 0.7V when the servo operates normally.
01/08/2019 at 01:48 •
I'm getting even more lazy.
Dealing with signal levels of the servos when they are turned of gets annoying so... What about driving the motors directly ?
The servos can be unscrewed and we can access the two wires, which are easy to desolder. So all I need is a dozen of motor drivers ("H bridges") that can hold a few hundreds of mA. But... only one motor needs to be driven at the same time.
I have enough Allegro A3968ELB (dual H Bridges) for this purpose but that still sounds overkill.
Another idea is to share the sensors' selection with the motor drivers' outputs. It's a bit tricky...
I am very tempted to implement those functions with relays. They draw a lot of current but convenience of design and simplicity beat many other constraints, and I don't want to have to program anything...
12/22/2018 at 04:52 •
I'm lazy and don't want to use a microcontroller so here comes the FPGA.
The function is pretty simple so VHDL simulation will be easy.
The servos are controlled by one output, one pin driven in PWM : 1ms long pulse for closed, 2ms long pulse for open. There would be a bit more than 500ms in each state : >500ms open, >500ms closed. The PWM pulses are repeated at about 50Hz, or 20ms apart. This could be either 16ms or 32ms...
Already we see what can be done :
- a prediv from the 50MHz integrated clock, down to 1KHz (a counter from 0 to 49999) => 16 bits
- a counter for the pulse repeat rate : the pulse is high during the first cycle (or two, for the open case). 20ms gives us 5 bits.
- A counter for the open or close period : 50 repeats gives us a 6-bits counter
- 2 state bits for wait-open-close
The state affects one bit of the 2nd stage, so the pulse is longer or shorter. And that's all for the PWM+FSM.
There is a need for a RNG : it can be taken from bits of the free-running counter, sampled when the trigger state changes. Some probability shaping is required, one bit gives 1/2, and 2 bits combine to add the 1/4 and 3/4 chance (respectively with AND and OR). Maybe probabilities 0, 1, 1/2, 1/4 and 1/8 could be selected...
One input needs to be selected when the RNG is 1. Otherwise, the FSM returns to the WAIT state. There are up to 16 inputs max (10 or 12 in practice, 14 outputs max) so this maps to the PWM counter (which is also the RNG ?). The counter would scan the inputs until one is set to 1. The loop can be stopped when non-existent input 16 is reached, set to 1.
The FSM has these states and runs at 1KHz :
- 0 : wait until the trigger input changes. PWM counter is running at 1KHz. Servo power is off.
- 1 : scan / select input (1 to 16 cycles max), select output
- 2 : if conditions met : power on the selected servo and run 64 cycles of "open"
- 3 : run 64 cycles of "close" then goto back to 0
yeah, this should work... it could even be implemented mostly as TTL/CMOS :-D
There are however many other issues to solve, such as : how to send the PWM signal properly and avoid electrical issues when the servo is not powered ? So far the servos are switched from the low side, such that the PWM input will float around 5V when idle, which is not suitable for classic (push-pull) digital outputs...