Bynase

From Laen
Jump to: navigation, search

Contents

Why Bynase

In the end, all Bynase does is send a value across a digital line.

There's a bunch of other ways to accomplish that goal-- ones that can send that value a heck of a lot more precisely than Bynase: shift registers,i2c, SPI, RS232, USB, and tons of others.

Using a serial protocol has problems, though: Your receiver has to be listening at the exact time your sender is sending. They're point-to-point; you typically can't talk to more than one chip at the same time. Some protocols require very precise crystal oscillators.

..And any noise in the system can make communication totally unreliable. An extra "1" getting injected in the data stream can turn 00110100 into 10110100.

So, bring in bynase. The basis of bynase is: Toggle a pin so that it's on a percentage of the time. And on the receiver: Take a bunch of samples of a pin to determine what percentage of the time it's HIGH. If you take 100 samples, and it's HIGH for 10 of them, then your value is "10".

So, you _could_ just use PWM on the sender. With an 8 bit counter, you get 256 steps between "on 0% of the time" and "on 100% of the time." Your receiver still samples the line occasionally, and still determines that it's on for a certain percentage of the time.

Sounds pretty good, right? You have the essentials: The line is HIGH for 10% of the time, LOW for the other 90%, and the receiver can see that.

EXCEPT, that it's very predictable when the pin will be HIGH and when it'll be low. It's going to go HIGH for the first 10% of the cycles (25 cycles), and LOW for the last 90% (230 cycles). What if you're running two ATTiny84s, both at 8MHz, and your receiver ends up sampling every 256 cycles? Every time it reads the wire the sender is at the same point in its PWM cycle, and it always gets the same value.

So, Bynase throws some noise in the line. Instead of being on for 25 cycles, and off for the next 230 cycles, it does this:

value = 10
if value < a random number between 0 and 99.
  set the pin LOW
else
  set the pin HIGH

So, every time it calls that block, there's a 10% chance it'll set it high, and a 90% chance it'll set it low.

A receiver can be as simple as:

for 100 times
  if input is high
   result = result + 1

..And as long as you run that while the sender is sending, you get a value between 0 and 100.

So now it doesn't matter if your receiver is listening right as your sender is sending, or if their clocks are synced up, or if they're running at the same speed, or even if there's more than one listener.

It doesn't even matter if the line is noisy. The value you're sending includes a bunch of random noise of its own. If you need a cleaner number, you just take more samples.

Randomness

It's not very important that the number be perfectly random. It just needs to jump around alot between being a low number and a high number. I use AVR GCC's "rand()", which I found out today consumes an obscene number of cycles (more than 1500).

Ward Cunningham uses an "Inverted Counter".

Here's a C implementation of an Inverted Counter suitable for AVRs. Note that all it does is count upwards, then invert the number on the return.

uint8_t counter;

uint8_t byrand( ) {
 unsigned char b = counter++;
 unsigned char result = 0;
 while (b) {
   result <<= 1;
   result  |= b % 2;
   b      >>= 1;
   }
 return result;
}

Parts

Simple Repeater

  • INPUT: A bynase value
  • OUTPUT: A (matching) bynase value.

Reads a bynase value on one pin, and writes it out to another pin. It doesn't just repeat the signals, it repeats the averaged bynase value.

This tends to be a randomness amplifier, pushing a system higher or lower.

Inverting Repeater

  • INPUT: A bynase value
  • OUTPUT: The inverse of the bynase value.

Reads a bynase value on one pin, then writes it out inverted to another pin. If it reads a value of 0%, it'll write out a value of 100%. 75% gets you 25%.

Other Parts

  • Multiplier - Scales Signal1 up by Signal2%.
  • Divider - Scales Signal1 down by Signal2%
  • Bynase Servo Controller - 0 is 1000us, 50 is 1500us, 100 is 2000us.
  • Accelerometer to Bynase - Reads i2c accelerometer data from a Wii Nunchuck and writes X, Y, and Z values out three pins.
  • LED Bar Graph - Visually represents Bynase value on a 10 LED bar graph.
  • Averager - Takes two bynase values, and outputs the average of the two.
  • Analog to Bynase - Takes any analog value and writes it out as bynase. For example: Hook a pot up to the pin, and feed the bynase out into the dampener or amplifier.
  • Bynase to Analog - Takes a bynase value and PWMs out an analog value.
  • Serial to Bynase - Set via i2c, stores the value in EEPROM, pulses whatever value you give it.
  • Synapse - Every time it receives a pulse, it gains "energy". When it has enough "energy", it pulses an out on one of its pins.

Experiments

Repeater Network with Feedback

Set up a string of nine simple repeaters with a simple "Read a bynase value from one pin, write that bynase value to another pin". Connect the last output to the first input, creating a feedback loop.

Behavior: It's a bistable system that tends to settle high or low. It can take a long time to stabilize, though.

Repeater Network with Troublemaker

Same as the repeater network, but with an inverted repeater at the end of the chain. The repeater network (which is naturally bistable) will try to settle on a high or a low, but the inverted repeater tosses it back in the other direction.

Behavior: A bunch of waves oscillate down the line, eventually devolving into chaos (a standing wave, I think), then it starts to oscillate again.

Questions

Use interrupts to send bynase out?

Network effects?

Tri-stating?

What is the sound of a one simple repeater feedback loop? I bet it would be bistable high/low.

What about an inverted repeater simple feedback loop? I bet it would average to 50%.

What's the fastest you can send a value between 0 and 10 via bynase?

Multiple transmitters and the voltage divider effect?

Why not just PWM to write? Why use the randomness? Because the two devices could get clock-locked, causing harmonics. If Device1 is PWMing at 15kHz, and Device2 is reading at 15kHz, it'll always read on the low or the high. With any two frequencies, this will be a problem to some extent.

Properties of Bynase

General Bynase

My gut feeling is that you want to "write" more often than you "read".

The more samples you take when receiving your bynase value, the more accurate that value will be.

My Bynase Implementation

Writing sucks, because I have to generate a random number each time, and that's a bit CPU intensive.

Reading sucks, because you have to generate a running average of the last N samples. The more samples you take, the more accurate your value is, but the more memory it requires.

Observations

Transmitting a full bynase value is slow, but propagation is quick. There's a lot of wave effects here..

Links

Bynase Protocol

Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox