Make Your Move

Welcome to Make Your Move written by engineers at Solutions Cubed, LLC. Here we highlight projects we’re working on and discuss interesting technology in the news.Our company creates and sells electronic modules for machine and robotic systems. We also design custom electronic systemsfor a variety of markets.

Please feel free to comment, we’d love to hear from you.

Thermistor and Thermocouple Temperature Logger Part 2



This week in the epic adventure I like to call Thermistor and Thermocouple Temperature Logger Part 2, I took a look at the thermistor portion of my circuit.

[Read more…]

Undocumented Microchip Errata Strike Again

Two years ago, I found an issue with the open drain performance of one of the I/O lines of a PIC24FJ32GB002 microcontroller.  I got it confirmed from Microchip, but they never actually put out an errata on that behavior.  This time, I have found an even larger problem, that I am sure will rise to the level of an official errata.

I was trying to use a PIC24FJ64GC010 microcontroller in a design for a client.  The design has a capacitive sensing keypad that has worked well in the past with a slightly different Microchip microcontroller.  I moved to the PIC24FJ64GC010 because it had some other features that were necessary for the design.  Unfortunately, migrating to the new micro would prove to be problematical.  The capacitive keypad was implemented as shown in the schematic below.  In order to get the best performance, each button was implemented on its own.  In addition, the CTMU output current was routed through the internal op-amp as a voltage follower so that the noise immunity of the keypad would be greater.  Little did I know that dragons lurked in this approach.



Problems arose when I started shaking out the PCB.  For the life of me I could not get some I/O lines to output a current pulse.  The scope capture below shows the problem.  The yellow trace shows the output of the op-amp.  Every time the current from the I/O goes up, the current on the op-amp should ramp up.  The current is turned off and then a different I/O is selected.  Every time a button is sampled, the micro would toggle an I/O as shown with the green trace of the scope capture.  As can be seen from the scope capture, only 8 current ramps are shown.  However, there are 12 toggles on showing that the micro was trying to output current with the CTMU.



At this point, I put on my troubleshooting cap and went to work, because when problem like this arise it is almost always the engineers fault.  I individually addressed the I/Os shown in the schematic in digital mode – I could read inputs and set outputs as desired on ALL I/O lines.  I could also read analog inputs on all of the I/O lines (which due to the new A/D architecture is a feat in itself and will be detailed in an upcoming blog).  I could individually turn on and off the internal pull up resistors.  However, I could not make 4 of the I/O lines output CTMU pulses.  I even lifted individual I/O pins off of the PCB to ensure that the problem was not somehow related to the PCB layout.

I spent some time trying to cajole the Microchip application engineers that there was a problem and could they help me.  After fending off their initial dismissive replies (ie – “try using our sample code”, “it works here”, “have you used our demo board”, “you are overdriving the outputs, they should not clip”, etc), after 2 weeks, I was finally able to convince them to look at the problem for real.  I had to send them my hardware. and from there it was easy for them to confirm the problem.  Another engineer here was able to initially figure out the pattern that allowed the diagnosis, which is fairly odd:

“The CTMU will NOT output on any A/D that is even and less than 15”.  For example, RB4(AN4) will not output CTMU pulses while RB1(AN1) will.  Unfortunately for me, I had randomly selected four of the offending analog I/O lines.  This was a setback to the schedule and my stress level.  However, at least I know I am not crazy and I did everything I could to get the part to work.  In order to get the design to work, I needed to reroute the board and leave off these bad I/Os.

Unfortunately, I do not know if this is a family-wide problem, or a problem with any of the new advanced analog micros, or just related to the PIC24FJ64GC010.  It will be interesting to see what the errata says.  Microchip put out a new errata sheet on 4-20-14 (about 3 weeks after they confirmed the problem), but this issue is not listed.

Thermistor and Thermocouple Temperature Logger


(Image: scope capture of three T type thermocouples being read with SPI and the MAX31855 ICs)

