The mystery of "bit banging"

Gramps

Senior Member
The definition says it's using software to do a job normally executed with hardware. 🙄
What in the world does THAT mean? Would someone please illustrate a simple way to bit-bang an LED to do something. Perhaps show the code to flash an LED both ways?
Thanks, Gramps
 

steliosm

Senior Member
BIt-banging is the process of emulating a protocol in software instead of relying on a hardware peripheral to do the same things. The most common cases are emulation of the serial protocol and i2c protocol. In the first case, of the serial protocol, instead of using a serial peripheral on the microcontroller along with a register address to hold the byte for transmission, you are emulating the protocol's high/low sequences and delays using software. Timing is critical in order for the emulation to work properly.

Flashing a LED does not need a protocol or the use of a specific peripheral, except from the GPIO pin. Using a WS2811 based led requires to emulate the WS2811 protocol in order to control the IC inside the Led and thus the Led. You can have a look here about how this is done: PICAXE WS2811 RGB LED Controller.
 

Aries

New Member
I think perhaps you are misunderstanding ... There are things that the "hardware" (i.e. the underlying microcontroller) has built into it (for example, some of them have SPI or I2C) and so, if you want to use one of those things, you use the microcontroller directly (and usually Picaxe will provide a command to do so). Where the microcontroller does not provide the feature, you have to do it yourself, meaning you have to write some code (or software). The manual provides an example of the difference between the M2 series and X2 series Picaxes. The X2 series have a built-in SPI hardware feature, accessed via the SPIIN and SPIOUT commands. The M2 series do not, and the manual shows how to simulate these in software. The technique of pulling pins high and low (in order to send bits) is what is usually referred to as bit-banging.
 

hippy

Ex-Staff (retired)
My definition would be; doing in high-level software, mostly with HIGH, LOW and PAUSE commands, what would commonly be done by an on-chip or external hardware peripheral.

SPI is a good example given. IROUT and IRIN are others where software can be used to issue or read IR commands which use other than the Sony protocol.
 

Gramps

Senior Member
Flashing a LED does not need a protocol or the use of a specific peripheral, except from the GPIO pin.
Ok, so if I used all the pins on my 08 chip and wanted to flash an LED on the GPIO pin, how do you do it? Do you disconnect the download cable with a line of code and then take command of the pin in the normal way?
 

steliosm

Senior Member
Yes, you could do that. The download pin can work as a normal pin. If you use the command "disconnect" you can do what ever you want with this pin. Mind you, though, that you will need to hard-reset the chip in order to get it back to programming mode (turn the power to the chip off and then back on) and also that what ever is connected to the download pin will be affected during the download procedure. If this is just a led, then you will notice that the led flashes during the download.
 

hippy

Ex-Staff (retired)
Ok, so if I used all the pins on my 08 chip and wanted to flash an LED on the GPIO pin, how do you do it? Do you disconnect the download cable with a line of code and then take command of the pin in the normal way?
You don't even need to disconnect the download cable. You can just add a LED+R to the Download SEROUT pin, pin 0, leg 7 ....
Code:
TX <-----------------------------.
                   .--._.--.     |
            ___   -|V+   0V|--.  |  LED
