HP5508A replacement v1.8 - remove SoftwareSerial

It turns out that SoftwareSerial is not only expectably slow, but also causes the board to freeze spontaneously for some reason.

Since there are 2 UART blocks available in the PIC, lets switch to HardwareSerial. The second UART on the DP32 chip (PIC32MX250F128B) is on the PPS pins for RB14 and RA1. So we only need to move one pin, HC05/RXD from 18/RA4 to 7/RB14:

The updated pin assignment is this:

Usage Pin (Arduino/PIC) Notes

   REF        0/RB5   
   AM2303     1/RB7              
   BMP180     2/RB8                 all I2C devices - not just BMP any more
   BMP180     3/RB9                 all I2C devices - not just BMP any more
   USB+       4/RB10
   USB-       5/RB11
   HC05/RXD   7/RB14
   HC05/TXD  10/RA1 
   MEAS1     11/RB0                 LED4
             12/RB1                 LED3
   MEAS2     13/RB2                 LED2
   MEAS3     14/RB3                 LED1
   CLOCK     15/RA2
   HC05/EN   17/RB4

And then we need a software update.

Serial.println() is a blocking call and the hardware FIFO buffer is only 8 bytes deep, so if we send the whole data string at once we will wait until the transfer is complete instead of being able to handle the stream to the USB serial connection. The default rate of the HC05 is pretty slow, but regardless of its' speed, we don't want to block on the FIFO. The solution is as follows:

1. declare a buffer for the current data. If new data is available before this buffer has been transmitted, we skip the new sample

2. write a function that takes characters from the buffer and puts it into any available space in the FIFO, but does not block

3. Call that function frequently

For 1,

#include <CircularBuffer.h>
CircularBuffer<char> bluetoothBuffer(300); // make some space for hardware accelerated output
buffer[offset15-1]=0;                                                         // terminate message buffer
        if (0==bluetoothBuffer.available())
          for (int i=0;i<strlen(buffer);i++)
        // update queue
        if ((FIFO_SIZE-1)==tail)  // check for wrap around
          tail = 0;                    // update tail location
          tail = tail +1;              // update tail location  

For 2,

void SendBluetoothData()
  {   // direct to hardware FIFO
  if (bluetoothBuffer.available())
    if (U2STAbits.UTXBF == 0)
      U2TXREG = bluetoothBuffer.read();

this part was quite frustrating to get right. Thanks to Matt at UECIDE.org:


For 3,

void convertToAscii( INT64 value,int offset)
// constant time version of string conversion. For speed, not all are considered
// with 15 divisions by 10, and at 10 MHz that is about 30 years of continuous operation
// 64 bits can be done with 19 divisions
  int i;
  SendBluetoothData();  // needs to be called periodically, so I am doing it in this frequently run routine
  if (value<0)
    value = -value;
  for(i=numbersize-2; i>=1;i--)
    buffer[i+offset] = (value % 10) +'0';
    value = value / 10;
  buffer[numbersize-1+offset]= ' ';
  SendBluetoothData();  // needs to be called periodically, so I am doing it in this frequently run routine
void loop()
    sensorCounter++;  // cycle through the different sensors
    if (head != tail)  // only send a new data packet if the queue is not empty; probably superfluous since serial.println blocks :/

That works quite well, but I should probably make the data transfer interrupt driven in the future....