Archives

Bit-banging Serial Out for Arduino debugging

On one of my Arduino projects I needed a debugging stream to show what is going on. Normally I would be using the hardware serial UART for that, but on my ATMega328p the hardware serial port was already in use. More specifically, it was the serial port that I was trying to debug.

I’ve tried a lot of alternatives like SoftwareSerial and AltSoftwareSerial, but both seemed to mess up things more than was helpful. The problem with both of these libraries is that they are written to support receiving of serial data, while I was only interested in getting data out. Both these libraries take up a precious timer interrupt which I needed for my own drivers.

After someone suggested to send out the data manually, i quickly came up with a class that did exactly what I wanted, no more no less. Check out the WikiPedia page on async serial. It is really a very basic protocol. Just flip a port on the right time and you are good to go.

Puerto_serie_Rs232

The script uses Arduino pin 13, PB5 (also known as the SCK pin, or hardware pin #19) on a ATMega328p to output serial data at 9600 baud. If you want 38400bps, change the periodMicroSecs to 26.

Do not forget to add this to your setup() code:

pinMode(13, OUTPUT);

Without further ado, here’s the code.

#include <arduino.h>

//use hardware port 13 (PB5) for max performance.
class debugStream
{
    public:
      debugStream()
      {
        writePin(HIGH);
      }
      void println(const char *line)
      {
        print(line);
        writeByte('\r');
        writeByte('\n');
      };
      void print(const char *line)
      {
        while(*line != 0)
        {
          writeByte(*line);
          line++;
        }
      };
      void println(int i)
      {
        char sbuf[10];
        sprintf(sbuf, "%d", i);
        println(sbuf);
      };
      
      //http://www.dnatechindia.com/Tutorial/8051-Tutorial/BIT-BANGING.html
      void writeByte(uint8_t c)
      {
         //int periodMicroSecs = 104; //1/9600  interval
         int periodMicroSecs = 26;  //1/38400 interval
         
         writePin(LOW);
         delayMicroseconds(periodMicroSecs);
         for(uint8_t b = 0; b < 8; b++)
         {
           writePin(c & 0x01);
           c >>= 1;
           delayMicroseconds(periodMicroSecs);
         }
         
         //stop bit
         writePin(HIGH);
         delayMicroseconds(periodMicroSecs*2);
      };
      
      void writePin(bool value)
      {
        if(value)
        {
          PORTB |= 0b00100000;
        }
        else
        {
          PORTB &= ~0b00100000;
        }
      };
};

NOTE: check out the periodMicroSecs*2 on the stop bit. The extra delay was necessary on my machine to stabilise the output, although from a protocol standpoint this should not be necessary.

Simplicate 2.0 release issues

Yesterday I released SimplyStats 2.0 to the public. It took less than 30 minutes before I received the first crash report. The crash appears when starting the App, so making it completely unusable for some customers. As it turns out, SimplyStats 2.0 does NOT work on iOS 8.0.2.

The (Dutch) screenshot below shows the logged Exceptions per iOS version for 2.0, since the release. The secondary dimension (below) shows me that there are 59 exceptions in total, 15 on iOS 8.0, and 44 on iOS 8.0.2. For the sake of argument: no exception have occurred on other platforms.

Crashes_en_uitzonderingen_-_Google_Analytics

Why did this bug slip through? Well first of all, iOS 8.0 and iOS8.0.2 were released by Apple, but quickly updated to 8.1. iOS 8.0 is full of strange stability bugs. The reason I cannot test it, is I do not have any devices running 8.0(.2) and neither do my Beta testers. The iOS simulator (used to develop Apps) for version 8.0 has been pulled offline by Apple. There’s no way I can test it.

My apologies.  Apple suggests upgrading the system software and I agree to that suggestion.