Welcome! Log In Create A New Profile


Fitting Teacup in 168

Posted by electronrancher 
Fitting Teacup in 168
January 16, 2012 06:23PM
Hello All,

With all the Arduino talk, I thought this would be a snap and I'm still sure I'm doing something wrong. But try as I might, I cannot get arduino-0022 to fit even a stripped-down Teacup in a Diecimila 168. The smallest I've gotten is 14454 bytes using 3 axes and one heater in bang-bang.

So no extruder control, no hotbed, no endstops, no PID, thermistor only with a 20-entry table. The entire intercom directory was unused and renamed to be invisible to the compiler. Still over the 14336 max. Has anyone gotten a usable system that can fit in a '168? I would sure like a copy of your setup as I am very puzzled.

I suppose I could use Teensy, but I'm not ready to give up unless it's really never going to fit in Diecimila. I need 3 axes, heater with thermistor, and extruder on/off only. I can use software endstops if that's all will fit

Thanks in advance for any advice or working setups you can offer!

Here's the config.h

/* Notice to developers: this file is intentionally included twice. */

/** \file
	\brief Sample Configuration

	\note this sample uses AIO0 for both X_STEP and thermistor, and is intended to be an example only!


	1. Mechanical/Hardware
	2. Acceleration settings
	3. Pinouts
	4. Temperature sensors
	5. Heaters
	6. Communication options
	7. Miscellaneous
	8. Appendix A - PWMable pins and mappings

*                                                                           *
* 1. MECHANICAL/HARDWARE                                                    *
*                                                                           *

	Set your microcontroller type in Makefile! atmega168/atmega328p/atmega644p/atmega1280

	If you want to port this to a new chip, start off with arduino.h and see how you go.
#if ! ( defined (__AVR_ATmega168__) )
	#error TheArduino board uses ATMEGA168. Set your cpu type in Makefile!

/** \def F_CPU
	CPU clock rate
#ifndef	F_CPU
	#define	F_CPU	16000000UL

/** \def HOST
	This is the motherboard, as opposed to the extruder. See extruder/ directory for GEN3 extruder firmware
#define	HOST

	Values reflecting the gearing of your machine.
		All numbers are fixed point integers, so no more than 3 digits to the right of the decimal point, please :-)

/** \def STEPS_PER_M
	steps per meter ( = steps per mm * 1000 )

	calculate these values appropriate for your machine

	for threaded rods, this is
		(steps motor per turn) / (pitch of the thread) * 1000

	for belts, this is
		(steps per motor turn) / (number of gear teeth) / (belt module) * 1000

	half-stepping doubles the number, quarter stepping requires * 4, etc.

	valid range = 20 to 4'0960'000 (0.02 to 40960 steps/mm)
#define	STEPS_PER_M_X					320000
#define	STEPS_PER_M_Y					320000
#define	STEPS_PER_M_Z					320000

/// [blog.arcol.hu] may help with this one
#define	STEPS_PER_M_E					320000

	Values depending on the capabilities of your stepper motors and other mechanics.
		All numbers are integers, no decimals allowed.

		Units are mm/min

/// used for G0 rapid moves and as a cap for all other feedrates

/// used when searching endstops and as default feedrate
#define	SEARCH_FEEDRATE_X			50
#define	SEARCH_FEEDRATE_Y			50
#define	SEARCH_FEEDRATE_Z			50
// no SEARCH_FEEDRATE_E, as E can't be searched

/** \def SLOW_HOMING
	wether to search the home point slowly
		With some endstop configurations, like when probing for the surface of a PCB, you can't deal with overrunning the endstop. In such a case, uncomment this definition.
// #define	SLOW_HOMING

/// this is how many steps to suck back the filament by when we stop. set to zero to disable
#define	E_STARTSTOP_STEPS			20

	Soft axis limits, in mm.
	Define them to your machine's size relative to what your host considers to be the origin.

#define	X_MIN			0.0
#define	X_MAX			100.0

#define	Y_MIN			0.0
#define	Y_MAX			100.0

#define	Z_MIN			0.0
#define	Z_MAX			100.0

/**	\def E_ABSOLUTE
	Some G-Code creators produce relative length commands for the extruder, others absolute ones. G-Code using absolute lengths can be recognized when there are G92 E0 commands from time to time. If you have G92 E0 in your G-Code, define this flag.
// #define E_ABSOLUTE

*                                                                           *
* 2. ACCELERATION                                                           *
*                                                                           *
* IMPORTANT: choose only one! These algorithms choose when to step, trying  *
*            to use more than one will have undefined and probably          *
*            disastrous results!                                            *
*                                                                           *

	acceleration, reprap style.
		Each movement starts at the speed of the previous command and accelerates or decelerates linearly to reach target speed at the end of the movement.

	acceleration and deceleration ramping.
		Each movement starts at (almost) no speed, linearly accelerates to target speed and decelerates just in time to smoothly stop at the target. alternative to ACCELERATION_REPRAP

	how fast to accelerate when using ACCELERATION_RAMPING.
		given in mm/s^2, decimal allowed, useful range 1. to 10'000. Start with 10. for milling (high precision) or 1000. for printing
#define ACCELERATION 1000.

	temporal step algorithm
		This algorithm causes the timer to fire when any axis needs to step, instead of synchronising to the axis with the most steps ala bresenham.

		This algorithm is not a type of acceleration, and I haven't worked out how to integrate acceleration with it.
		However it does control step timing, so acceleration algorithms seemed appropriate

		The Bresenham algorithm is great for drawing lines, but not so good for steppers - In the case where X steps 3 times to Y's two, Y experiences massive jitter as it steps in sync with X every 2 out of 3 X steps. This is a worst-case, but the problem exists for most non-45/90 degree moves. At higher speeds, the jitter /will/ cause position loss and unnecessary vibration.
		This algorithm instead calculates when a step occurs on any axis, and sets the timer to that value.

		// TODO: figure out how to add acceleration to this algorithm

*                                                                           *
* 3. PINOUTS                                                                *
*                                                                           *

	Machine Pin Definitions
	- make sure to avoid duplicate usage of a pin
	- comment out pins not in use, as this drops the corresponding code and makes operations faster

#include	"arduino.h"

	internal pullup resistors
		the ATmega has internal pullup resistors on it's input pins which are counterproductive with the commonly used eletronic endstops, so they should be switched off. For other endstops, like mechanical ones, you may want to uncomment this.

	user defined pins
	adjust to suit your electronics,
	or adjust your electronics to suit this

#define	X_STEP_PIN						DIO0
#define	X_DIR_PIN							DIO1
//#define	X_MIN_PIN							AIO2
//#define	X_MAX_PIN							xxxx
//#define	X_ENABLE_PIN					xxxx
//#define	X_INVERT_DIR
//#define	X_INVERT_MIN
//#define	X_INVERT_MAX

#define	Y_STEP_PIN						DIO2
#define	Y_DIR_PIN							DIO3
//#define	Y_MIN_PIN							AIO5
//#define	Y_MAX_PIN							xxxx
//#define	Y_ENABLE_PIN					xxxx
//#define	Y_INVERT_DIR
//#define	Y_INVERT_MIN
//#define	Y_INVERT_MAX

#define	Z_STEP_PIN						DIO4
#define	Z_DIR_PIN							DIO5
//#define	Z_MIN_PIN							DIO4
//#define	Z_MAX_PIN							xxxx
//#define	Z_ENABLE_PIN					xxxx
//#define	Z_INVERT_DIR
//#define	Z_INVERT_MIN
//#define	Z_INVERT_MAX

//#define	E_STEP_PIN						DIO6
//#define	E_DIR_PIN							DIO7
//#define E_ENABLE_PIN					xxxx
//#define	E_INVERT_DIR

//#define	PS_ON_PIN							DIO9
//#define	STEPPER_ENABLE_PIN		xxxx

*                                                                           *
* 4. TEMPERATURE SENSORS                                                    *
*                                                                           *

	TEMP_HYSTERESIS: actual temperature must be target +/- hysteresis before target temperature can be achieved.
	Unit is degree Celsius.
#define	TEMP_HYSTERESIS				5
	TEMP_RESIDENCY_TIME: actual temperature must be close to target for this long before target is achieved

	temperature is "achieved" for purposes of M109 and friends when actual temperature is within [hysteresis] of target for [residency] seconds

/// which temperature sensors are you using? List every type of sensor you use here once, to enable the appropriate code. Intercom is the gen3-style separate extruder board.
// #define	TEMP_MAX6675
// #define	TEMP_AD595
// #define	TEMP_PT100
// #define	TEMP_INTERCOM
// #define	TEMP_NONE

*                                                                           *
* Define your temperature sensors here                                      *
*                                                                           *
* for GEN3 set temp_type to TT_INTERCOM and temp_pin to 0                   *
*                                                                           *
* Types are same as TEMP_ list above- TT_MAX6675, TT_THERMISTOR, TT_AD595,  *
*   TT_PT100, TT_INTERCOM, TT_NONE. See list in temp.c.                     *
*                                                                           *

	#define DEFINE_TEMP_SENSOR(...)

//                 name       type          pin		additional
// "noheater" is a special name for a sensor which doesn't have a heater.
// Use "M105 P#" to read it, where # is a zero-based index into this list.

*                                                                           *
* 5. HEATERS                                                                *
*                                                                           *

	check if heater responds to changes in target temperature, disable and spit errors if not
	largely untested, please comment in forum if this works, or doesn't work for you!

*                                                                           *
* Define your heaters here                                                  *
*                                                                           *
* If your heater isn't on a PWM-able pin, set heater_pwm to zero and we'll  *
*   use bang-bang output. Note that PID will still be used                  *
*                                                                           *
* See Appendix 8 at the end of this file for PWMable pin mappings           *
*                                                                           *
* If a heater isn't attached to a temperature sensor above, it can still be *
*   controlled by host but otherwise is ignored by firmware                 *
*                                                                           *
* To attach a heater to a temp sensor above, simply use exactly the same    *
*   name - copy+paste is your friend                                        *
*                                                                           *
* Some common names are 'extruder', 'bed', 'fan', 'motor'                   *
*                                                                           *
* A milling spindle can also be defined as a heater. Attach it to a         *
* temperature sensor of TT_NONE, then you can control the spindle's rpm     *
* via temperature commands. M104 S1..255 for spindle on, M104 S0 for off.   *
*                                                                           *

	#define DEFINE_HEATER(...)

//               name      port   pin    pwm
DEFINE_HEATER(extruder,	PB3)
// DEFINE_HEATER(fan,			PORTB, PINB4, OCR0cool smiley
// DEFINE_HEATER(motor,		PORTD, PIND6, OCR2cool smiley
//DEFINE_HEATER(extruder_motor, PB4)

/// and now because the c preprocessor isn't as smart as it could be,
/// uncomment the ones you've listed above and comment the rest.
/// NOTE: these are used to enable various capability-specific chunks of code, you do NOT need to create new entries unless you are adding new capabilities elsewhere in the code!
/// so if you list a bed above, uncomment HEATER_BED, but if you list a chamber you do NOT need to create HEATED_CHAMBER
/// I have searched high and low for a way to make the preprocessor do this for us, but so far I have not found a way.

//#define HEATER_BED HEATER_bed
// #define HEATER_FAN HEATER_fan

*                                                                           *
* 6. COMMUNICATION OPTIONS                                                  *
*                                                                           *

	RepRap Host changes it's communications protocol from time to time and intentionally avoids backwards compatibility. Set this to the date the source code of your Host was fetched from RepRap's repository, which is likely also the build date.
	See the discussion on the reprap-dev mailing list from 11 Oct. 2010.

	Undefine it for best human readability, set it to an old date for compatibility with hosts before August 2010

	Baud rate for the connection to the host. Usually 115200, other common values are 19200, 38400 or 57600.
#define	BAUD	115200

/** \def XONXOFF
	Xon/Xoff flow control.
		Redundant when using RepRap Host for sending GCode, but mandatory when sending GCode files with a plain terminal emulator, like GtkTerm (Linux), CoolTerm (Mac) or HyperTerminal (Windows).
		Can also be set in Makefile
// #define	XONXOFF

*                                                                           *
* 7. MISCELLANEOUS OPTIONS                                                  *
*                                                                           *

/** \def DEBUG
		enables /heaps/ of extra output, and some extra M-codes.
		WARNING: this WILL break most host-side talkers that expect particular responses from firmware such as reprap host and replicatorG
		use with serial terminal or other suitable talker only.
// #define	DEBUG

/** \def BANG_BANG
drops PID loop from heater control, reduces code size significantly (1300 bytes!)
may allow DEBUG on '168
 #define	BANG_BANG
/** \def BANG_BANG_ON
PWM value for 'on'
 #define	BANG_BANG_ON	200
/** \def BANG_BANG_OFF
PWM value for 'off'
#define	BANG_BANG_OFF	45

	move buffer size, in number of moves
		note that each move takes a fair chunk of ram (69 bytes as of this writing) so don't make the buffer too big - a bigger serial readbuffer may help more than increasing this unless your gcodes are more than 70 characters long on average.
		however, a larger movebuffer will probably help with lots of short consecutive moves, as each move takes a bunch of math (hence time) to set up so a longer buffer allows more of the math to be done during preceding longer moves

/** \def DC_EXTRUDER
	DC extruder
		If you have a DC motor extruder, configure it as a "heater" above and define this value as the index or name. You probably also want to comment out E_STEP_PIN and E_DIR_PIN in the Pinouts section above.
// #define	DC_EXTRUDER HEATER_motor
// #define	DC_EXTRUDER_PWM	180

	Teacup implements a watchdog, which has to be reset every 250ms or it will reboot the controller. As rebooting (and letting the GCode sending application trying to continue the build with a then different Home point) is probably even worse than just hanging, and there is no better restore code in place, this is disabled for now.
// #define USE_WATCHDOG

	analog subsystem stuff
	REFERENCE - which analog reference to use. see analog.h for choices

	this option makes the step interrupt interruptible (nested).
	this should help immensely with dropped serial characters, but may also make debugging infuriating due to the complexities arising from nested interrupts
	\note disable this option if you're using a '168 or for some reason your ram usage is above 90%. This option hugely increases likelihood of stack smashing.

	temperature history count. This is how many temperature readings to keep in order to calculate derivative in PID loop
	higher values make PID derivative term more stable at the expense of reaction time
#define	TH_COUNT					8

/// this is the scaling of internally stored PID values. 1024L is a good value
#define	PID_SCALE						1024L

	number of steps to run into the endstops intentionally
		As Endstops trigger false alarm sometimes, Teacup debounces them by counting a number of consecutive positives. Valid range is 1...255. Use 4 or less for reliable endstops, 8 or even more for flaky ones.

*                                                                           *
* 8. APPENDIX A - PWMABLE PINS AND MAPPINGS                                 *
*                                                                           *
*                                                                           *
* list of PWM-able pins and corresponding timers                            *
* timer1 is used for step timing so don't use OC1A/OC1B                     *
* they are omitted from this listing for that reason                        *
*                                                                           *
* For the atmega168/328, timer/pin mappings are as follows                  *
*                                                                           *
* OCR0A - PD6  - DIO6                                                       *
* OCR0B - PD5  - DIO5                                                       *
* OCR2A - PB3  - DIO11                                                      *
* OCR2B - PD3  - DIO3                                                       *
*                                                                           *
* For the atmega644, timer/pin mappings are as follows                      *
*                                                                           *
* OCR0A - PB3  - DIO3                                                       *
* OCR0B - PB4  - DIO4                                                       *
* OCR2A - PD7  - DIO15                                                      *
* OCR2B - PD6  - DIO14                                                      *
*                                                                           *
* For the atmega1280, timer/pin mappings are as follows                     *
*                                                                           *
* OCR0A  - PB7 - DIO13                                                      *
* OCR0B  - PG5 - DIO4                                                       *
* OCR2A  - PB4 - DIO10                                                      *
* OCR2B  - PH6 - DIO9                                                       *
* OCR3AL - PE3 - DIO5                                                       *
* OCR3BL - PE4 - DIO2                                                       *
* OCR3CL - PE5 - DIO3                                                       *
* OCR4AL - PH3 - DIO6                                                       *
* OCR4BL - PH4 - DIO7                                                       *
* OCR4CL - PH5 - DIO8                                                       *
* OCR5AL - PL3 - DIO46                                                      *
* OCR5BL - PL4 - DIO45                                                      *
* OCR5CL - PL5 - DIO44                                                      *
*                                                                           *

Re: Fitting Teacup in 168
January 17, 2012 04:18AM
you could update your firmware stk500 with a tiny one. there is an opti bootloader that takes 500 bytes. also as for pins, you could also look up breadboard arduino, and use internal clock and gain 2 more i/o pins to use. downside is it now runs at 8mhz.

also use arduino ide 18. arduino 22 is more complex, and has code overhead for interrupts for serial tx, and ram buffering overhead as well. something you need to be watchful of in 1k of ram is the tx buffers used as well. I think the teacup has features that take care of buffering issues anyway. so use ide18.

another thing that is possible for homing if you only home once during build is wire a 1k between arduino, and dir pin, then have the limit switch when pressed change the dir of motor, that way when you hit an end stop, your motor changes dir, and then it goes back and forth 1mm but generally stays homed, and frees up an additional pin on each axis. z will still need a real home as it needs to be +/- .05mm each time.
but one thing i have started to play with is combining all dir pins to one i/o pin. the steppers just need the step pin to be separate anyway. just change dir to whatever it should be before stepping stepper driver...

that should free up enough pins and changing the boot loader should free up more bytes for programming.

of course you could always spend 7-12$ and upgrade to a 328 chip. it has 32k of eprom and 2k of ram. i have a firmware mod of sprinter running with pid on a 328. dealing with an 1280 mega is less of a headache because it has a lot more pins, but difficult for bread boarding.

also the firmware i use also has a software 16bit wide pwm for relays and slower devices. also allows me to use any pin for pwm rather than the 6 pins on 328, or 3 pins on 168 atmega.

Edited 2 time(s). Last edit at 01/17/2012 04:23AM by jamesdanielv.
Re: Fitting Teacup in 168
January 18, 2012 08:43PM
Thank you, James.

I will try Arduino 0018 this weekend. I agree that changing to a different bootloader, or deleting the loader entirely will probably fit it. But the use of the term arduino seemed that it must have included all the baggage of the libs and bootloader.

By the way, great tip on the "bouncy" limit switch - that's a nice hack I will keep it in mind. Let me give this a shot on arduino 0018 and I'll see where that gets me.
Re: Fitting Teacup in 168
January 18, 2012 08:48PM
14680 bytes on arduino 0018. Ok time for some ripping and tearing.
Re: Fitting Teacup in 168
January 20, 2012 08:43AM
Ah. When I still developed on such an '168 I always had something like 12'000 bytes. Without extruder, though.

You can comment out X_MIN, X_MAX, etc. to shrink more. That's just a protection against faulty G-code.

If this still isn't sufficient, you can rewrite decfloat_to_int() in gcode_parse.c. It's used for few values only and is too complicated for this usage.

Next step would be to reduce update_current_position() in dda.c to report the endpoint only.

More if you've done that.

Generation 7 Electronics Teacup Firmware RepRap DIY
Re: Fitting Teacup in 168
January 21, 2012 02:52AM
it would be far easier to just load the opti boot loader. it takes around 500bytes, can be done with bitbang method here:

Googled it and found it here:


i was in a bind once where a seller did not know he was selling 168s, so i purchased some 328 chips seperately as it would take 2 weeks to send the 10boards back. The other seller assumed that arduino compatible drop in replacement ment i would program them with bootloader. after i hit my head a few times, i found the method above.
Re: Fitting Teacup in 168
January 21, 2012 07:53AM
Well, if one has a programmer to upload a new bootloader, one can work without any bootloader just as fine. Uploading firmware via programmer is just as simple as doing it with via serial and one can even connect both devices at the same time.

One important tidbit here is, if your firmware is bigger than total flash size minus bootloader size, one has to re-adjust the fuses to ignore the bootloader.

Generation 7 Electronics Teacup Firmware RepRap DIY
Re: Fitting Teacup in 168
January 26, 2012 07:36PM
Thanks guys!

I do hope to keep it in arduino platform with standard bootloader, as I think it will be more easily accepted by the general population. So there is benefit in reducing the size.

13902 with just X,Y,Z, and no software stops. Great advice, thank you Traumflug!
13926 with X,Y,Z,E and no soft stops. I will need to look into why those softstops take so much room. But this is a great start, and I am convinced that it will work.
Sorry, only registered users may post in this forum.

Click here to login