progress!
having some issues with brightness and contrast right now. the issue with contrast is it takes some time for my code to load the shift register with the value of the next digit and during this time the previous display's digit is visible. its not a very big amount of time in relation to the time the actual digit is visible, but its enough to affect readability. my solution to the problem was to lower the resistance values for the current limiters, from 470 to 180 ohms. the value i actually want is 250, but with the 470s the displays were dim, and now their to bright, and the contrast issue is the same. ive inserted a "blanking" delay at the end of an output cycle, where i turn off all the displays for a set length of time. it doesnt really work all that much. ultimately i figure the problem with the contrast is actually a problem with the arduino ide. its just too slow. you waste hundreds on ns of time just setting one of the pins values (times multiple pins), thus pissing away precious microseconds. the solution will be to talk to the registers directly. i knew at some point i would need to come up with tighter code, so this is not a major issue.
another odd bug with my code, which left me scratching my head was that for some reason it wouldnt let me output values from an array over a typical for loop, but it would let me output the value from the loop counter, and thats what you see. you may also notice the beer, fiy thats my 5th one, so i better stop tweaking before i burn out my displays.
*edit: reasons not to code drunk*
nested loops end up in places that a couple of ifs should have been used
variable names are indecipherable gibberish
comments are 80% swear words complaining about why the code underneath it doesnt work
you #define entire lines of code
you forget important idiot proofing (your microcontroller wont tell you when it segfaults)
you also forget that your target mcu cant multiply
anyway i got the serial interface somewhat working. though im not happy with my packet format, which was designed for simplicity (and my blood alcohol level when i designed it). i decided to make the entire command a single byte, so i wouldn't need to go through the trouble of finding sync. the first nibble was the opcode and the second nibble was the parameters for that code. of 16 possible op codes 0-9 were used to write a hex value to to a specific digit. the other 6 were debugging codes, to do things like dump all 10 display values in raw mode, or dump the font, 2 more to allow you to set and clear decimal points, and 2 more to read a single digit in hex and raw. so a lot of redundancy there.
anyway this is somewhat cumbersome. im actually thinking of using a text format. ascii is only 7 bit, and i can use the 8th bit for sync, just set it for the first byte and look for a byte > 127. the opcodes can just use a single character, and this gives me like 96 possible codes (minus control characters, which id rather not use). the downside here is it would be very slow. say i want to write f in hex to digit 5. i would do W5F. i could also do simd codes: like WAA55F00C666 (W is the write hex command, A is the parameter, for write all, followed by the values to be written, lol). writing raw values would just take 2 characters to represent their values in hex, and read commands would be very short. if your controlling this in lua this would be a really easy and intuitive way to do things. but this device will sit attatched to anomain mcu, and micro controllers aren't so good at text processing.
my other option is to use a binary format, that can be sorted out with bitwise operations. i can keep my sync bit, and use the remaining 7 bits to store opcodes/data. i can drop to 3-bit opcodes instead of 4 (i dont need as many because i can allocate as many additional bytes for data as needed), and this gives me an entire nibble for parameters. all the read all commands would be one byte commands with no additional bytes. there would be 4 read commands, for raw/hex/text, and another to read the decimal point flags. the read commands all have complementary write commands. the difference is that additional bytes would follow the command for the data. hex and text modes only need include another byte. raw mode and decimal point mods require 8 and 10 bits respectively, since the 8th bit is for sync, these need 2 data bytes. so all commands are less than 3 bytes. the 4-bit parameters also allow for expansion. values 0-9 index individual displays, where a is the all command, and in the case of write commands would require additional data bytes, and probibly some formatting to save space. other values can be used for settings, like brightness and contrast. so i rather like this idea.
ultimately i intend to use an i2c interface for this. i2c is a lot easier do deal with. it has all its sync data build in, and its designed with an address-register-data format. you can also write to a series of registers by sending additional data bytes. reading is a little bit more trouble, you need to send a address-register to the device, then you can receive bytes back starting from that register, and you can also receive a series of bytes in this way, with the register incrementing by one for each. it makes using a uart seem archaic. for now im going to be using a serial interface. i will try to do some interface with freespace though serial. im going to use a proxy script like i did before. freespace will talk to it over tcp/ip loopback, but ultimately will talk to the arduino over serial. id use my ethernet shield, but the library im using only supports tcp server. so i couldnt use my existing udp code, where my proxy script just needs a little modification. so i will use that for my initial testing.