We’ve been developing a barbecue controller as part of an R&D project.  My portion of the project is interfacing the temperature sensors to the overall system.  I’ve decided to include both thermistors and thermocouple sensors, as well as battery backup and data logging functions.  In the end the project won’t need all of that but  I wanted to come up with something “stand-alone” I could develop.

Thus far I’ve designed the schematic and first revision circuit board.  I’ve been able to test the temperature sensors, but not much else.  I did want to share the MAX31855 interface, which I found pretty cool and a definite time saver.  The Maxim Integrated Circuits’ MAX31855 (datasheet) is a cold-junction compensated thermocouple interface.  It provides a 14-bit signed digital value that is temperature in 0.25 degree C increments with +/-2 degree C accuracy.  You buy a chip specific to the thermocouple you’re using.  In our case I placed 4 of these ICs on the board and selected “T” type thermocouples.  The device uses an SPI interface, although it only outputs data.  You can see a partial schematic below (click to enlarge).



For the microcontroller interface I used the PIC16F1789, a Microchip product.  This part has 12-bit analog to digital converters and operates between 2.5V-5.5V, which works well with the battery powered system I’ve envisioned,

Configuring the SPI interface is pretty straightforward, and here is the code I used to do this.

/* Configure_SPIPort:
   Configures registers used to send and receive using the SPI hardware       */
void Configure_SPIPort(void)
    SSPSTATbits.SMP = 0;  // Input data sampled at middle of data output time
    SSPSTATbits.CKE = 0;   // Transmit occurs on transition from Idle to active clock state

    SSPCONbits.CKP = 0; //  Idle state for clock is a low level
    SSPCONbits.SSPM = 2; //SPI Master mode, clock = FOSC/64
    SSPCONbits.SSPEN = 1; // Enables serial port and configures SCK, SDO, SDI and SS as the source of the serial port pins

    SSPCON2 = 0;
    SSPCON3 = 0;

I’m running the SPI at 500KHz, which is a little fast for some SPI ICs, but the MAX31855 is spec’ed at 5MHz max speed.  The actual communication with a MAX31855 is shown in the code below.  The code is repeated for each thermocouple (with different variables).…

