RUG/Pennsylvania/State College/Electronics/Gen3/Firmware

From RepRap
Revision as of 00:35, 5 May 2011 by Joshj (talk | contribs) (Current Firmware)
Jump to: navigation, search

Mendel Firmware (Techzone Remix)

Current Firmware

These files are identical to the firmware found here: media:OneWireA-DFirmware.zip With the exception of (motherboard) configuration.h, which is modified as follows:

OneWireA-DFirmware (Source?):

#define ENDSTOPS_MAX_ENABLED 0

// This is for Darwin.
#define X_STEPS_PER_MM   10.047
#define Y_STEPS_PER_MM   10.047
#define INVERT_Y_DIR 0
#define Z_STEPS_PER_MM   805.030

// parameters for the Bath U. mendel prototype
#define X_STEPS_PER_MM   13.333333
#define Y_STEPS_PER_MM   13.333333
#define Z_STEPS_PER_MM   944.88

Bestmobocode:

#define ENDSTOPS_MAX_ENABLED 1

// This is for Darwin.
#define X_STEPS_PER_MM   20.094
#define Y_STEPS_PER_MM   20.094
#define INVERT_Y_DIR 1
#define Z_STEPS_PER_MM   1610.6

// parameters for the Bath U. mendel prototype
#define X_STEPS_PER_MM   26.666666
#define Y_STEPS_PER_MM   26.666666
#define Z_STEPS_PER_MM   1889.76

For the most part, this seems to be a modified version of (old) vanilla reprap code, probably Sanguino v1.6 (from reprap-mendel-20100308), available here.

The motherboard firmware looks to be unmodified, except for configuration.h and ThermistorTable.h.

The extruder board firmware has been modified (configuration.h, extruder.h, extruder_class.pde, temperature.h).


There's a page describing the modifications required to use the Techzone thermocouple boards here:

Experimental Firmware

I've created a version of the reprap-mendel-20100308 extruder firmware using my beautified code modifications from below (Future Firmware), available File:Joshj mendel-20100308 extruder.zip. I started with the vanilla reprap-mendel-20100308 code and the modifications described in TechZone_A-D_With_OneWire. I cleaned up the code some (removed extraneous variables, etc) and included brnrd's temperature overflow bugfix.

In addition to the changes mentioned below, I had to make one additional change to extruder_class.pde: In the "extruder::extruder()" function, after the "#ifdef MAX6675_THERMOCOUPLE" block and before the "#else" command, I added:

#elif defined USE_DS2760				//joshj_2011-05-04
// Nothing to do					//joshj_2011-05-04

Future Firmware

The newest (vanilla) mendel firmware has some code tweaks, and most importantly has heated bed support. It may be worth trying to merge the code from TechZone_A-D_With_OneWire into the vanilla firmware. The files that would need to be modified are (at least) configuration.h, temperature.h, and extruder_class.pde

I'm working on an experimental version using mendel firmware v1.8 (from reprap-mendel-20110207), available | here. Unfortunately, this version of the firmware doesn't seem to compile properly if you're not using thermistors. TODO: Work around this.

The files changed are:

  • Motherboard
    • configuration.h - basic tweaks (machine type, step size, etc)

configuration.h

  • Under "// Temperature measurement", I commented the existing "#define USE_THERMISTOR" and added:
#define USE_DS2760
  • After "#define TC_0 17 // CS Pin of MAX6607" and before "#else", I added:
#elif defined USE_DS2760								//joshj_2011-05-04 start
	// I2C pins for the DS2760 temperature circuit
	#define OW 19    // Pin used for the OneWire communications
	#define ReadNet 0x33	// Read Net Address Net command
	#define SkipNet 0xCC	// 'Skip Addressing' Net command
	#define RdReg 0x69		// 'Read Data' (at Address XX) Function command
	#define thermoTypeK							//joshj_2011-05-04 end

temperature.h

  • In the "#ifdef USE_THERMISTOR block", after the first table and before the "#else" command, I added:
    #elif defined USE_DS2760				//joshj_2011-05-04 start
	#ifdef thermoTypeK
		//Table for looking up temperatures based on units of 15.625uV 
		//(the DS2760 voltage measurement value is 15.625uV per  unit) of thermocouple. 
		#define NUMTEMPS 40
		short temptable[NUMTEMPS][2] = {
		   {0,0},
		   {25, 10},
		   {51, 20},
		   {77, 30},
		   {103, 40},
		   {129, 50},
		   {156, 60},
		   {182, 70},
		   {209, 80},
		   {236, 90},
		   {262, 100},
		   {289, 110},
		   {315, 120},
		   {341, 130},
		   {367, 140},
		   {393, 150},
		   {419, 160},
		   {444, 170},
		   {470, 180},
		   {495, 190},
		   {521, 200},
		   {546, 210},
		   {572, 220},
		   {598, 230},
		   {624, 240},
		   {650, 250},
		   {676, 260},
		   {702, 270},
		   {728, 280},
 		   {755, 290},
		   {781, 300},
		   {808, 310},
		   {834, 320},
		   {861, 330},
		   {888, 340},
 		   {915, 350},
		   {942, 360},
		   {968, 370},
		   {995, 380},
		   {1022, 390}
		};
	#endif						//joshj_2011-05-04 end

