Saturday 23 November 2013

(Ab)using CurrentCost dev boards part 3

In the previous parts, I looked at how things were connected and how the RF transmitter was configured. This time around, I want to see if I can actually transmit something! The PIC16F689 is the microcontroller in use, and Microchip have made the IDE (MPLabX) and a compiler freely available for those running Windows, Mac or Linux.


In order to help me get my head around what's connected where, I drew up a picture that shows the PIC functions in red, and the board connections in blue. It's not complete in that the ICSP connections aren't marked. (I also removed the "R" designator from each of the ports so that the text would fit!)


Interesting things to note include:
  • There's wiring between the TX module and PIC so that the TX can provide a clock between 1MHz and 10MHz to the PIC. By default this isn't used, but can clock the PIC at 10MHz instead of 8MHz if you needed the extra bit of speed.
  • The interrupt line from the TX module is directly hooked to the interrupt input on the PIC. This makes it slightly simpler to handle transmission.
  • The SPI port on the PIC isn't wired up to the SPI port on the TX module (only the clock is wired). This means I can't use the PIC's SPI port to configure the TX. I have to bitbang instead. No great shakes.
  • Sadly, the PIC's hardware async serial port is occupied, so serial debug has to be bitbang as well. 
  • The sensor input (SNSR) is on a pin that can handle analog input (AN7). There's nothing stopping the use of the ADC, although there's no seperate onboard voltage reference - the ADC references to the power supply. There's also a 10K resistor pulling the input low. You could add a reference if you wanted to.
  • There's at least four unused pins (A4, B5, C2, C7) easily accessible for other uses. Potentially, you could have nine extra pins for whatever purpose you had. You'd have to cut a couple of traces and not mind potentially disabling ICSP.

Knowing all this about the hardware, the first thing I did was to write a "Hello World" program which just flashes the LED. At least this way I know if things work right! The LED is on RC6, so the code looks something like:

#include <htc.h>
// Default frequency
#define _XTAL_FREQ      4000000L

// Where our LED is
#define     LED     RC6     // LED

// Config bits
__CONFIG(FOSC_INTRCIO & WDTE_OFF & PWRTE_ON & MCLRE_ON  & CP_OFF & CPD_OFF &
         BOREN_OFF & IESO_OFF & FCMEN_OFF );

// Code to do something
void main(void)
{
    TRISC=0xBF;     // Enable LED output

    while (1)
    {
        LED=1;      // LED on
       __delay_ms(100);
       LED=0;      // LED off
       __delay_ms(100);
    }

}


Then, I realised I'm going to need to know the pinout for the ICSP connector on the board if I want to get the code onto the PIC. I'm using a PICKit 2 for this, so I've reproduced the pinout of the dev board and the pinout of a suitable cable to go between the dev board and the PICKit2.

For a suitable pinout, something like this should work:
  Dev Board     PICKit 2 or 3  
1
2
2
5
3
4
4
1
5
3

The advantage of this is that you can test, debug(ish) and reflash the device all over the same cable. If you do it this way, remember that the board is designed to be run from ~3V. When I initially started the PICKit2 software, it was set to 5v.

If you compile up the helloworld example, you'll find that the LED on the dev board will flash on and off! Just what we expected. The next step is to send out the configuration for the radio. I wrote four functions for this - one that bitbashes the data out, and three that put the radio in the state I want it in.

void SendCTRL(uint16_t tosend) {
    uint8_t cnt=16;
    nSEL=0; // select the chip
    SCK=0;
    while(cnt--)
    {
        if (tosend & 0x8000) { SDI=1; } else {SDI=0;}
        SCK=1;
        __delay_us(1);
        SCK=0;
        tosend<<=1;
    }
    nSEL=1;
}

void InitRadio(void)
{
    SendCTRL(0xCC00);       // read "status" - or rather pretend to
    SendCTRL(0x88F0);       // config band/capacitance/bandwith
    SendCTRL(0xC857);       // data rate = 3918bits/sec
    SendCTRL(0xD240);       // PLL Bandwidth set
    SendCTRL(0xA634);       // Freq set
    SendCTRL(0xC220);       // Low battery & bit sync
    SendCTRL(0xC001);       // TX off

}

// Start the RF output
void StartTX(void)
{
    SendCTRL(0xC039);        // turn on osc, synth,PA
}

// Stop the RF output
void StopTX(void)
{
    SendCTRL(0xC001);       // power down TX
    SendCTRL(0xC400);       // go to sleep
}

Using InitRadio() to set up the radio, I can then call StartTX to enable the transmit stages. Calling StopTX then shuts down the transmitter. Testing the code is relatively simple if you have a radio receiver that you can tune to the correct frequency within the 433MHz band. Basically, I tuned the radio and ran the code. When StartTX is called, I can hear the start of the transmission. When StopTX is called, the transmission ceases! If you're wondering where the values for SendCTRL came from, they were taken from the sniffing I did in the previous post. Sadly, actually transmitting useful data over the link was slightly harder, but I'll go into that in the next post - part 4.

4 comments:

  1. Very interesting work Graham. How can I learn more about what you did in terms of repurposing the PIC16F689 based board?

    ReplyDelete
    Replies
    1. To be honest, I need to finish writing things up - sadly this took a bit of a back burner with other things happening in my life recently.

      Delete
  2. I know how that happens! According to Google (which as we know is all knowing!), you are common thread of any progress made in making CurrrentCost stuff more usable, so I'm very interested to see what these Dev boards can do. I've got 6... and one of them is looking at a door state. Not the most exciting use... but helpful.

    I'd like to get them to count an occurrence, like the've done with the Gasmart monitor (have one of those too!), as I'd like a cheap water meter monitor, and was thinking of using the others to retro fit on my old wired alarm to monitor rooms (ideally with temp and humidity along with PIR detection). But all that would need assistance for someone with your brain capacity rather than mine.

    I'm not bad a fudging perl into grabbing the XML messages from the Envir and sending to my own hosted EmonCMS pi based Energy monitor. Certainly not at your level with hacking and programming firmwares. Big respect....

    Would appreciate any progress updates when you have some.

    Cheers
    Mike

    ReplyDelete
    Replies
    1. Hopefully you've seen the latest part that's up on the blog which shows that transmission is indeed possible. The biggest issue I've come across so far is that the EnviR display can only really display electricity usage. While it can receive water/gas/oil data, this is in the form of an impulse count which shows as a "dAtA" channel. It all comes out in the XML though, but with a slightly different format - you can see a snippet in this post. Fudging perl and hacking XML isn't my strong point at all - I can't do a lot more than get the data into an RRD database!

      Delete