/* Read_Thermocouples:
 Reads temperature signals from MAX31855 using the SPI interface.  
void Read_Thermocouples(void)
    _CS_TEMP1 = 0;  // select the first MAX31855
    SSPBUF = 0xAA;          // doesn't matter what we write but H'AA' easy to see on scope
    while(SSPSTATbits.BF == 0); // wait for 8 bits to clock in
    MyTemp.B[1] = SSPBUF; // save data
    SSPBUF = 0xF0; // doesn't matter what we write but H'F0' easy to see on scope differs / from H'AA'
    while(SSPSTATbits.BF == 0); // wait for 8 bits to clock in
    MyTemp.B[0] = SSPBUF; // save data
    NV.Ints.Thermocouple1 = MyTemp.W[0]; // use union to combine bytes in 16 bit value, stick in reg
    _CS_TEMP1 = 1;   // de-select the MAX31855

    INDICATOR.Bits.THERMO1 = 0; // clear my fault flag
    if (NV.Ints.Thermocouple1 & 0x1 == 1) // check to see if an fault flag was set by MAX31855
        INDICATOR.Bits.THERMO1 = 1; // if so, then set flag in my structure
    NV.Ints.Thermocouple1 = NV.Ints.Thermocouple1>>2; // shift temperature data two to the right
    NV.Ints.Thermocouple1 = NV.Ints.Thermocouple1 & 0x3fff; // make sure upper 2 bits are clear
    if ((NV.Ints.Thermocouple1 & 0x2000) != 0 ) // check sign bit
        NV.Ints.Thermocouple1 += 0xc000; // if sign bit is set then extend sign to all 16 bits
    if (NV.Ints.Thermocouple1 == 0x1fff) // check to see if thermocouple is attached
        INDICATOR.Bits.THERMO1 = 1; // if not then set flag

The code deserves some decryption.  Here are some descriptions of the variables used above.
_CS_TEMP1: A constant that refers to the chip select pin.
INDICATOR.Bits.THERMO1: A variable structure that maintains fault conditions and other flags in the firmware.
NV.Ints.Thermocouple1: A variable structure of integers that can be stored in EEPROM and accessed via a serial UART, this is where the temperature data is stored.
MyTemp: This variable can be a little confusing in this context. It is not related to temperature.  MyTemp is a variable union that I often use as a temporary register to quickly break apart or assemble other variables.  For example, I can read two bytes from the SPI port and place them in byte sized members of the union and then use an integer sized member of the union to copy the bytes as a single 16-bit value.

union LongUnion
    long LW;
    unsigned long uLW;
    int W[2];
    unsigned int uW[2];
    char B[4];
    unsigned char uB[4];
union LongUnion

In my firmware I select the MAX31855 by asserting the chip select pin and then sending hexadecimal 0xAA and 0xF0.  The data I send doesn’t matter, but the PIC16F1789 needs to have the SSBUF register written to in order to begin clocking data out and reading data in.  The SSPSTATbits.BF variable is defined by Microchip in this part’s header file, and will be set when the SPI receive buffer is full.  After 16 bits of data are read the chip is de-selected.  The image at the head of this blog entry shows a scope capture of this process.

Once I’ve read 16 bits I need to convert the data to a temperature value.  Not all of the bits relate to temperature so I need to adjust the values I read somewhat.  Bit 0 is a fault flag (set if there is a fault) and bit 1 is reserved (read as 0).  Additionally, bit 15 is the sign bit (using two’s compliment format this bit is set if the value is negative).  In the firmware I check the fault flag (bit 0) and then shift the 16-bits I read from the MAX31855 two places to the right.  This leaves the sign flag in the 13th bit location.  I clear the upper two bits of the register which is kind of an old school operation.  In assembly code when you shift data the carry bit can be shifted into a register.  In C I’ve never seen a “1” get shifted in, but I’ve been doing this for so many years I just can’t stop.   I then check the sign bit and if it is set I set the two highest bits of the temperature data to maintain the two’s compliment formatting.

This diagram shows the process more visually.


There are some additional points related to the MAX31855 that deserve mention.

First, if the thermocouple is disconnected the datasheet states that the MAX31855 will respond with a cleared sign bit and all other temperature data bits set (0x1FFF in hexadecimal).  I didn’t see that, but also didn’t delve into why it didn’t happen.

There are an additional 16-bits of data that can be read from the MAX31855.  You would read this data by clocking in 16 more bits before setting the chip select pin.   This additional data includes the 12-bit internal temperature of the IC and more details on the nature of any fault that occurs.

Lastly, the MAX31855 calculates temperature when the chip is not selected for SPI communication.  It also requires a maximum of 100mS to take the measurements.  Therefore, the fastest you can sample a thermocouple using this IC is 10Hz.

Dual Axis Solar Panel Tracker / Controller Part 5


The saga of the dual axis solar panel controller continues.  As an R&D project I couldn’t put a lot of time into this design this week.  Here is what I did get accomplished.

[Read more…]

Dual Axis Solar Panel Tracker / Controller Part 4


I finally received the PCB for this design.  And in general it turned out okay.  There were a couple of shortcoming in my design that will force me to to re-spin the PCB, so it’ll be a while before I can finish everything up.  But having the PCB gives me the ability to debug my firmware and test the overall concept for this solar panel tracker.

[Read more…]

Simple and Low Cost Temperature and Humidity Sensor: Part 2


Above you can see the primary circuitry for the simple temperature and humidity sensor I described last week.  The board shown above is part of a client’s design, so there is quite a bit more circuitry than is required for the sensor I described last week.

[Read more…]

Simple and Low Cost Temperature and Humidity Sensor


Here’s a simple and low cost temperature and humidity sensor.  I’ve been developing a control system for an industrial application for one of our clients.  As part of that system we have a microcontroller located in a box with some other equipment, and thought it would be good to include some environmental monitoring.  Mostly we want to know if the things get too hot, or if they start to get wet due to maintenance people spraying down the outside of the equipment boxes (which are supposed to be water proof).

[Read more…]

Dual Axis Solar Panel Tracker / Controller Part 3


I’ve been working on a solar panel tracker/controller as an R&D project (previous blog entries part 1 and part 2).  I was able to finish the circuit board design a couple of weeks ago.  I want to panelize it with some other projects so I haven’t shipped it off yet.

[Read more…]

Voice Recording and Playback with an Arduino (BM023)

Back in the late ‘90s we created some small robots for a Microchip technical conference.  They rolled around and used a servo with an IR sensor mounted on it to detect objects.  They had a bit of a Wall-e look, long before that look was made cool by the movie.  Whenever they detected an object they would play a random message that we recorded onto an application.  I was thinking of those robots when I came up with the single message record/play breakout module.

[Read more…]

Dual Axis Solar Panel Controller / Tracker Part 2


Last week I discussed my latest project, an accelerometer based dual axis solar tracker (that blog is here).  When starting a project its easy to get lost in the details.  For example, this project has a whole host of possible control functions and interfaces.  I’ve always found it useful to start my work on the schematic and hardware.  So that’s what I did.

Since this is an R&D project I decided to use some components I haven’t used before.  This design will control a 24VDC brushed motor, and a 12VDC brushed motor.  I’m going to use two St Microelectronics PN:  VNH3SP30-E.  They’re rated for 40V and 30A (although there’s no way they can handle 30A without melting off the PCB).  One feature I like about these controllers is that they only need a single PWM channel for proportional control.  Two other digital channels are used to provide direction.  Here’s a section of the schematic that shows the connections between a PIC16F1789 and two of the motor controllers (click the image for a better view).


In the end, this control system will be used to control our dual axis controller that uses a worm gear for horizontal movement, and a linear actuator for vertical movement.  Here’s a photo of the assembly in front of the old college text books we could never bring ourselves to throw away.  Both the worm gear and linear actual came with feedback.  The worm gear was very expensive and has an encoder on the motor.  the linear actuator was pretty cheap and came with a potentiometer that failed in about a month.  That was one catalyst for attempting that has the position feedback on the control board via an accelerometer.


So for this first run at this design I generated a schematic (here’s a PDF), bill-of-materials (and another PDF), and a circuit board layout.

The circuit board ended up being about 2.5” x 3.5”.  Here’s what the top copper layer looks like.  The 6 dots on the upper and lower right-hand side of the board are for mounting automotive style blade fuses.

Finally, I ran though the list of components I selected to see if any were not able to operate over the industrial temperature range of –40C to 85C (or -40F to 185F).

Here is the column from my bill-of-materials.


There are a couple of interesting findings.  First, I have an 8MHz oscillator on the design that has the smallest range of operation (-20C to 70C).  I’m actually going to use the internal oscillator available in the microcontroller, and I don’t see clock timing to be an incredibly important issue in this design.  I added the oscillator part to the schematic as kind of a back-up plan but don’t plan on using it.  So I’ll ignore that problem for now.

The next lowest temp. range part is the PDV-P7002, a photocell I will be using to detect daylight.  For a part like this, whose resistance changes with light, I would guess that it goes “out-of-specification” outside of its operating range.  I doubt it quits working.  I’ll have to research that some more, but since I’m using the photocell as a yes/no type input I can accommodate a wide resistance variance.

That leaves me with some ceramic caps that don’t meet my operating temperature range, and I can certainly select a similar part with an extended temperature range, so I’m probably good there.

I guess there was one other issue.  The small metal buttons I have on this design (E-Switch parts) had no temperature rating.  I thought that was interesting.  These are not the kind of buttons you would use in an outdoor design, but no temperature rating?

And now for a sanity check.  Am I really going to run this design between –40C and 85C.  Nope.  This is R&D, it’ll spend its life in my office.  If this were a consulting contract we would design for this temperature but suggest our clients place test fixtures in the intended environment to collect operating data and/or make use of a temperature chamber for extended temperature testing.

That’s as far as I was able to get this week.  I’ll try to take some time over Christmas break to order the circuit board.  I need to panelize it with some other designs so it doesn’t cost an arm and a leg.  Hopefully I can begin writing code in January.