Thread subject: Homeroasters - Home Roasting Coffee Community :: TC4 - Coding and tech issues

Posted by JimG on 04/12/2011 11:55 AM
#1

Welcome to a new thread for discussing the nitty-gritty coding and technical issues associated with the TC4. My intention in starting this thread is that it be dedicated to techie issues that apply across the entire spectrum of TC4 applications.

First item of business is to announce that Jasen Grice has written a new library that supports Type T thermocouples. I haven't used the new library yet, but I can see that it is compatible with the TypeK library that has been in use for several months now. It looks like the two libraries would be interchangeable as far as existing applications are concerned.

Here is the TRY-branch where you can find the new library:
https://tc4-shiel...asen-TypeT

Reports of any testing done using this new library will be greatly appreciated!

Jim

Posted by greencardigan on 04/13/2011 9:21 PM
#2

Hi Jim,

I'm still trying to get my head around the filtering side of things in aBourbon so i can replicate this in my picaxe code.

Is this how it goes?

1. Heavy filtering on ambient temps. Does this occur before or after cold junction compensation?
2. Light filtering of temps for display and logging
3. Heavy filtering of temps for ror calcs
4. Heavy filtering of ROR values for display and logging


Currently I'm not filtering the ambient or display temps and my temp traces seem smooth enough.

I've had a few late nights trying to get the (1-beta)*xi + beta*y-1 filter method working on the picaxe! I have to work with temps x 100 to preserve the temp resolution (integer math only) and that means I have to work around the 16bit math limitation to do 31bit math in the filter calcs.

I ended up using a filtering level ranging from 0 to 255 rather than your 0-99 as it is easier to divide by 256.

Also, are you eventually intending to make aBourbon compatible with both pBourbon and Artisan?

Brad

Posted by JimG on 04/13/2011 10:13 PM
#3

Quote

greencardigan wrote:
1. Heavy filtering on ambient temps. Does this occur before or after cold junction compensation?
2. Light filtering of temps for display and logging
3. Heavy filtering of temps for ror calcs
4. Heavy filtering of ROR values for display and logging

All filtering is done at the end, i.e., after CJ compensation, TC linearization, etc.

The ambient temps are heavily filtered on the idea that the ambient sensor is located in a stable environment (on the PCB, presumably inside an enclosure) so variations are most likely noise. So we kill the quick jumps and keep the longer term trends.

Heavily filtered streams of BT and ET values are used for computing the derivatives (RoR). These heavily filtered BT and ET streams are used only for the calculation of derivatives.

Optionally, the streams of computed RoR values can also be post-filtered. This works surprisingly well. I did some testing while Bill was writing aGesha and found that a combination of pre- and post-filtering for RoR gives better results with less lag time than pre-filtering BT and ET only.

More lightly filtered streams of BT and ET are computed for logging and displaying the data.

A lot of flexibility is built into the code for filtering. Different combinations of sensors and roasters produce varying amounts of signal noise. A lot of air flow will usually create more noise, for instance.

Quote

greencardigan wrote:
Also, are you eventually intending to make aBourbon compatible with both pBourbon and Artisan?

The current release candidate of aBourbon is up to date with your changes to pBourbon.

I chose to write a standalone sketch to support Artisan instead of trying to build more functionality into aBourbon. I've tested aArtisan on the desk, but not on my roaster. It works very well on the desktop, FWIW:
https://tc4-shiel...hes/RB-100

Jim

Posted by greencardigan on 04/16/2011 1:18 AM
#4

Hi Jim,
I'm having an issue with this section of code in pBourbon REL-200. And the same issue for the equivalent part in the keyPressed function.

Code

void mouseClicked() {
  if( !started ) { 
    started = true;
    delay( START_DELAY );
    println("\nSynchronising aBourbon Time");
    comport.write( "RESET\n" );
  }
  else {
    makeJPG = true;
  }
}


If my TC4 logger is already running, I get the following displayed.

Quote

comport clear()'ed.
buffering...
134,20.75,20.50,-0.45,20.00,-0.07,0
135,20.87,20.62,-0.42,20.12,-0.06,0

Synchronising aBourbon Time
# RESET
# SEND COLUMN HEADERS AND SETUP DETAILS
1,20.87,20.62,-0.39,20.12,-0.05,0
2,20.87,20.62,-0.36,20.12,-0.04,0
3,21.00,20.75,-0.30,20.25,-0.00,0


