RUG/Pennsylvania/State College/Electronics/Gen3/Firmware
Contents
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:
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)
- Extruder
- OneWire.h - from http://www.pjrc.com/teensy/td_libs_OneWire.html (unmodified)
- OneWire.cpp - from http://www.pjrc.com/teensy/td_libs_OneWire.html (unmodified)
- configuration.h
- temperature.h
- extruder_class.pde
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