extruder_class.pde

  • At the top of the file, I added:
#include "OneWire.h"				//joshj_2011-05-04
  • After the other "#include" statements, I added:
#ifdef USE_DS2760					//joshj_2011-05-04 start
	int readDS2760()
	{
	  word tmpCJ;				// compensation temperature, from internal sensor
	  word tCuV;				// thermocouple voltage reading
	  word cjComp;				// compensated voltage reading
	  byte tmpRead;
	  int i;
	  
	  OneWire myWire(OW);
	  
	  myWire.reset();
	  myWire.write(ReadNet,0);	// Read DS2760 address
	  tmpRead=myWire.read();	// First byte is family code, should be 0x30
	  myWire.reset();
	  
	  if(tmpRead != 0x30)
	  {
		return 2000;			// Couldn't find DS2760
	  }	
		 
	  myWire.reset();
	  myWire.write(SkipNet,0);	// Only one slave, so skip addressing
	  myWire.write(RdReg,0);	// Read Data from Address (next line)
	  myWire.write(0x18,0);		// Temperature Register MSB (internal temperature sensor)
	  tmpRead=myWire.read();	// We use the internal temperature sensor to calculate the
					// cold junction compensation for the thermocouple.
	  myWire.reset();
	  
	  if(bitRead(tmpRead,7))	// Negative reading
	  {
		tmpCJ=0;				// Limit to 0 degrees C
	  } else {
		tmpCJ=tmpRead;
	  }	
	  
	  myWire.reset();
	  myWire.write(SkipNet,0);	// Only one slave, so skip addressing
	  myWire.write(RdReg,0);	// Read Data from Address (next line)
	  myWire.write(0x0E,0);		// Current Register MSB (thermocouple voltage)
	  tmpRead=myWire.read();	// Note that the current sensing on the DS2760 actually measures the voltage across the sense resistor
					// We use this to measure the voltage across the (low-resistance) thermocouple to high accuracy.
	  tCuV=tmpRead;
	  tCuV=tCuV << 8;			// Shift left 8 bits
	  tmpRead=myWire.read();	// Current Register LSB (thermocouple voltage)
	  myWire.reset();
	  tCuV=tCuV | tmpRead;		// now we have MSB, LSB
	  tCuV=tCuV >> 3;			// Lowest 3 bits of LSB are not used, so shift right 3
	  if(bitRead(tCuV,12))		// Bit 12 is the sign bit - tCuV is (currently) two's complement
	  {
		 tCuV = tCuV | 0xF000;	// If tCuV is negative, pad the leftmost bits (necessary because we shifted right earlier)
		 tCuV = tCuV ^ 0xFFFF;  // Since we don't care about the sign, flip value to positive.
		 // Should add 1 to tCuV to negate properly.
	  }
	   
	   // Back-convert tempCJ to a voltage value
cjComp=temptable[(int)(tmpCJ/10)][0] + (tmpCJ-temptable[(int)(tmpCJ/10)][1])*(temptable[(int)(tmpCJ/10)+1][0]-temptable[(int)(tmpCJ/10)][0])/10;

		cjComp=cjComp+tCuV;
	  if(cjComp>temptable[NUMTEMPS-1][0])	// If voltage exceeds maximum voltage from table
	  {
		return temptable[NUMTEMPS-1][1];	// Return maximum temperature from table
		/* I question the wisdom of this -- probably better to return 2000, 
			so entering a temperature over 390C doesn't cause the tip to burn out.
			(Unless Repsnapper prevents the user from entering absurdly large temperatures)
		*/
	  }
	  for (i=1; i<NUMTEMPS; i++)		// Check each table entry
	  {
		if (temptable[i][0]>cjComp)		// Until we find one larger than our voltage value
		{
		  return temptable[i-1][1] + (cjComp-temptable[i-1][0])*(temptable[i][1]-temptable[i-1][1])/(temptable[i][0]-temptable[i-1][0]);
		}
	  }
	  return 2000;  //if it fails to get a temperature return 2000 so it will turn off the heat.
	}
#endif								//joshj_2011-05-04 end
  • Inside the function "void PIDcontrol::internalTemperature(short table[][2])", after the "#ifdef MAX6675_THERMOCOUPLE" ... "#endif" block, I added:
#ifdef USE_DS2760				//joshj_2011-05-04 start
  currentTemperature = readDS2760();
  if(currentTemperature == 0)
  {
    currentTemperature = 1999;
  }
#endif						//joshj_2011-05-04 end