The attached photo shows the serial data format used by a ten pin bowling pinspotter mod. The data cable has four pins.
Questions: What type of protocol does it look like? Is there a library that could help me read it?
I can see that it's 16 bits. One start and one stop bit. Each of 10 bits represents a bowling pin. The last 4 bits seem to tell the pinspotter which action to take.
My first goal is to be able to read all four states. Then I'd like to be able to manually send the signals from an Arduino. Then, maybe, automatically trigger one of the actions. (Specially, I want to automatically reverse the sweep after an off-spot condition.) It might also be useful as a troubleshooting tool.
Do you know what signal is on the 4 pins? If not then this is the first thing to figure out.
I would guess it's something like Clock, Data, VCC, GND but you will have to determine what pin has what and also what voltage level the clock/data is as the UNO/MEGA can only handle 5V and a DUO 3.3V signals.
Riva:
Do you know what signal is on the 4 pins? If not then this is the first thing to figure out.
I would guess it's something like Clock, Data, VCC, GND but you will have to determine what pin has what and also what voltage level the clock/data is as the UNO/MEGA can only handle 5V and a DUO 3.3V signals.
I was starting to think I posted this in the wrong area since I haven't gotten many replies.
Since the data line defaults to high, I should be able to check the voltage. I'm hoping it's 5V since I have an Uno and an ATtiny85 right now.
Today I found that only 3 wires are used. Clock, data, and ground. (I was thinking that it seems similar to SPI.)
I'm working all this weekend so might not have chance to look until Monday. The basic routine to read the signal should be pretty simple from what I have seen.
EDIT: A quiet day at work so managed to knock up some test code for sending & reading back values.
OK, so that's a little confusing to me since I haven't worked with serial data directly before. Only an LCD using I2C and the serial monitor. Is this what is referred to as "bit banging?"
Do I need to mod the code to send specific data? It needs the following binary sequences, including the start and stop bits:
I'd probably wire up 3 or 4 buttons to send one sequence each as a diagnostic tool. Since the 7-pin and 10-pin "pick-off" is basically the same, it probably only needs one of the two sequences.
rekkuuza:
Would this work to send a single command?
Oops my bad, I had not fully read your initial post, just down to the bit that says "Questions: What type of protocol does it look like? Is there a library that could help me read it?" so the code I supplied is designed for reading the signals and the sending part (using shiftOut) is purely to test the reader and does not generate correctly timed signals for sending as the reader will work with variable clock speeds not just the fixed 400Hz.
Let me look at this some more so I can maybe code a timed sending function.
Is the clock signal always running or does it stop when there is no data to send?
What Arduino are you using as this will maybe effect the final code.
Man, I just wrote a reply, but my network freaked out and I lost it.
Using an Uno for testing. Not sure if the clock runs all the time. I did see that shiftOut toggles the clock line which answers the my question about a clock signal. It might work, but at what speed? Running at exactly 400Hz is probably not critical. Maybe 400Hz or less might work?
I have now knocked up a test sketch for sending data at 400Hz. It uses the Timer1 library from here.
The main output code is in an interrupt routine called clkISR that runs the clock continually (with or without data) and clocks out data when present.
Also there is a routine to pass data to clkISR correctly called sendData. You supply the 14 bit value (10 pin bits + 4 control bits) to sendData and it will add on the start/stop bits, determine how many times to send the data (once for strike, 3x for other), pass the data to the ISR and then tell the ISR new data is loaded and repeats data if needed.
rekkuuza:
I'm curious why "strike" is sent once, but another signal is sent 3 times. The "start" pulse I guess happens internally after the signal is received.
I have no idea why but the image you linked in your initial post has strike - transmits once and miss - transmits three times. Maybe only a miss transmits 3 times and everything else only once but the datasheet is not clear on this. I also have no idea what the start u12-3 is all about. You will just need to mess around with different sequences and counts or use a logic analyzer to find out what is currently being sent.
rekkuuza:
I guess I could try sending data to another Uno and have it echo it to the serial monitor. Even nicer if it would display as a logic analyzer.
It might be as simple as patching in the Arduino running the reader code into the CLK,DATA & GND lines and let it show what traffic passes between the proper equipment or maybe you could use the SUMP project to work your arduino as an analyser.
To get started communicating between two Uno boards, I borrowed Gammon's SPI master/slave code. I managed to hack it to send/receive two separate binary bytes.
I tried to set the clock speed down to 400Hz using SPISettings, but I can't really tell if it worked or not. It didn't fail, but I thought maybe it defaulted to some other speed. I even tried 1Hz because I figured I could watch it work at that speed, but it didn't seem to change.
Here's the hacked master code:
// Written by Nick Gammon, February 2011
// Ruined by me, Dec 2015
#include <SPI.h>
void setup (void) {
digitalWrite(SS, HIGH); // ensure SS stays high for now
// Put SCK, MOSI, SS pins into output mode
// also put SCK, MOSI into LOW state, and SS into HIGH state.
// Then put SPI hardware into Master mode and turn SPI on
SPI.begin ();
// Slow down the master a bit
SPI.setClockDivider(SPI_CLOCK_DIV128);
//SPI.beginTransaction(SPISettings(400, MSBFIRST, SPI_MODE0));
} // end of setup
void loop (void) {
//char c;
// enable Slave Select
digitalWrite(SS, LOW); // SS is pin 10
// send test string
//for (const char * p = "Omega-Tek\n" ; c = *p; p++)
//SPI.transfer (c);
SPI.transfer(0x40);
SPI.transfer(0x0C);
// disable Slave Select
digitalWrite(SS, HIGH);
delay (1500);
} // end of loop
A quick test on the machine failed. Now I'm studying how that TimerOne library works. I also figured out that I could use a speaker to listen to see if the clock frequency is actually reduced. (It would probably be difficult to hear 16MHz considering I don't always hear what people are saying to me. heh)
I know I'm moving forward a bit slow here, but now I have my clock running. Should I be using specific pins, or avoiding certain pins, for clock and data while using TimerOne?
"Time" to add a single 16-bit command. Trying to keep it as simple as possible.
Not talking to yourself but I'm not near a suitable PC for several days so cannot check your code.
The code I posted in #10 should easily slow down by altering the timer1 period from 1250 to something higher and hanging a couple of LED's on CLK/DATA pins.