2
votes

This is an embedded solution using C++, im reading the changes of brightness from a cellphone screen, from very bright (white) to dark (black).

Using JavaScript and a very simple script im changing the background of a webpage from white to black on 100 milliseconds intervals and reading the result on my brightness sensor, as expected the browser is not very precise on timing, some times it does 100ms sometimes less and sometimes more with a huge deviation at times.

    var syncinterval = setInterval(function(){
        bytes = "010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101";

        bit = bytes[i];
        output_bit(bit);

        i += 1;
        if(i > bytes.length) {
            clearInterval(syncinterval);

            i = 0;
            for (i=0; i < input.length; i++) {
                tbits = input[i].charCodeAt(0).toString(2);
                while (tbits.length < 8) tbits = '0' + tbits;
                bytes += tbits;
            }
            console.log(bytes);

        }
    }, sync_speed);

My initial idea, before knowing how the timing was on the browser was to use asynchronous serial communication, with some know "word" to sync the stream of data as RS232 does with his start bit, but on RS232 the clocks are very precise.

enter image description here

I could use a second sensor to read a different part of the screen as a clock, in this case even if the monitor or the browser "decides" to go faster or slower my system will only read when there is a clock signal (this is a similar application were they swipe the sensors instead of making the screen flicks as i need), but this require a more complex hardware system, i would like not to complicate things before searching for a software solution.

I don't need high speeds, the data im trying to send is just about 8 Bytes as much.

2
Could you change your system so that you could display a split background with data on one half of the screen and a clock on the other half of the screen? You'd need two sensors, but you'd be able to let the browser control the clock, and thus timing should inherently be easy to do... - sonicwave

2 Answers

1
votes

With any kind of asynchronous communications, you rely on transmitter sending a new 'bit' of data at a fixed time interval, and the receiver sampling the data at the same (fixed) interval. If the browser isn't accurate on timings, you'll just need to slow the bitrate down until its good enough.

There are a few tricks you can use to help you improve the reliability:-

a : While sending, calculate the required 'start transmit time' of each 'bit' in advance, and modify the delay after each bit has been 'sent', based on current time vs. required time. This means you'll avoid cumulative errors (i.e. if Bit 1 is sent a little 'late', the delay to bit 2 will be reduced to compensate), rather than delaying a constant N microseconds per bit.

b: While receiving, you must sample the incoming data much faster than you expect changes. (UARTS normally use a 16x oversample) This means you can resynchronize with the 'start bit' (the initial change from 1 to 0 in your diagram) and you can then sample each bit at the expected 'centre' of its time period.

In other words, if you're sending data at 1000us intervals, you sample data at ~62us intervals, and when you detect a 'start bit, you wait 500us to put you in the centre of the time period, then take 8 single-bit samples at 1000us intervals to form an 8-bit byte.

1
votes

You might consider not using a fixed-rate encoding, where each bit is represented as a sequence of the same length, and instead go for a variable-rate encoding:

Time:  0 1 2 3 4
0:     _/▔\_
1:     _/▔▔▔▔▔\_

This means that when decoding, all you need to do is to measure the time the screen is lit. Short pulses are 0s, long pulses are 1s. It's woefully inefficient, but doesn't require accurate clocking and should be relatively resistant to inaccurate timing. By using some synchronisation pulses (say, an 010 sequence) between bytes you can automatically detect the length of the pulses and so end up not needing a fixed clock at all.