This results in the graph beign drawn wrong at the start. I get lines from time 134 back to 1.

I suggest that the started = true line be moved to after the comport.write line??

What do you think??

Posted by JimG on 04/16/2011 8:00 AM
#5

Yeah, I ran into the same problem when I fired up my new Uno board. The issue is that there is a lag between when the RESET command is issued and when it is heard at the remote.

This is what I did to fix things here:
Code

  if( !started ) { // waiting for user to begin logging
    delay( START_DELAY ); // make sure the Arduino sketch has had time to get started
    println("\nSynchronising aBourbon Time");
    comport.write( "RESET\n" );  // issue command to the TC4 to synchronize clocks
    delay( 200 );
    comport.write( "RESET\n" ); // Uno requires a second reset -- why?
    delay( 1200 ); // make sure reset has occurred before we start logging data
    started = true;
  }


Here is a diff that shows the revisions (I've also since removed the extra line of code in KeyPressed):
http://code.googl...mp;old=514

The good news is that I don't think this is a problem on Duemilanove and older Arduino's. The Uno has so many other problems that I can't recommend it at this point.


Jim

Posted by bvwelch on 04/16/2011 8:27 AM
#6

About this timesync stuff -- perhaps the Arduino side should respond to a RESET by sending a "RESET" response? Then the PC should wait for the RESET to come back, before setting its 'started' variable?

BTW, I'm a bit confused between RESET and STRT messages. Perhaps they could be consolidated?

Edited by bvwelch on 04/16/2011 8:29 AM

Posted by JimG on 04/16/2011 8:29 AM
#7

I like that idea. I'll give it a try today.

Thanks!

Jim

Posted by bvwelch on 04/16/2011 8:33 AM
#8

Hi Jim, I revised my suggestion above, at just about the same time as you replied. I'm not sure if START will work, may need a new RESET message coming back in reply ?

Posted by JimG on 04/16/2011 10:08 AM
#9

I saw that.

The difference between reset and start is that start indicates that the beans have been loaded.

Thanks.

Jim

Posted by JimG on 04/16/2011 11:36 AM
#10

I've got something that's working well here with both the Uno (problem child) and the Duemilanove. Had the added benefit of getting rid of the forced delay to give the remote (Arduino, PICAXE) a chance to spin up.

Most of the time, 5 resets are required for the Duemilanove. This is because opening the serial port always resets the board.

On the Uno, most of the time 1 reset is required, sometimes 2. But it does not get reset when the serial port is opened.

Anxious to see how it behaves on your PICAXE, Brad.

The basics:
Code

// ------------------------------- reset the Arduino, etc.
void resetRemote() {
//    delay( START_DELAY ); // make sure the remote has had time to get started
    println("\nSynchronising with remote:");
    int i = 0;
    while( resetAck == 0 && i < 10 ) {
      comport.write( "RESET\n" );  // issue command to the TC4 to synchronize clocks
      delay( 500 );
      i++;
    }
    print( resetAck ); println( " reset(s) required." );
    if( resetAck != 0 )
      started = true;
}

// ------------------------------- save a frame when mouse is clicked
void mouseClicked() {
  if( !started ) {  // waiting for user to begin logging
    resetRemote();
  }
  else {
    makeJPG = true;  // queue a request to save a frame
  }
}

...... similar code for beginning of keyPressed()

// -------------------------------------------------------------
void serialEvent(Serial comport) { // this is executed each time a line of data is received from the TC4

    // grab a line of ascii text from the logger
    String msg = comport.readStringUntil('\n');

    // exit right away if blank line
    if (msg == null) return; // *****************
    msg = trim(msg);
    if (msg.length() == 0) return; // ****************

    // otherwise, check first to see if it is a comment --------------------------------------------
    if (msg.charAt(0) == '#') { // this line is a comment
      logfile.println(msg); // write it to the log no matter what
      println(msg); // write it to the terminal no matter what     
      String[] rec = split(msg, ",");  // comma separated input list
      if( rec[0].equals( "# Reset" ) ) { // acknowledge, and count, RESET's echoed back from remote
        ++resetAck;    // count them for possible debugging use
      }
        else if( started ) { // skip these roast markers if logging hasn't been started by the user
        if (rec[0].equals("# STRT")) {
          ba_x = T0[0][idx-1];
          ba_y = MAX_TEMP - T0[1][idx-1];
        } else if (rec[0].equals("# FC")) {
... snipped


Changes committed to the repository here:
https://tc4-shiel...c/pBourbon

Jim

Posted by greencardigan on 04/16/2011 7:02 PM
#11

Jim,
I gave this a quick test just now and it seems to be working fine with my PICAXE. I get the message '1 reset required'.

Posted by JimG on 04/17/2011 12:08 AM
#12

Quote

greencardigan wrote:
Jim,
I gave this a quick test just now and it seems to be working fine with my PICAXE. I get the message '1 reset required'.

Sounds good!

BTW, I finally determined that the problem with my Uno was a bad via between the top and bottom layers along the RESET signal. Now, that's bad luck :@

Jim

Posted by greencardigan on 04/17/2011 7:24 AM
#13

I just solved one of the issues I was having too. My picaxe was locking up at random times while I was testing it with pBourbon and Artisan.

After a few grumpy days and way too many hours looking for bugs in the code I realised the batteries powering the picaxe were very low. :(

Posted by bvwelch on 04/17/2011 8:39 AM
#14

Quote

JimG wrote:
The Uno has so many other problems that I can't recommend it at this point.
Jim


Now that the reset signal problem on the PCB is repaired, how do you find the Uno's operation?

Posted by JimG on 04/17/2011 11:02 AM
#15

Now that I've soldered the jumper wire to fix the bad PCB trace, the Uno is working well. Not really any different from the Duemilanove, though, AFAIK.

I've tested the Uno on XP, Ubuntu, and Mac OS X. Still having some issues with Mac, but it may be related to the USB hub I'm using. That is a documented issue with Uno and Mac. I need to do more testing to see if I can get it going on the Mac.

So as of now, Uno = goodo.

Jim

Posted by bvwelch on 04/19/2011 7:13 PM
#16

Here's a small but fun project for someone -- implement Dan's 'percentage timer' idea for OT1 and/or OT2. Instead of using PWM, use the system time to implement 0 to 100 percent duty cycle with a 10 second period. Put the 'knob' (pot) on ANLG1 or 2.

EDIT: Nevermind, Jim's already done this. Duh.

Edited by bvwelch on 04/19/2011 11:34 PM

Posted by mhoy on 04/20/2011 1:30 AM
#17

Is there a way to detect that a thermocouple is either unplugged or not used?

Thanks,
Mark

Posted by JimG on 04/20/2011 7:33 AM
#18

I've done this (prototype level only) for another project by forcing a small current through the thermocouple, on the order of 0.5 uA.

If there is an intact thermocouple connected, the differential voltage created by this small current passing through the TC loop is too small to affect the readings. The common mode voltage is around 500mV, but the ADC seems to be able to reject it OK.

If the TC is broken, or not present, a differential voltage of around 500mV (I use a signal diode) shows up across the input terminals of the ADC channel. This is a low enough value that it does no damage, but high enough to put the input signal out of normal range. So the code just has to check for input values that are waaaay high.

Jim

Posted by mhoy on 04/21/2011 10:34 PM
#19

Finally made something with my TC4 and LCD board. This is a controller for my Bradley Original Smoker. There is power in/out with one thermocouple input. The buttons (which I have to figure out how to program) will allow on the fly setup of the SSR controlled heater element.

lh4.googleusercontent.com/_0-aEomHvbkE/TbDycAizcOI/AAAAAAAAAm0/pDCFuhmF99g/s800/P1020830.JPG

Mark

Edited by mhoy on 04/21/2011 10:35 PM

Posted by mhoy on 04/23/2011 11:57 AM
#20

Took another look at the SVN repository and voila, cButton/cButton.[ch]. Somehow I had missed it when I last looked... Oddly the buttons seem to 'bounce' but it works well enough for now. On to trying some smoked salmon. Don't know which grind selection for it. :-) An on/off controller has overshoot but looks like it will work well enough for smoking where the time frame is hours.

Sous Vide would also now be possible, wonder if the wife would notice the rice cooker if it went missing. :)

Mark