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

From RepRap
Revision as of 19:35, 15 November 2011 by Joshj (talk | contribs) (Moving Monotronics info to its own page.)
Jump to: navigation, search


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

OneWireA-DFirmware (Source?):


// 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



// 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:

Past Attempts

Previously I modified our extruder firmware (Emf_Bestextruder4_07) to attempt to add brnd's temperature overflow bugfix from File:FirmwareforOneWireAD heatbed brnrd (documented here). As far as I can tell, this should fix the temperature overflow bug. However, when tested this code seemed not to help. Patched file here: File:Extruder class jpj12 2011-04-07 temp fix.pde.

Experimental Firmware

I've created a version of the reprap-mendel-20100308 extruder firmware using my beautified code modifications from below (Future Firmware), available here: File:Joshj mendel-20100308

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

Note that I've had problems using arduino 0021 or 0022 to compile any version of the reprap firmware. arduino-0018 works properly.

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've created an experimental version using mendel firmware v1.8 (from reprap-mendel-20110207). It's available here: File:Joshj reprap-mendel-20110207

The files changed are:

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

Motherboard code


Settings I changed:

#define X_STEPS_PER_MM   20.094
#define Y_STEPS_PER_MM   20.094
#define Z_STEPS_PER_MM   1610.6
#define INVERT_Y_DIR 1
#define E0_STEPS_PER_MM		3.5


  • After "#define TEMP_JAYCAR_NTC_125DEG_10K_THERMISTOR 8", I added:
 #define TEMP_SENSOR_DS2760_THERMOCOUPLE 9		//joshj_2011-05-04	Techzone Thermocouple board

Extruder code


  • 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							
	#define TEMP_PIN 3	// Dummy value, or it won't compile.
	#define BED_TEMP_PIN 6  // Dummy value, or it won't compile.
				//joshj_2011-05-04 end


  • 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] = {
		   {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


  • 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.write(ReadNet,0);	// Read DS2760 address;	// First byte is family code, should be 0x30
	  if(tmpRead != 0x30)
		return 2000;			// Couldn't find DS2760
	  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);	// We use the internal temperature sensor to calculate the
					// cold junction compensation for the thermocouple.
	  if(bitRead(tmpRead,7))	// Negative reading
		tmpCJ=0;				// Limit to 0 degrees C
	  } else {
	  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);	// 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=tCuV << 8;			// Shift left 8 bits;	// Current Register LSB (thermocouple voltage)
	  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;

	  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