这是一个使用 C++ 的嵌入式解决方案,我正在读取手机屏幕的亮度变化,从非常亮(白色)到暗(黑色)。
使用 JavaScript 和一个非常 simple script我以 100 毫秒的间隔将网页的背景从白色更改为黑色,并在亮度传感器上读取结果,正如预期的那样,浏览器的计时不是很精确,有时它会执行 100 毫秒,有时更少,有时更多,偏差很大次。
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);
在知道浏览器上的计时方式之前,我最初的想法是使用异步串行通信,其中一些知道“字”来同步数据流,就像 RS232 与他的起始位一样,但在 RS232 上,时钟非常慢精确。
我可以使用第二个传感器来读取屏幕的不同部分作为时钟,在这种情况下,即使显示器或浏览器“决定”更快或更慢,我的系统也只会在有时钟信号时读取(this is a similar application是他们滑动传感器而不是根据我的需要使屏幕轻弹),但这需要更复杂的硬件系统,我希望在寻找软件解决方案之前不要让事情变得复杂。
我不需要高速,我尝试发送的数据大约只有 8 个字节。
最佳答案
对于任何类型的异步通信,您都依赖于发送器以固定的时间间隔发送新的数据“位”,并且接收器以相同(固定)的时间间隔对数据进行采样。如果浏览器的计时不准确,您只需降低比特率,直到足够好为止。
您可以使用一些技巧来帮助您提高可靠性:-
a :发送时,提前计算每个“位”所需的“开始发送时间”,并根据当前时间与所需时间修改每个位“发送”后的延迟。这意味着您将避免累积错误(即,如果位 1 发送得有点“晚”,位 2 的延迟将减少以进行补偿),而不是每位延迟恒定的 N 微秒。
b:接收时,您必须比预期的变化速度更快地对传入数据进行采样。 (UARTS 通常使用 16 倍过采样)这意味着您可以与“起始位”(图中从 1 到 0 的初始变化)重新同步,然后您可以在其时间周期的预期“中心”对每个位进行采样。
换句话说,如果您以 1000us 的间隔发送数据,则以大约 62us 的间隔采样数据,当您检测到“起始位”时,您会等待 500us 将您置于时间段的中心,然后采取8 个单位样本,间隔 1000us,形成一个 8 位字节。
关于c++ - 串行通信协议(protocol)设计问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20586378/