RX >---.---|___|-->|SI   SO|--|--^--|>|--.
      .|.         -|       |- |         .|.
      | |         -|       |- |         | |
      |_|          `-------'  |         |_|
       |                      |          |
0V ----^----------------------^----------^--
Then to control the LED just use "HIGH 0" and "LOW 0" as you would for a LED on any other pin.

This won't cause problems during download but you will see the LED flicker as the download progresses.

If you are also using SERTXD you may see some odd characters in the output data and it would be recommended to use a LOW 0 before SERTXD to avoid lost or corrupt characters.

If that's not what you mean by GPIO pin you will have to detail what you actually need.
 

AllyCat

Senior Member
Hi,
... wanted to flash an LED on the GPIO pin, how do you do it? Do you disconnect the download cable with a line of code and then take command of the pin in the normal way?
AFAIK PICaxe doesn't have one GPIO (General Purpose Input Output) pin, although most pins can be considered as such. However, if you mean the "Programming" (Serial I/O) pins, then the two of these are quite specifically defined as "Input Only" and "Output Only" respectively. The Serial/Programming Output pin can indeed be used for other purposes, provided that you remember that it always starts at an output zero level (not tri-state like most other PICaxe pins) and will indeed carry spurious "0/1 data" levels during programming. In practice it is also possible to use that pin as an Input, but not really recommended except for very special (advanced) purposes.

But it is almost impossible to use the Serial/Programming Input pin as an Output, even if you use the DISCONNECT command (which just prevents a "1" on the pin initiating a new download). It is indeed a hardware I/O pin in the "base PIC" (unlike the "MR" Leg4 pin on most M2s), but even if you change it to an output using a POKESFR command, the PICaxe Basic Operating System seems to come along within some milliseconds and changes it back to an Input. :(

However, most of the "Input Only" pins (e.g. Leg4) can be used in a "Limited" Output mode, by using their "Weak Pullup" resistors (about 35 kohms to the supply rail) to drive for example a MOSFET such as 2N7000, combined with a high valued pull-down resistor (e.g. 100k - 1M) to hold it Off. Most of these pins can be controlled by the PULLUP command, but not the Programming input because the PICaxe Basic Operating system "protects you from yourself". However, the Weak Pullup resistor can be activated by using the appropriate POKESFR command.

Cheers, Alan.
 

Gramps

Senior Member
WOW! What a wealth of good information!
It looks like these work-a-rounds come from hours of head banging but is this really an example of "bit banging?"
 

lbenson

Senior Member
Hardware: buy a blinking LED and put +5V and 0V to the proper leads.

Bit banging; with a normal LED wired properly to pin 1: DO: HIGH 1: PAUSE 500: LOW 1: PAUSE 500: LOOP
 

lbenson

Senior Member
Arguably, even if it's a black box, it's just hardware when you hook it up to your personal micro. A GPS device has lots of processing power, but from the point of view of the programmer on the PICAXE, it's just something which sends strings of ASCII text. You could possibly bitbang what you receive and convert it to ASCII, but on the PICAXE, you just issue a command and the hardware/firmware does the decoding for you.
 

benbaker7

Active member
Hiya Gramps. Try wading through the Wikipedia results relating to 'bitbanging'... When read in conjunction with the foregoing, you'll probably see how it fits in, particularly with Hippy's comments above.

Ben Baker
.
 

Goeytex

Senior Member
When I think of bit-banging I think of making software do what is commonly done in hardware. Like "software serial". This is bit-banged internally by the Picaxe Firmware (serout/serin) as it does not use a hardware UART. It works quite well.

Bit-banging software serial using Picaxe Basic commands would be impractical if not impossible except possibly at the slowest of baud rates due to the command latency (overhead) of the Picaxe. I am guessing that bit-banging any modern protocol with user generated Picaxe Basic would be impractical. But that is not really "fair use" of a Picaxe due to the nature of on-chip interpreted BASIC.

The good news is that in many cases Rev-Ed has done the bit-banging already, eg. bit-banged serial and bit-banged SPI ( and likely others that I have not played with) for those chips where a hardware peripheral is not supported.

Goeytex
 

hippy

Ex-Staff (retired)
Bit-banging software serial using Picaxe Basic commands would be impractical if not impossible except possibly at the slowest of baud rates due to the command latency (overhead) of the Picaxe. I am guessing that bit-banging any modern protocol with user generated Picaxe Basic would be impractical.
You are right about the overhead of a full protocol being too much for a PICAXE but, when it comes to transmitting, throwing a single byte out at higher speed, baud rates aren't quite as low as one might anticipate. You have to choose the appropriate PICAXE and craft the right code but results can be impressive.

The attached code for a 20X2 at 32MHz outputs UART-style serial with a bit time just below 300us, 3,333 baud from 'SendB0'. The 'SendB0Faster' pushes that to just below 200us bit time, 5,000 baud. The 'SendB0Fastest' unrolled loop has a bit time just short of 80us, 12,500 baud. Using a 28X2 at 64MHz would halve the bit times, double the baud rates, 25,000 baud.

No, that's not going to win any prizes in a speed contest, sustained transmission not so great, and receiving is a different kettle of fish, often far more demanding, but such tricks are good enough to allow a PICAXE to directly send IR commands to Sky and TiVo set-top boxes and other devices.

Though not pure bit-banging, it should be possible to keep the HSEROUT generator in synchronous mode fed so it generates a continuous data stream which opens the door to even lower bit rates and higher baud rates.
Code:
#Picaxe 20X2
#No_Data
#No_Table

Symbol TX = C.0 : Symbol TX_PIN = pinC.0

PowerOnReset:
  Low TX
  SetFreq M32

MainLoop:
  Do
    ;     _   ___   _     _
    ; ___| |_|   |_| |___| |___    lsb sent first, msb last
    ;     S 0 1 1 0 1 0 0 1 P
    b0 = %10010110 : Gosub SendB0
    b0 = %10010110 : Gosub SendB0Faster
    b0 = %10010110 : Gosub SendB0Fastest
    Pause 1000
  Loop

SendB0:
  w0 = b0 << 1 | 0x401
  Do
    TX_PIN = bit0
    w0 = w0 >> 1
  Loop Until w0 = 1
  Return

SendB0Faster:
  w0 = b0 << 1 | 1
  ptr = 10
  Do
    @ptrDec = bit0
    w0 = w0 >> 1
  Loop Until ptr = 0
  ptr = 10
  Do
    TX_PIN = @ptrDec
  Loop Until ptr = 0
  Return

SendB0Fastest:
  TX_PIN = 1
  TX_PIN = bit0
  TX_PIN = bit1
  TX_PIN = bit2
  TX_PIN = bit3
  TX_PIN = bit4
  TX_PIN = bit5
  TX_PIN = bit6
  TX_PIN = bit7
  TX_PIN = 0
  Return
bit-bang-uart.jpg
 

Gramps

Senior Member
wading through the Wikipedia results relating to 'bitbanging'...
More like slogging!
I started my "research" in Wikipedia, looking up the words and phrases used. Not having been raised on "computereese," the explanation was a "bit" muddled. 🙄
However, I do have a new appreciation for the Basic Compiler's built-in bitbanging!
 

Goeytex

Senior Member
The attached code for a 20X2 at 32MHz outputs UART-style serial with a bit time just below 300us, 3,333 baud from 'SendB0'. The 'SendB0Faster' pushes that to just below 200us bit time, 5,000 baud. The 'SendB0Fastest' unrolled loop has a bit time just short of 80us, 12,500 baud. Using a 28X2 at 64MHz would halve the bit times, double the baud rates, 25,000 baud.
Well done. This is the same result I got when using "fastest" with a 14M2 as I did not have the luxury of "<<" or ">>" with this chip. I only tested with the fastest method , but added delays to get to 4800 baud. (9600 not doable) due to command latency. This code prints Hello World to a terminal using True RS232/TTL via a CP2102 Adapter connected to PinB.3

Code:
;*******************************************
;Example - Bit-banged Serial Out @ 4800 baud
;True Level (non-inverted)
;*******************************************

#picaxe 14M2
#no_data

Output B.3
Symbol SerOutPin = PINB.3
SerOutPin = 1   'True RS232/TTL Idle High
Symbol serdata  = B0  ' Bit0 to Bit7

SetFreq M32
Pause 1000      'Stabilize

'Clear Terminal (Using Cool Term)
SerData = 12 : Gosub Send_Serial
Pause 400

Main:
Serdata = "H" : Gosub Send_serial
Serdata = "E" : Gosub Send_serial
Serdata = "L" : Gosub Send_serial
Serdata = "L" : Gosub Send_serial
Serdata = "O" : Gosub Send_serial
Serdata = " " : Gosub Send_serial
Serdata = "W" : Gosub Send_serial
Serdata = "O" : Gosub Send_serial
Serdata = "R" : Gosub Send_serial
Serdata = "L" : Gosub Send_serial
Serdata = "D" : Gosub Send_serial
Serdata = 13  : Gosub Send_serial
SerData = 10  : Gosub Send_serial
Pause 8000
Goto Main

Send_Serial:
  'Provides 208us Bit time for 4800 baud
  SerOutPin = 0 : Pauseus 48  'Start Bit  
  SerOutPin = bit0 : Pauseus 48
  SerOutPin = bit1 : Pauseus 48
  SerOutPin = bit2 : Pauseus 48
  SerOutPin = bit3 : Pauseus 48
  SerOutPin = bit4 : Pauseus 48
  SerOutPin = bit5 : Pauseus 48
  SerOutPin = bit6 : Pauseus 48
  SerOutPin = bit7 : Pauseus 48
  SerOutPin = 1 : Pause 2   'Stop Bit
Return
25597
 
Last edited:

hippy

Ex-Staff (retired)
This code prints Hello World to a terminal using True RS232/TTL via a CP2102 Adapter connected to PinB.3
Excellent work.

One of the issues with bit-banging on a PICAXE is that timing can vary depending on where a command falls in memory so adding code can sometimes push timing out. To help with that the technique I have used is to put the time sensitive code at the start of the program and jump round it .
Code:
#Picaxe ...

PowerOnReset:
  Goto Init

Send_Serial:
  ...
  Return
 
Init:
  ...
Main:
  ...
  Goto Main
 

Technoman

Senior Member
Just a coincidence...
Yesterday night, searching for some documents in the attic, I came across a piece of software I wrote at the end of the eighties for the Intel 87C51. At that time I was working in a company manufacturing large industrial control system. Someone thought the I2C bus, only used then in TV set and VCR, was interesting in a new design. Big banging was the only solution as the chip, as probably other MCU, has not any I2C embedded peripheral.
It turned out to work very well in an industrial environment.
 
Top