Archive for September, 2010

Butterfly Logger Firmware 0.29

Sunday, September 19th, 2010

I’ve finally managed to get another release of the Butterfly Logger firmware done. I was supposed to have released a lot of this a couple of years ago but it got lost in the ether somewhere.

Without any further ado the source code is here, with the changes from the previous version are listed below.

Changes summary:
- Added  'j' and 'J' commands to read SHT75 Humidity and Temp.
- Fixed the SHT75 clock waveform (now it looks  symetrical )
- Added ENABLE_SHT_CALCS option to print/store real world values for SHT75
- Tuned vref for more accurate results. (Battery voltage and dependant SHT75 calculations)
- Added Kionix accelerometer logging
- Fixed vref ( done by matthias.weisser )
- Make file uses no-inline-small-functions ( done by matthias.weisser )
- Direction ADCs are now refered to as Auxilliary ADCs

More information about the data logger project can be found at the project website.

Any questions can be asked in the project forums, here.

Using thermocouples with the Reprap Mendel

Monday, September 6th, 2010

Using thermocouples with the Reprap Mendel is pretty straight forward, although I did overcome a couple of issues in getting it working.

A known issue with the MAX6675 Arduino/Reprap code

The MAX6675 chip can take up to 220ms to take a reading from the thermocouple and the reading begins automatically after the previous read. If another read is attempted before the current reading has been completed then the chip returns the previous value and restartsthe internal analog to digital the conversion. This means that if you read from the chip every 150ms or so you will always get the same first reading returned again and again.

The arduino library code needs a 220ms delay between multiple reads to allow for the MAX6675 chip to take another reading. In the current state the library simply reads the same value repeatedly. Luckily it is a known issue documented on the project’s site and is not hard to fix.

The taking of a single reading rather than taking a number of readings and averaging will contribute to a high noise level in the thermocouple readings when using this software.

Discovering the problem

When testing the PCB with the library code everything works fine. The arduino returns a reading every second and everything looks good.

When using the Reprap firmware with the thermocouple code it always returned the first value read from the chip (usually 24°C or so). This lead to things getting pretty hot as the extruder would turn the heater to full duty cycle while recording no change in temperature.

I first looked at the SPI lines on the scope to see if there was excessive noise or some other issue. I also compared this side by side with the ‘working’ arduino system. The scope traces are shown below. The reference channels (R1 and R2) are the reprap firmware and the bottom traces (1 and 2) are the arduino. I noticed nothing wrong with the traces, they both looked very good.

Reprap code compared to aduino library code communicating to the MAX6675.

It was here however that I noticed that the arduino code calls another read to the chip immediately after the preceding read. After a bit more investigation I noticed that the library software calls the temperature reading function 5 times consecutively and always returns 5 identical results. A quick read of the data sheet confirmed the typical conversion time to be 170ms with a maximum of 220ms. The arduino library starts a conversion just 20μs after finishing reading the last. Reading the data sheet further also confirmed the action of restarting a conversion every time the chip is read.

I monitored the lines on a scope and found that the Reprap software was indeed reading the chip every 136ms. To fix this I simply changed SLOW_CLOCK in configuration.h to 8089 from 5000. Based on the current delay giving 136ms, this gives 220ms delay between calls to the thermocouple chip. After making this change to the firmware the thermocouple now works perfectly.

Time between calls to the MAX6675 thermocouple chip using the standard firmware on my reprap.

Fixing the problem

A more robust fix to the reprap extruder firmware is shown below, but I have not tested this code yet. This simply exits the temperature reading method if enough time has not elapsed between calls to the function. The advantage of this is that the main loop can run as fast as it needs to without impacting on the operation of the thermocouple sensors.

#ifdef MAX6675_THERMOCOUPLE
#define MAX6675_CONVERSION_TIME 220 // number of milliseconds between valid temperature readings

  int value = 0;
  byte error_tc;
  
  static unsigned long last_read_time=0; // number of milliseconds since power on at last MAX6675 read 
  unsigned long time_since_last_read=0;  // number of milliseconds since last read of MAX6675 

  /* check the chip is ready to produce a new sample */
  time_since_last_read=millis()-last_read_time;

  /* only read from the chip if a conversion has been completed */
  if(time_since_last_read > MAX6675_CONVERSION_TIME){
    
    digitalWrite(TC_0, 0); // Enable device
  
    /* Cycle the clock for dummy bit 15 */
    digitalWrite(SCK,1);
    digitalWrite(SCK,0);
  
    /* Read bits 14-3 from MAX6675 for the Temp
     	 Loop for each bit reading the value 
     */
    for (int i=11; i>=0; i--)
    {
      digitalWrite(SCK,1);  // Set Clock to HIGH
      value += digitalRead(SO) << i;  // Read data and add it to our variable
      digitalWrite(SCK,0);  // Set Clock to LOW
    }
  
    /* Read the TC Input inp to check for TC Errors */
    digitalWrite(SCK,1); // Set Clock to HIGH
    error_tc = digitalRead(SO); // Read data
    digitalWrite(SCK,0);  // Set Clock to LOW
  
    digitalWrite(TC_0, 1); //Disable Device
  
    last_read_time = millis(); //remember the read time for next time
  
    if(error_tc)
      currentTemperature = 2000;
    else
      currentTemperature = value>>2;
  }
#endif

}

The arduino library can be improved by simply inserting the following at line 55 of the file MAX6675.cpp just before the end of the for loop.

if (i>1) delay(220); // Wait 220ms for next sample to be ready

This will force a 220ms delay when reading the thermocouple multiple times via the read_temp(int samples) function. Alternatively you could use the millis() function to track the last time it was read and automatically delay the read by the appropriate amount.