Browse Source

Merged from Upstream Master

pull/1/head
xifle 12 years ago
parent
commit
9eeb711c96
  1. 149
      Marlin/Configuration.h
  2. 28
      Marlin/Configuration_adv.h
  3. 20
      Marlin/Makefile
  4. 4
      Marlin/Marlin.h
  5. 16
      Marlin/Marlin.pde
  6. 665
      Marlin/Marlin_main.cpp
  7. 339
      Marlin/Servo.cpp
  8. 132
      Marlin/Servo.h
  9. 393
      Marlin/pins.h
  10. 22
      Marlin/planner.cpp
  11. 4
      Marlin/planner.h
  12. 24
      Marlin/stepper.cpp
  13. 96
      Marlin/temperature.cpp
  14. 245
      Marlin/ultralcd.cpp
  15. 41
      Marlin/ultralcd.h
  16. 1263
      Marlin/ultralcd_implementation_hitachi_HD44780.h
  17. 450
      README.md

149
Marlin/Configuration.h

@ -2,7 +2,7 @@
#define CONFIGURATION_H
// This configurtion file contains the basic settings.
// Advanced settings can be found in Configuration_adv.h
// Advanced settings can be found in Configuration_adv.h
// BASIC SETTINGS: select your board type, temperature sensor type, axis scaling, and endstop configuration
//User specified version info of this build to display in [Pronterface, etc] terminal window during startup.
@ -51,6 +51,9 @@
#define MOTHERBOARD 7
#endif
// This defines the number of extruders
#define EXTRUDERS 1
//// The following define selects which power supply you have. Please choose the one that matches your setup
// 1 = ATX
// 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC)
@ -78,7 +81,7 @@
// 9 is 100k GE Sensing AL03006-58.2K-97-G1 (4.7k pullup)
// 10 is 100k RS thermistor 198-961 (4.7k pullup)
//
// 1k ohm pullup tables - This is not normal, you would have to have changed out your 4.7k for 1k
// 1k ohm pullup tables - This is not normal, you would have to have changed out your 4.7k for 1k
// (but gives greater accuracy and more stable PID)
// 51 is 100k thermistor - EPCOS (1k pullup)
// 52 is 200k thermistor - ATC Semitec 204GT-2 (1k pullup)
@ -90,12 +93,12 @@
#define TEMP_SENSOR_BED 0
// Actual temperature must be close to target for this long before M109 returns success
#define TEMP_RESIDENCY_TIME 10 // (seconds)
#define TEMP_RESIDENCY_TIME 10 // (seconds)
#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one
#define TEMP_WINDOW 1 // (degC) Window around target to start the recidency timer x degC early.
// The minimal temperature defines the temperature below which the heater will not be enabled It is used
// to check that the wiring to the thermistor is not broken.
// to check that the wiring to the thermistor is not broken.
// Otherwise this would lead to the heater being powered on all the time.
#define HEATER_0_MINTEMP 5
#define HEATER_1_MINTEMP 5
@ -121,7 +124,7 @@
#define BANG_MAX 256 // limits current to nozzle while in bang-bang mode; 256=full current
#define PID_MAX 256 // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 256=full current
#ifdef PIDTEMP
//#define PID_DEBUG // Sends debug data to the serial port.
//#define PID_DEBUG // Sends debug data to the serial port.
//#define PID_OPENLOOP 1 // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX
#define PID_FUNCTIONAL_RANGE 10 // If the temperature difference between the target temperature and the actual temperature
// is more then PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max.
@ -132,15 +135,15 @@
// If you are using a preconfigured hotend then you can use one of the value sets by uncommenting it
// Ultimaker
#define DEFAULT_Kp 22.2
#define DEFAULT_Ki 1.08
#define DEFAULT_Kd 114
#define DEFAULT_Ki 1.08
#define DEFAULT_Kd 114
// Makergear
// #define DEFAULT_Kp 7.0
// #define DEFAULT_Ki 0.1
// #define DEFAULT_Kd 12
// #define DEFAULT_Ki 0.1
// #define DEFAULT_Kd 12
// Mendel Parts V9 on 12V
// Mendel Parts V9 on 12V
// #define DEFAULT_Kp 63.0
// #define DEFAULT_Ki 2.25
// #define DEFAULT_Kd 440
@ -149,11 +152,11 @@
// Bed Temperature Control
// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis
//
// uncomment this to enable PID on the bed. It uses the same ferquency PWM as the extruder.
// uncomment this to enable PID on the bed. It uses the same ferquency PWM as the extruder.
// If your PID_dT above is the default, and correct for your hardware/configuration, that means 7.689Hz,
// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating.
// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater.
// If your configuration is significantly different than this and you don't understand the issues involved, you proabaly
// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater.
// If your configuration is significantly different than this and you don't understand the issues involved, you proabaly
// shouldn't use bed PID until someone else verifies your hardware works.
// If this is enabled, find your own PID constants below.
//#define PIDTEMPBED
@ -223,9 +226,9 @@
#endif
// The pullups are needed if you directly connect a mechanical endswitch between the signal and ground pins.
const bool X_ENDSTOPS_INVERTING = true; // set to true to invert the logic of the endstops.
const bool Y_ENDSTOPS_INVERTING = true; // set to true to invert the logic of the endstops.
const bool Z_ENDSTOPS_INVERTING = true; // set to true to invert the logic of the endstops.
const bool X_ENDSTOPS_INVERTING = true; // set to true to invert the logic of the endstops.
const bool Y_ENDSTOPS_INVERTING = true; // set to true to invert the logic of the endstops.
const bool Z_ENDSTOPS_INVERTING = true; // set to true to invert the logic of the endstops.
//#define DISABLE_MAX_ENDSTOPS
// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1
@ -280,13 +283,13 @@ const bool Z_ENDSTOPS_INVERTING = true; // set to true to invert the logic of th
#define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E
#define HOMING_FEEDRATE {50*60, 50*60, 4*60, 0} // set the homing speeds (mm/min)
// default settings
// default settings
#define DEFAULT_AXIS_STEPS_PER_UNIT {78.7402,78.7402,200.0*8/3,760*1.1} // default steps per unit for ultimaker
#define DEFAULT_MAX_FEEDRATE {500, 500, 5, 25} // (mm/sec)
#define DEFAULT_MAX_ACCELERATION {9000,9000,100,10000} // X, Y, Z, E maximum start speed for accelerated moves. E default values are good for skeinforge 40+, for older versions raise them a lot.
#define DEFAULT_ACCELERATION 3000 // X, Y, Z and E max acceleration in mm/s^2 for printing moves
#define DEFAULT_ACCELERATION 3000 // X, Y, Z and E max acceleration in mm/s^2 for printing moves
#define DEFAULT_RETRACT_ACCELERATION 3000 // X, Y, Z and E max acceleration in mm/s^2 for r retracts
// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing).
@ -307,7 +310,7 @@ const bool Z_ENDSTOPS_INVERTING = true; // set to true to invert the logic of th
// EEPROM
// the microcontroller can store settings in the EEPROM, e.g. max velocity...
// M500 - stores paramters in EEPROM
// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily).
// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily).
// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to.
//define this to enable eeprom support
//#define EEPROM_SETTINGS
@ -315,9 +318,18 @@ const bool Z_ENDSTOPS_INVERTING = true; // set to true to invert the logic of th
// please keep turned on if you can.
//#define EEPROM_CHITCHAT
// Preheat Constants
#define PLA_PREHEAT_HOTEND_TEMP 180
#define PLA_PREHEAT_HPB_TEMP 70
#define PLA_PREHEAT_FAN_SPEED 255 // Insert Value between 0 and 255
#define ABS_PREHEAT_HOTEND_TEMP 240
#define ABS_PREHEAT_HPB_TEMP 100
#define ABS_PREHEAT_FAN_SPEED 255 // Insert Value between 0 and 255
//LCD and SD support
//#define ULTRA_LCD //general lcd support, also 16x2
//#define DOGLCD // Support for SPI LCD 128x64 (Controller ST7565R graphic Display Family)
//#define DOGLCD // Support for SPI LCD 128x64 (Controller ST7565R graphic Display Family)
//#define SDSUPPORT // Enable SD Card Support in Hardware Console
//#define SDSLOW // Use slower SD transfer mode (not normally needed - uncomment if you're getting volume init error)
@ -353,43 +365,74 @@ const bool Z_ENDSTOPS_INVERTING = true; // set to true to invert the logic of th
#if defined(ULTIMAKERCONTROLLER) || defined(REPRAP_DISCOUNT_SMART_CONTROLLER) || defined(G3D_PANEL)
#define ULTIPANEL
#define NEWPANEL
#endif
#endif
#if defined(REPRAPWORLD_KEYPAD)
#define NEWPANEL
#define ULTIPANEL
#endif
// Preheat Constants
#define PLA_PREHEAT_HOTEND_TEMP 180
#define PLA_PREHEAT_HPB_TEMP 70
#define PLA_PREHEAT_FAN_SPEED 255 // Insert Value between 0 and 255
//I2C PANELS
#define ABS_PREHEAT_HOTEND_TEMP 240
#define ABS_PREHEAT_HPB_TEMP 100
#define ABS_PREHEAT_FAN_SPEED 255 // Insert Value between 0 and 255
//#define LCD_I2C_SAINSMART_YWROBOT
#ifdef LCD_I2C_SAINSMART_YWROBOT
// This uses the LiquidCrystal_I2C library ( https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home )
// Make sure it is placed in the Arduino libraries directory.
#define LCD_I2C_TYPE_PCF8575
#define LCD_I2C_ADDRESS 0x27 // I2C Address of the port expander
#define NEWPANEL
#define ULTIPANEL
#endif
// PANELOLU2 LCD with status LEDs, separate encoder and click inputs
//#define LCD_I2C_PANELOLU2
#ifdef LCD_I2C_PANELOLU2
// This uses the LiquidTWI2 library v1.2.3 or later ( https://github.com/lincomatic/LiquidTWI2 )
// Make sure the LiquidTWI2 directory is placed in the Arduino or Sketchbook libraries subdirectory.
// (v1.2.3 no longer requires you to define PANELOLU in the LiquidTWI2.h library header file)
// Note: The PANELOLU2 encoder click input can either be directly connected to a pin
// (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1).
#define LCD_I2C_TYPE_MCP23017
#define LCD_I2C_ADDRESS 0x20 // I2C Address of the port expander
#define LCD_USE_I2C_BUZZER //comment out to disable buzzer on LCD
#define NEWPANEL
#define ULTIPANEL
#endif
// Panucatt VIKI LCD with status LEDs, integrated click & L/R/U/P buttons, separate encoder inputs
//#define LCD_I2C_VIKI
#ifdef LCD_I2C_VIKI
// This uses the LiquidTWI2 library v1.2.3 or later ( https://github.com/lincomatic/LiquidTWI2 )
// Make sure the LiquidTWI2 directory is placed in the Arduino or Sketchbook libraries subdirectory.
// Note: The pause/stop/resume LCD button pin should be connected to the Arduino
// BTN_ENC pin (or set BTN_ENC to -1 if not used)
#define LCD_I2C_TYPE_MCP23017
#define LCD_I2C_ADDRESS 0x20 // I2C Address of the port expander
#define LCD_USE_I2C_BUZZER //comment out to disable buzzer on LCD (requires LiquidTWI2 v1.2.3 or later)
#define NEWPANEL
#define ULTIPANEL
#endif
#ifdef ULTIPANEL
// #define NEWPANEL //enable this if you have a click-encoder panel
#define SDSUPPORT
#define ULTRA_LCD
#ifdef DOGLCD // Change number of lines to match the DOG graphic display
#define LCD_WIDTH 20
#define LCD_HEIGHT 5
#else
#define LCD_WIDTH 20
#define LCD_HEIGHT 4
#endif
#else //no panel but just lcd
#ifdef DOGLCD // Change number of lines to match the DOG graphic display
#define LCD_WIDTH 20
#define LCD_HEIGHT 5
#else
#define LCD_WIDTH 20
#define LCD_HEIGHT 4
#endif
#else //no panel but just lcd
#ifdef ULTRA_LCD
#ifdef DOGLCD // Change number of lines to match the 128x64 graphics display
#define LCD_WIDTH 20
#define LCD_HEIGHT 5
#else
#define LCD_WIDTH 16
#define LCD_HEIGHT 2
#endif
#ifdef DOGLCD // Change number of lines to match the 128x64 graphics display
#define LCD_WIDTH 20
#define LCD_HEIGHT 5
#else
#define LCD_WIDTH 16
#define LCD_HEIGHT 2
#endif
#endif
#endif
@ -403,6 +446,26 @@ const bool Z_ENDSTOPS_INVERTING = true; // set to true to invert the logic of th
// SF send wrong arc g-codes when using Arc Point as fillet procedure
//#define SF_ARC_FIX
// Support for the BariCUDA Paste Extruder.
//#define BARICUDA
/*********************************************************************\
*
* R/C SERVO support
*
* Sponsored by TrinityLabs, Reworked by codexmas
*
**********************************************************************/
// Number of servos
//
// If you select a configuration below, this will receive a default value and does not need to be set manually
// set it manually if you have more servos than extruders and wish to manually control some
// leaving it undefined or defining as 0 will disable the servo subsystem
// If unsure, leave commented / disabled
//
// #define NUM_SERVOS 3
#include "Configuration_adv.h"
#include "thermistortables.h"

28
Marlin/Configuration_adv.h

@ -63,21 +63,31 @@
//This is for controlling a fan to cool down the stepper drivers
//it will turn on when any driver is enabled
//and turn off after the set amount of seconds from last driver being disabled again
//#define CONTROLLERFAN_PIN 23 //Pin used for the fan to cool controller, comment out to disable this function
#define CONTROLLERFAN_SEC 60 //How many seconds, after all motors were disabled, the fan should run
#define CONTROLLERFAN_PIN -1 //Pin used for the fan to cool controller (-1 to disable)
#define CONTROLLERFAN_SECS 60 //How many seconds, after all motors were disabled, the fan should run
#define CONTROLLERFAN_SPEED 255 // == full speed
// When first starting the main fan, run it at full speed for the
// given number of milliseconds. This gets the fan spinning reliably
// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu)
//#define FAN_KICKSTART_TIME 100
// Extruder cooling fans
// Configure fan pin outputs to automatically turn on/off when the associated
// extruder temperature is above/below EXTRUDER_AUTO_FAN_TEMPERATURE.
// Multiple extruders can be assigned to the same pin in which case
// the fan will turn on when any selected extruder is above the threshold.
#define EXTRUDER_0_AUTO_FAN_PIN -1
#define EXTRUDER_1_AUTO_FAN_PIN -1
#define EXTRUDER_2_AUTO_FAN_PIN -1
#define EXTRUDER_AUTO_FAN_TEMPERATURE 50
#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed
//===========================================================================
//=============================Mechanical Settings===========================
//===========================================================================
// This defines the number of extruders
#define EXTRUDERS 1
#define ENDSTOPS_ONLY_FOR_HOMING // If defined the endstops will only be used for homing
@ -210,9 +220,9 @@
// However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled.
//#define WATCHDOG_RESET_MANUAL
#endif
// Enable the option to stop SD printing when hitting and endstops, needs to be enabled from the LCD menu when this option is enabled.
//#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED
// Enable the option to stop SD printing when hitting and endstops, needs to be enabled from the LCD menu when this option is enabled.
//#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED
// extruder advance constant (s2/mm3)
//
@ -276,7 +286,7 @@ const unsigned int dropsegments=5; //everything with less than this number of st
#else
#define BLOCK_BUFFER_SIZE 16 // maximize block buffer
#endif
//The ASCII buffer for recieving from the serial:
#define MAX_CMD_SIZE 96

20
Marlin/Makefile

@ -1,12 +1,12 @@
# Sprinter Arduino Project Makefile
#
#
# Makefile Based on:
# Arduino 0011 Makefile
# Arduino adaptation by mellis, eighthave, oli.keller
# Marlin adaption by Daid
#
# This has been tested with Arduino 0022.
#
#
# This makefile allows you to build sketches from the command line
# without the Arduino environment (or Java).
#
@ -21,7 +21,7 @@
# (e.g. UPLOAD_PORT = /dev/tty.USB0). If the exact name of this file
# changes, you can use * as a wildcard (e.g. UPLOAD_PORT = /dev/tty.usb*).
#
# 3. Set the line containing "MCU" to match your board's processor.
# 3. Set the line containing "MCU" to match your board's processor.
# Older one's are atmega8 based, newer ones like Arduino Mini, Bluetooth
# or Diecimila have the atmega168. If you're using a LilyPad Arduino,
# change F_CPU to 8000000. If you are using Gen7 electronics, you
@ -44,7 +44,7 @@ ARDUINO_INSTALL_DIR ?= ../../arduino-0022
ARDUINO_VERSION ?= 22
# You can optionally set a path to the avr-gcc tools. Requires a trailing slash. (ex: /usr/local/avr-gcc/bin)
AVR_TOOLS_PATH ?=
AVR_TOOLS_PATH ?=
#Programmer configuration
UPLOAD_RATE ?= 115200
@ -213,7 +213,7 @@ CXXSRC = WMath.cpp WString.cpp Print.cpp Marlin_main.cpp \
SdFile.cpp SdVolume.cpp motion_control.cpp planner.cpp \
stepper.cpp temperature.cpp cardreader.cpp ConfigurationStore.cpp \
watchdog.cpp
CXXSRC += LiquidCrystal.cpp ultralcd.cpp SPI.cpp
CXXSRC += LiquidCrystal.cpp ultralcd.cpp SPI.cpp Servo.cpp
#Check for Arduino 1.0.0 or higher and use the correct sourcefiles for that version
ifeq ($(shell [ $(ARDUINO_VERSION) -ge 100 ] && echo true), true)
@ -317,19 +317,19 @@ endif
# Default target.
all: sizeafter
build: $(BUILD_DIR) elf hex
build: $(BUILD_DIR) elf hex
# Creates the object directory
$(BUILD_DIR):
$(BUILD_DIR):
$P mkdir -p $(BUILD_DIR)
elf: $(BUILD_DIR)/$(TARGET).elf
hex: $(BUILD_DIR)/$(TARGET).hex
eep: $(BUILD_DIR)/$(TARGET).eep
lss: $(BUILD_DIR)/$(TARGET).lss
lss: $(BUILD_DIR)/$(TARGET).lss
sym: $(BUILD_DIR)/$(TARGET).sym
# Program the device.
# Program the device.
# Do not try to reset an arduino if it's not one
upload: $(BUILD_DIR)/$(TARGET).hex
ifeq (${AVRDUDE_PROGRAMMER}, arduino)
@ -356,7 +356,7 @@ COFFCONVERT=$(OBJCOPY) --debugging \
--change-section-address .data-0x800000 \
--change-section-address .bss-0x800000 \
--change-section-address .noinit-0x800000 \
--change-section-address .eeprom-0x810000
--change-section-address .eeprom-0x810000
coff: $(BUILD_DIR)/$(TARGET).elf

4
Marlin/Marlin.h

@ -186,6 +186,10 @@ extern float add_homeing[3];
extern float min_pos[3];
extern float max_pos[3];
extern int fanSpeed;
#ifdef BARICUDA
extern int ValvePressure;
extern int EtoPPressure;
#endif
#ifdef FWRETRACT
extern bool autoretract_enabled;

16
Marlin/Marlin.pde

@ -34,11 +34,17 @@
#include "pins.h"
#ifdef ULTRA_LCD
#ifdef DOGLCD
#include <U8glib.h> // library for graphics LCD by Oli Kraus (https://code.google.com/p/u8glib/)
#else
#include <LiquidCrystal.h> // library for character LCD
#endif
#if defined(LCD_I2C_TYPE_PCF8575)
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#elif defined(LCD_I2C_TYPE_MCP23017) || defined(LCD_I2C_TYPE_MCP23008)
#include <Wire.h>
#include <LiquidTWI2.h>
#elif defined(DOGLCD)
#include <U8glib.h> // library for graphics LCD by Oli Kraus (https://code.google.com/p/u8glib/)
#else
#include <LiquidCrystal.h> // library for character LCD
#endif
#endif
#if DIGIPOTSS_PIN > -1

665
Marlin/Marlin_main.cpp

File diff suppressed because it is too large

339
Marlin/Servo.cpp

@ -0,0 +1,339 @@
/*
Servo.cpp - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2
Copyright (c) 2009 Michael Margolis. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
A servo is activated by creating an instance of the Servo class passing the desired pin to the attach() method.
The servos are pulsed in the background using the value most recently written using the write() method
Note that analogWrite of PWM on pins associated with the timer are disabled when the first servo is attached.
Timers are seized as needed in groups of 12 servos - 24 servos use two timers, 48 servos will use four.
The methods are:
Servo - Class for manipulating servo motors connected to Arduino pins.
attach(pin ) - Attaches a servo motor to an i/o pin.
attach(pin, min, max ) - Attaches to a pin setting min and max values in microseconds
default min is 544, max is 2400
write() - Sets the servo angle in degrees. (invalid angle that is valid as pulse in microseconds is treated as microseconds)
writeMicroseconds() - Sets the servo pulse width in microseconds
read() - Gets the last written servo pulse width as an angle between 0 and 180.
readMicroseconds() - Gets the last written servo pulse width in microseconds. (was read_us() in first release)
attached() - Returns true if there is a servo attached.
detach() - Stops an attached servos from pulsing its i/o pin.
*/
#ifdef NUM_SERVOS
#include <avr/interrupt.h>
#include <Arduino.h>
#include "Servo.h"
#define usToTicks(_us) (( clockCyclesPerMicrosecond()* _us) / 8) // converts microseconds to tick (assumes prescale of 8) // 12 Aug 2009
#define ticksToUs(_ticks) (( (unsigned)_ticks * 8)/ clockCyclesPerMicrosecond() ) // converts from ticks back to microseconds
#define TRIM_DURATION 2 // compensation ticks to trim adjust for digitalWrite delays // 12 August 2009
//#define NBR_TIMERS (MAX_SERVOS / SERVOS_PER_TIMER)
static servo_t servos[MAX_SERVOS]; // static array of servo structures
static volatile int8_t Channel[_Nbr_16timers ]; // counter for the servo being pulsed for each timer (or -1 if refresh interval)
uint8_t ServoCount = 0; // the total number of attached servos
// convenience macros
#define SERVO_INDEX_TO_TIMER(_servo_nbr) ((timer16_Sequence_t)(_servo_nbr / SERVOS_PER_TIMER)) // returns the timer controlling this servo
#define SERVO_INDEX_TO_CHANNEL(_servo_nbr) (_servo_nbr % SERVOS_PER_TIMER) // returns the index of the servo on this timer
#define SERVO_INDEX(_timer,_channel) ((_timer*SERVOS_PER_TIMER) + _channel) // macro to access servo index by timer and channel
#define SERVO(_timer,_channel) (servos[SERVO_INDEX(_timer,_channel)]) // macro to access servo class by timer and channel
#define SERVO_MIN() (MIN_PULSE_WIDTH - this->min * 4) // minimum value in uS for this servo
#define SERVO_MAX() (MAX_PULSE_WIDTH - this->max * 4) // maximum value in uS for this servo
/************ static functions common to all instances ***********************/
static inline void handle_interrupts(timer16_Sequence_t timer, volatile uint16_t *TCNTn, volatile uint16_t* OCRnA)
{
if( Channel[timer] < 0 )
*TCNTn = 0; // channel set to -1 indicated that refresh interval completed so reset the timer
else{
if( SERVO_INDEX(timer,Channel[timer]) < ServoCount && SERVO(timer,Channel[timer]).Pin.isActive == true )
digitalWrite( SERVO(timer,Channel[timer]).Pin.nbr,LOW); // pulse this channel low if activated
}
Channel[timer]++; // increment to the next channel
if( SERVO_INDEX(timer,Channel[timer]) < ServoCount && Channel[timer] < SERVOS_PER_TIMER) {
*OCRnA = *TCNTn + SERVO(timer,Channel[timer]).ticks;
if(SERVO(timer,Channel[timer]).Pin.isActive == true) // check if activated
digitalWrite( SERVO(timer,Channel[timer]).Pin.nbr,HIGH); // its an active channel so pulse it high
}
else {
// finished all channels so wait for the refresh period to expire before starting over
if( ((unsigned)*TCNTn) + 4 < usToTicks(REFRESH_INTERVAL) ) // allow a few ticks to ensure the next OCR1A not missed
*OCRnA = (unsigned int)usToTicks(REFRESH_INTERVAL);
else
*OCRnA = *TCNTn + 4; // at least REFRESH_INTERVAL has elapsed
Channel[timer] = -1; // this will get incremented at the end of the refresh period to start again at the first channel
}
}
#ifndef WIRING // Wiring pre-defines signal handlers so don't define any if compiling for the Wiring platform
// Interrupt handlers for Arduino
#if defined(_useTimer1)
SIGNAL (TIMER1_COMPA_vect)
{
handle_interrupts(_timer1, &TCNT1, &OCR1A);
}
#endif
#if defined(_useTimer3)
SIGNAL (TIMER3_COMPA_vect)
{
handle_interrupts(_timer3, &TCNT3, &OCR3A);
}
#endif
#if defined(_useTimer4)
SIGNAL (TIMER4_COMPA_vect)
{
handle_interrupts(_timer4, &TCNT4, &OCR4A);
}
#endif
#if defined(_useTimer5)
SIGNAL (TIMER5_COMPA_vect)
{
handle_interrupts(_timer5, &TCNT5, &OCR5A);
}
#endif
#elif defined WIRING
// Interrupt handlers for Wiring
#if defined(_useTimer1)
void Timer1Service()
{
handle_interrupts(_timer1, &TCNT1, &OCR1A);
}
#endif
#if defined(_useTimer3)
void Timer3Service()
{
handle_interrupts(_timer3, &TCNT3, &OCR3A);
}
#endif
#endif
static void initISR(timer16_Sequence_t timer)
{
#if defined (_useTimer1)
if(timer == _timer1) {
TCCR1A = 0; // normal counting mode
TCCR1B = _BV(CS11); // set prescaler of 8
TCNT1 = 0; // clear the timer count
#if defined(__AVR_ATmega8__)|| defined(__AVR_ATmega128__)
TIFR |= _BV(OCF1A); // clear any pending interrupts;
TIMSK |= _BV(OCIE1A) ; // enable the output compare interrupt
#else
// here if not ATmega8 or ATmega128
TIFR1 |= _BV(OCF1A); // clear any pending interrupts;
TIMSK1 |= _BV(OCIE1A) ; // enable the output compare interrupt
#endif
#if defined(WIRING)
timerAttach(TIMER1OUTCOMPAREA_INT, Timer1Service);
#endif
}
#endif
#if defined (_useTimer3)
if(timer == _timer3) {
TCCR3A = 0; // normal counting mode
TCCR3B = _BV(CS31); // set prescaler of 8
TCNT3 = 0; // clear the timer count
#if defined(__AVR_ATmega128__)
TIFR |= _BV(OCF3A); // clear any pending interrupts;
ETIMSK |= _BV(OCIE3A); // enable the output compare interrupt
#else
TIFR3 = _BV(OCF3A); // clear any pending interrupts;
TIMSK3 = _BV(OCIE3A) ; // enable the output compare interrupt
#endif
#if defined(WIRING)
timerAttach(TIMER3OUTCOMPAREA_INT, Timer3Service); // for Wiring platform only
#endif
}
#endif
#if defined (_useTimer4)
if(timer == _timer4) {
TCCR4A = 0; // normal counting mode
TCCR4B = _BV(CS41); // set prescaler of 8
TCNT4 = 0; // clear the timer count
TIFR4 = _BV(OCF4A); // clear any pending interrupts;
TIMSK4 = _BV(OCIE4A) ; // enable the output compare interrupt
}
#endif
#if defined (_useTimer5)
if(timer == _timer5) {
TCCR5A = 0; // normal counting mode
TCCR5B = _BV(CS51); // set prescaler of 8
TCNT5 = 0; // clear the timer count
TIFR5 = _BV(OCF5A); // clear any pending interrupts;
TIMSK5 = _BV(OCIE5A) ; // enable the output compare interrupt
}
#endif
}
static void finISR(timer16_Sequence_t timer)
{
//disable use of the given timer
#if defined WIRING // Wiring
if(timer == _timer1) {
#if defined(__AVR_ATmega1281__)||defined(__AVR_ATmega2561__)
TIMSK1 &= ~_BV(OCIE1A) ; // disable timer 1 output compare interrupt
#else
TIMSK &= ~_BV(OCIE1A) ; // disable timer 1 output compare interrupt
#endif
timerDetach(TIMER1OUTCOMPAREA_INT);
}
else if(timer == _timer3) {
#if defined(__AVR_ATmega1281__)||defined(__AVR_ATmega2561__)
TIMSK3 &= ~_BV(OCIE3A); // disable the timer3 output compare A interrupt
#else
ETIMSK &= ~_BV(OCIE3A); // disable the timer3 output compare A interrupt
#endif
timerDetach(TIMER3OUTCOMPAREA_INT);
}
#else
//For arduino - in future: call here to a currently undefined function to reset the timer
#endif
}
static boolean isTimerActive(timer16_Sequence_t timer)
{
// returns true if any servo is active on this timer
for(uint8_t channel=0; channel < SERVOS_PER_TIMER; channel++) {
if(SERVO(timer,channel).Pin.isActive == true)
return true;
}
return false;
}
/****************** end of static functions ******************************/
Servo::Servo()
{
if( ServoCount < MAX_SERVOS) {
this->servoIndex = ServoCount++; // assign a servo index to this instance
servos[this->servoIndex].ticks = usToTicks(DEFAULT_PULSE_WIDTH); // store default values - 12 Aug 2009
}
else
this->servoIndex = INVALID_SERVO ; // too many servos
}
uint8_t Servo::attach(int pin)
{
return this->attach(pin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);
}
uint8_t Servo::attach(int pin, int min, int max)
{
if(this->servoIndex < MAX_SERVOS ) {
pinMode( pin, OUTPUT) ; // set servo pin to output
servos[this->servoIndex].Pin.nbr = pin;
// todo min/max check: abs(min - MIN_PULSE_WIDTH) /4 < 128
this->min = (MIN_PULSE_WIDTH - min)/4; //resolution of min/max is 4 uS
this->max = (MAX_PULSE_WIDTH - max)/4;
// initialize the timer if it has not already been initialized
timer16_Sequence_t timer = SERVO_INDEX_TO_TIMER(servoIndex);
if(isTimerActive(timer) == false)
initISR(timer);
servos[this->servoIndex].Pin.isActive = true; // this must be set after the check for isTimerActive
}
return this->servoIndex ;
}
void Servo::detach()
{
servos[this->servoIndex].Pin.isActive = false;
timer16_Sequence_t timer = SERVO_INDEX_TO_TIMER(servoIndex);
if(isTimerActive(timer) == false) {
finISR(timer);
}
}
void Servo::write(int value)
{
if(value < MIN_PULSE_WIDTH)
{ // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds)
if(value < 0) value = 0;
if(value > 180) value = 180;
value = map(value, 0, 180, SERVO_MIN(), SERVO_MAX());
}
this->writeMicroseconds(value);
}
void Servo::writeMicroseconds(int value)
{
// calculate and store the values for the given channel
byte channel = this->servoIndex;
if( (channel < MAX_SERVOS) ) // ensure channel is valid
{
if( value < SERVO_MIN() ) // ensure pulse width is valid
value = SERVO_MIN();
else if( value > SERVO_MAX() )
value = SERVO_MAX();
value = value - TRIM_DURATION;
value = usToTicks(value); // convert to ticks after compensating for interrupt overhead - 12 Aug 2009
uint8_t oldSREG = SREG;
cli();
servos[channel].ticks = value;
SREG = oldSREG;
}
}
int Servo::read() // return the value as degrees
{
return map( this->readMicroseconds()+1, SERVO_MIN(), SERVO_MAX(), 0, 180);
}
int Servo::readMicroseconds()
{
unsigned int pulsewidth;
if( this->servoIndex != INVALID_SERVO )
pulsewidth = ticksToUs(servos[this->servoIndex].ticks) + TRIM_DURATION ; // 12 aug 2009
else
pulsewidth = 0;
return pulsewidth;
}
bool Servo::attached()
{
return servos[this->servoIndex].Pin.isActive ;
}
#endif

132
Marlin/Servo.h

@ -0,0 +1,132 @@
/*
Servo.h - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2
Copyright (c) 2009 Michael Margolis. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
A servo is activated by creating an instance of the Servo class passing the desired pin to the attach() method.
The servos are pulsed in the background using the value most recently written using the write() method
Note that analogWrite of PWM on pins associated with the timer are disabled when the first servo is attached.
Timers are seized as needed in groups of 12 servos - 24 servos use two timers, 48 servos will use four.
The sequence used to sieze timers is defined in timers.h
The methods are:
Servo - Class for manipulating servo motors connected to Arduino pins.
attach(pin ) - Attaches a servo motor to an i/o pin.
attach(pin, min, max ) - Attaches to a pin setting min and max values in microseconds
default min is 544, max is 2400
write() - Sets the servo angle in degrees. (invalid angle that is valid as pulse in microseconds is treated as microseconds)
writeMicroseconds() - Sets the servo pulse width in microseconds
read() - Gets the last written servo pulse width as an angle between 0 and 180.
readMicroseconds() - Gets the last written servo pulse width in microseconds. (was read_us() in first release)
attached() - Returns true if there is a servo attached.
detach() - Stops an attached servos from pulsing its i/o pin.
*/
#ifndef Servo_h
#define Servo_h
#include <inttypes.h>
/*
* Defines for 16 bit timers used with Servo library
*
* If _useTimerX is defined then TimerX is a 16 bit timer on the curent board
* timer16_Sequence_t enumerates the sequence that the timers should be allocated
* _Nbr_16timers indicates how many 16 bit timers are available.
*
*/
// Say which 16 bit timers can be used and in what order
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define _useTimer5
//#define _useTimer1
#define _useTimer3
#define _useTimer4
//typedef enum { _timer5, _timer1, _timer3, _timer4, _Nbr_16timers } timer16_Sequence_t ;
typedef enum { _timer5, _timer3, _timer4, _Nbr_16timers } timer16_Sequence_t ;
#elif defined(__AVR_ATmega32U4__)
//#define _useTimer1
#define _useTimer3
//typedef enum { _timer1, _Nbr_16timers } timer16_Sequence_t ;
typedef enum { _timer3, _Nbr_16timers } timer16_Sequence_t ;
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
#define _useTimer3
//#define _useTimer1
//typedef enum { _timer3, _timer1, _Nbr_16timers } timer16_Sequence_t ;
typedef enum { _timer3, _Nbr_16timers } timer16_Sequence_t ;
#elif defined(__AVR_ATmega128__) ||defined(__AVR_ATmega1281__)||defined(__AVR_ATmega2561__)
#define _useTimer3
//#define _useTimer1
//typedef enum { _timer3, _timer1, _Nbr_16timers } timer16_Sequence_t ;
typedef enum { _timer3, _Nbr_16timers } timer16_Sequence_t ;
#else // everything else
//#define _useTimer1
//typedef enum { _timer1, _Nbr_16timers } timer16_Sequence_t ;
typedef enum { _Nbr_16timers } timer16_Sequence_t ;
#endif
#define Servo_VERSION 2 // software version of this library
#define MIN_PULSE_WIDTH 544 // the shortest pulse sent to a servo
#define MAX_PULSE_WIDTH 2400 // the longest pulse sent to a servo
#define DEFAULT_PULSE_WIDTH 1500 // default pulse width when servo is attached
#define REFRESH_INTERVAL 20000 // minumim time to refresh servos in microseconds
#define SERVOS_PER_TIMER 12 // the maximum number of servos controlled by one timer
#define MAX_SERVOS (_Nbr_16timers * SERVOS_PER_TIMER)
#define INVALID_SERVO 255 // flag indicating an invalid servo index
typedef struct {
uint8_t nbr :6 ; // a pin number from 0 to 63
uint8_t isActive :1 ; // true if this channel is enabled, pin not pulsed if false
} ServoPin_t ;
typedef struct {
ServoPin_t Pin;
unsigned int ticks;
} servo_t;
class Servo
{
public:
Servo();
uint8_t attach(int pin); // attach the given pin to the next free channel, sets pinMode, returns channel number or 0 if failure
uint8_t attach(int pin, int min, int max); // as above but also sets min and max values for writes.
void detach();
void write(int value); // if value is < 200 its treated as an angle, otherwise as pulse width in microseconds
void writeMicroseconds(int value); // Write pulse width in microseconds
int read(); // returns current pulse width as an angle between 0 and 180 degrees
int readMicroseconds(); // returns current pulse width in microseconds for this servo (was read_us() in first release)
bool attached(); // return true if this servo is attached, otherwise false
private:
uint8_t servoIndex; // index into the channel data for this servo
int8_t min; // minimum is this value times 4 added to MIN_PULSE_WIDTH
int8_t max; // maximum is this value times 4 added to MAX_PULSE_WIDTH
};
#endif

393
Marlin/pins.h

@ -14,7 +14,7 @@
#define DIGIPOTSS_PIN -1
#if MOTHERBOARD == 99
#define KNOWN_BOARD 1
#define KNOWN_BOARD 1
#define X_STEP_PIN 2
#define X_DIR_PIN 3
@ -228,7 +228,7 @@
//x axis pins
#define X_STEP_PIN 21 //different from stanard GEN7
#define X_DIR_PIN 20 //different from stanard GEN7
#define X_DIR_PIN 20 //different from stanard GEN7
#define X_ENABLE_PIN 24
#define X_STOP_PIN 0
@ -248,14 +248,14 @@
#define E0_STEP_PIN 28
#define E0_DIR_PIN 27
#define E0_ENABLE_PIN 24
#define TEMP_0_PIN 2
#define TEMP_1_PIN -1
#define TEMP_2_PIN -1
#define TEMP_BED_PIN 1 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!! (pin 34 bed)
#define HEATER_0_PIN 4
#define HEATER_1_PIN -1
#define HEATER_1_PIN -1
#define HEATER_2_PIN -1
#define HEATER_BED_PIN 3 // (bed)
@ -272,33 +272,25 @@
//our RS485 pins
//#define TX_ENABLE_PIN 12
//#define RX_ENABLE_PIN 13
#define BEEPER -1
#define SDCARDDETECT -1
#define SUICIDE_PIN -1 //has to be defined; otherwise Power_off doesn't work
#define BEEPER -1
#define SDCARDDETECT -1
#define SUICIDE_PIN -1 //has to be defined; otherwise Power_off doesn't work
#define KILL_PIN -1
//Pins for 4bit LCD Support
#define LCD_PINS_RS 18
//Pins for 4bit LCD Support
#define LCD_PINS_RS 18
#define LCD_PINS_ENABLE 17
#define LCD_PINS_D4 16
#define LCD_PINS_D5 15
#define LCD_PINS_D5 15
#define LCD_PINS_D6 13
#define LCD_PINS_D7 14
//buttons are directly attached
#define BTN_EN1 11
#define BTN_EN2 10
#define BTN_ENC 12 //the click
#define BLEN_C 2
#define BLEN_B 1
#define BLEN_A 0
#define encrot0 0
#define encrot1 2
#define encrot2 3
#define encrot3 1
#endif
/****************************************************************************************
@ -376,33 +368,28 @@
#else
#define HEATER_1_PIN 9 // EXTRUDER 2 (FAN On Sprinter)
#endif
#define HEATER_2_PIN -1
#define HEATER_2_PIN -1
#define TEMP_0_PIN 13 // ANALOG NUMBERING
#define TEMP_1_PIN 15 // ANALOG NUMBERING
#define TEMP_2_PIN -1 // ANALOG NUMBERING
#define HEATER_BED_PIN 8 // BED
#define TEMP_BED_PIN 14 // ANALOG NUMBERING
#define SERVO0_PIN 11
#define SERVO1_PIN 6
#define SERVO2_PIN 5
#define SERVO3_PIN 4
#ifdef ULTRA_LCD
#ifdef NEWPANEL
//encoder rotation values
#define encrot0 0
#define encrot1 2
#define encrot2 3
#define encrot3 1
#define BLEN_A 0
#define BLEN_B 1
#define BLEN_C 2
#define LCD_PINS_RS 16
#define LCD_PINS_ENABLE 17
#define LCD_PINS_D4 23
#define LCD_PINS_D5 25
#define LCD_PINS_D5 25
#define LCD_PINS_D6 27
#define LCD_PINS_D7 29
#ifdef REPRAP_DISCOUNT_SMART_CONTROLLER
#define BEEPER 37
@ -413,7 +400,7 @@
#define SDCARDDETECT 49
#else
//arduino pin which triggers an piezzo beeper
#define BEEPER 33 // Beeper on AUX-4
#define BEEPER 33 // Beeper on AUX-4
//buttons are directly attached using AUX-2
#ifdef REPRAPWORLD_KEYPAD
@ -423,16 +410,7 @@
#define SHIFT_OUT 40 // shift register
#define SHIFT_CLK 44 // shift register
#define SHIFT_LD 42 // shift register
// define register bit values, don't change it
#define BLEN_REPRAPWORLD_KEYPAD_F3 0
#define BLEN_REPRAPWORLD_KEYPAD_F2 1
#define BLEN_REPRAPWORLD_KEYPAD_F1 2
#define BLEN_REPRAPWORLD_KEYPAD_UP 3
#define BLEN_REPRAPWORLD_KEYPAD_RIGHT 4
#define BLEN_REPRAPWORLD_KEYPAD_MIDDLE 5
#define BLEN_REPRAPWORLD_KEYPAD_DOWN 6
#define BLEN_REPRAPWORLD_KEYPAD_LEFT 7
#else
#else
#define BTN_EN1 37
#define BTN_EN2 35
#define BTN_ENC 31 //the click
@ -447,40 +425,21 @@
#else //old style panel with shift register
//arduino pin witch triggers an piezzo beeper
#define BEEPER 33 No Beeper added
#define BEEPER 33 // No Beeper added
//buttons are attached to a shift register
// Not wired this yet
// Not wired this yet
//#define SHIFT_CLK 38
//#define SHIFT_LD 42
//#define SHIFT_OUT 40
//#define SHIFT_EN 17
#define LCD_PINS_RS 16
#define LCD_PINS_RS 16
#define LCD_PINS_ENABLE 17
#define LCD_PINS_D4 23
#define LCD_PINS_D5 25
#define LCD_PINS_D5 25
#define LCD_PINS_D6 27
#define LCD_PINS_D7 29
//encoder rotation values
#define encrot0 0
#define encrot1 2
#define encrot2 3
#define encrot3 1
//bits in the shift register that carry the buttons for:
// left up center down right red
#define BL_LE 7
#define BL_UP 6
#define BL_MI 5
#define BL_DW 4
#define BL_RI 3
#define BL_ST 2
#define BLEN_B 1
#define BLEN_A 0
#endif
#endif //ULTRA_LCD
@ -526,15 +485,15 @@
#define HEATER_1_PIN -1
#define HEATER_2_PIN -1
#define TEMP_0_PIN 2 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!!
#define TEMP_1_PIN -1
#define TEMP_2_PIN -1
#define TEMP_1_PIN -1
#define TEMP_2_PIN -1
#define TEMP_BED_PIN 1 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!!
#endif// MOTHERBOARD == 33 || MOTHERBOARD == 34
// SPI for Max6675 Thermocouple
// SPI for Max6675 Thermocouple
#ifndef SDSUPPORT
// these pins are defined in the SD library if building with SD support
// these pins are defined in the SD library if building with SD support
#define MAX_SCK_PIN 52
#define MAX_MISO_PIN 50
#define MAX_MOSI_PIN 51
@ -586,8 +545,8 @@
#define HEATER_1_PIN -1
#define HEATER_2_PIN -1
#define TEMP_0_PIN 0 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!!
#define TEMP_1_PIN -1
#define TEMP_2_PIN -1
#define TEMP_1_PIN -1
#define TEMP_2_PIN -1
#define HEATER_BED_PIN -1
#define TEMP_BED_PIN -1
@ -650,14 +609,14 @@
#define PS_ON_PIN -1 //changed @ rkoeppl 20110410
#define KILL_PIN -1 //changed @ drakelive 20120830
//our pin for debugging.
#define DEBUG_PIN 0
//our RS485 pins
#define TX_ENABLE_PIN 12
#define RX_ENABLE_PIN 13
#define TX_ENABLE_PIN 12
#define RX_ENABLE_PIN 13
#endif
/****************************************************************************************
@ -673,7 +632,7 @@
#if MOTHERBOARD == 62 || MOTHERBOARD == 63 || MOTHERBOARD == 64
#undef MOTHERBOARD
#define MOTHERBOARD 6
#define SANGUINOLOLU_V_1_2
#define SANGUINOLOLU_V_1_2
#endif
#if MOTHERBOARD == 6
#define KNOWN_BOARD 1
@ -700,7 +659,7 @@
#define LED_PIN -1
#define FAN_PIN -1
#define FAN_PIN -1
#if FAN_PIN == 12 || FAN_PIN ==13
#define FAN_SOFT_PWM
#endif
@ -754,46 +713,35 @@
//we have no buzzer installed
#define BEEPER -1
//LCD Pins
#ifdef DOGLCD
// Pins for DOGM SPI LCD Support
#define DOGLCD_A0 30
#define DOGLCD_CS 29
// GLCD features
#define LCD_CONTRAST 1
// Uncomment screen orientation
// #define LCD_SCREEN_ROT_0
// #define LCD_SCREEN_ROT_90
#define LCD_SCREEN_ROT_180
// #define LCD_SCREEN_ROT_270
#else // standard Hitachi LCD controller
#define LCD_PINS_RS 4
#define LCD_PINS_ENABLE 17
#define LCD_PINS_D4 30
#define LCD_PINS_D5 29
#define LCD_PINS_D6 28
#define LCD_PINS_D7 27
#endif
#ifdef DOGLCD
// Pins for DOGM SPI LCD Support
#define DOGLCD_A0 30
#define DOGLCD_CS 29
// GLCD features
#define LCD_CONTRAST 1
// Uncomment screen orientation
// #define LCD_SCREEN_ROT_0
// #define LCD_SCREEN_ROT_90
#define LCD_SCREEN_ROT_180
// #define LCD_SCREEN_ROT_270
#else // standard Hitachi LCD controller
#define LCD_PINS_RS 4
#define LCD_PINS_ENABLE 17
#define LCD_PINS_D4 30
#define LCD_PINS_D5 29
#define LCD_PINS_D6 28
#define LCD_PINS_D7 27
#endif
//The encoder and click button
#define BTN_EN1 11 //must be a hardware interrupt pin
#define BTN_EN2 10 //must be hardware interrupt pin
#define BTN_EN1 11
#define BTN_EN2 10
#define BTN_ENC 16 //the switch
//not connected to a pin
#define SDCARDDETECT -1
//from the same bit in the RAMPS Newpanel define
//encoder rotation values
#define encrot0 0
#define encrot1 2
#define encrot2 3
#define encrot3 1
#define BLEN_C 2
#define BLEN_B 1
#define BLEN_A 0
#define SDCARDDETECT -1
#endif //Newpanel
#endif //Ultipanel
#endif
@ -823,17 +771,17 @@
#define Y_MAX_PIN 28
#define Y_ENABLE_PIN 29
#define Z_STEP_PIN 37
#define Z_STEP_PIN 37
#define Z_DIR_PIN 39
#define Z_MIN_PIN 30
#define Z_MAX_PIN 32
#define Z_ENABLE_PIN 35
#define HEATER_BED_PIN 4
#define TEMP_BED_PIN 10
#define HEATER_BED_PIN 4
#define TEMP_BED_PIN 10
#define HEATER_0_PIN 2
#define TEMP_0_PIN 8
#define TEMP_0_PIN 8
#define HEATER_1_PIN 3
#define TEMP_1_PIN 9
@ -863,29 +811,20 @@
//arduino pin witch triggers an piezzo beeper
#define BEEPER 18
#define LCD_PINS_RS 20
#define LCD_PINS_RS 20
#define LCD_PINS_ENABLE 17
#define LCD_PINS_D4 16
#define LCD_PINS_D5 21
#define LCD_PINS_D5 21
#define LCD_PINS_D6 5
#define LCD_PINS_D7 6
//buttons are directly attached
#define BTN_EN1 40
#define BTN_EN2 42
#define BTN_ENC 19 //the click
#define BLEN_C 2
#define BLEN_B 1
#define BLEN_A 0
#define SDCARDDETECT 38
//encoder rotation values
#define encrot0 0
#define encrot1 2
#define encrot2 3
#define encrot3 1
#else //old style panel with shift register
//arduino pin witch triggers an piezzo beeper
#define BEEPER 18
@ -895,40 +834,15 @@
#define SHIFT_LD 42
#define SHIFT_OUT 40
#define SHIFT_EN 17
#define LCD_PINS_RS 16
#define LCD_PINS_RS 16
#define LCD_PINS_ENABLE 5
#define LCD_PINS_D4 6
#define LCD_PINS_D5 21
#define LCD_PINS_D5 21
#define LCD_PINS_D6 20
#define LCD_PINS_D7 19
//encoder rotation values
#ifndef ULTIMAKERCONTROLLER
#define encrot0 0
#define encrot1 2
#define encrot2 3
#define encrot3 1
#else
#define encrot0 0
#define encrot1 1
#define encrot2 3
#define encrot3 2
#endif
#define SDCARDDETECT -1
//bits in the shift register that carry the buttons for:
// left up center down right red
#define BL_LE 7
#define BL_UP 6
#define BL_MI 5
#define BL_DW 4
#define BL_RI 3
#define BL_ST 2
#define BLEN_B 1
#define BLEN_A 0
#endif
#endif //ULTRA_LCD
@ -960,17 +874,17 @@
#define Y_MAX_PIN 16
#define Y_ENABLE_PIN 29
#define Z_STEP_PIN 37
#define Z_STEP_PIN 37
#define Z_DIR_PIN 39
#define Z_MIN_PIN 19
#define Z_MAX_PIN 18
#define Z_ENABLE_PIN 35
#define HEATER_BED_PIN -1
#define TEMP_BED_PIN -1
#define HEATER_BED_PIN -1
#define TEMP_BED_PIN -1
#define HEATER_0_PIN 2
#define TEMP_0_PIN 8
#define TEMP_0_PIN 8
#define HEATER_1_PIN 1
#define TEMP_1_PIN 1
@ -994,10 +908,10 @@
#define KILL_PIN -1
#define SUICIDE_PIN -1 //PIN that has to be turned on right after start, to keep power flowing.
#define LCD_PINS_RS 24
#define LCD_PINS_RS 24
#define LCD_PINS_ENABLE 22
#define LCD_PINS_D4 36
#define LCD_PINS_D5 34
#define LCD_PINS_D5 34
#define LCD_PINS_D6 32
#define LCD_PINS_D7 30
@ -1019,17 +933,17 @@
#define X_DIR_PIN 16
#define X_ENABLE_PIN 48
#define X_MIN_PIN 37
#define X_MAX_PIN 36
#define X_MAX_PIN 36
#define Y_STEP_PIN 54
#define Y_DIR_PIN 47
#define Y_DIR_PIN 47
#define Y_ENABLE_PIN 55
#define Y_MIN_PIN 35
#define Y_MAX_PIN 34
#define Y_MAX_PIN 34
#define Z_STEP_PIN 57
#define Z_STEP_PIN 57
#define Z_DIR_PIN 56
#define Z_ENABLE_PIN 62
#define Z_ENABLE_PIN 62
#define Z_MIN_PIN 33
#define Z_MAX_PIN 32
@ -1047,45 +961,76 @@
#define LED_PIN 13
#define FAN_PIN 7
#define FAN_PIN 7
//additional FAN1 PIN (e.g. useful for electronics fan or light on/off) on PIN 8
#define PS_ON_PIN 45
#define KILL_PIN 46
#define HEATER_0_PIN 2 // EXTRUDER 1
#define HEATER_1_PIN 3 // EXTRUDER 2
#define HEATER_2_PIN 6 // EXTRUDER 3
#if (TEMP_SENSOR_0==0)
#define TEMP_0_PIN -1
#define HEATER_0_PIN -1
#else
#define HEATER_0_PIN 2 // EXTRUDER 1
#if (TEMP_SENSOR_0==-1)
#define TEMP_0_PIN 6 // ANALOG NUMBERING - connector *K1* on RUMBA thermocouple ADD ON is used
#else
#define TEMP_0_PIN 15 // ANALOG NUMBERING - default connector for thermistor *T0* on rumba board is used
#endif
#endif
#if (TEMP_SENSOR_1==0)
#define TEMP_1_PIN -1
#define HEATER_1_PIN -1
#else
#define HEATER_1_PIN 3 // EXTRUDER 2
#if (TEMP_SENSOR_1==-1)
#define TEMP_1_PIN 5 // ANALOG NUMBERING - connector *K2* on RUMBA thermocouple ADD ON is used
#else
#define TEMP_1_PIN 14 // ANALOG NUMBERING - default connector for thermistor *T1* on rumba board is used
#endif
#endif
#if (TEMP_SENSOR_2==0)
#define TEMP_2_PIN -1
#define HEATER_2_PIN -1
#else
#define HEATER_2_PIN 6 // EXTRUDER 3
#if (TEMP_SENSOR_2==-1)
#define TEMP_2_PIN 7 // ANALOG NUMBERING - connector *K3* on RUMBA thermocouple ADD ON is used <-- this can not be used when TEMP_SENSOR_BED is defined as thermocouple
#else
#define TEMP_2_PIN 13 // ANALOG NUMBERING - default connector for thermistor *T2* on rumba board is used
#endif
#endif
//optional for extruder 4 or chamber: #define TEMP_X_PIN 12 // ANALOG NUMBERING - default connector for thermistor *T3* on rumba board is used
//optional FAN1 can be used as 4th heater output: #define HEATER_3_PIN 8 // EXTRUDER 4
#define HEATER_BED_PIN 9 // BED
#define TEMP_0_PIN 15 // ANALOG NUMBERING
#define TEMP_1_PIN 14 // ANALOG NUMBERING
#define TEMP_2_PIN 13 // ANALOG NUMBERING
//optional for extruder 4 or chamber: #define TEMP_2_PIN 12 // ANALOG NUMBERING
#define TEMP_BED_PIN 11 // ANALOG NUMBERING
#if (TEMP_SENSOR_BED==0)
#define TEMP_BED_PIN -1
#define HEATER_BED_PIN -1
#else
#define HEATER_BED_PIN 9 // BED
#if (TEMP_SENSOR_BED==-1)
#define TEMP_BED_PIN 7 // ANALOG NUMBERING - connector *K3* on RUMBA thermocouple ADD ON is used <-- this can not be used when TEMP_SENSOR_2 is defined as thermocouple
#else
#define TEMP_BED_PIN 11 // ANALOG NUMBERING - default connector for thermistor *THB* on rumba board is used
#endif
#endif
#define SDPOWER -1
#define SDSS 53
#define SDCARDDETECT 49
#define BEEPER 44
#define LCD_PINS_RS 19
#define LCD_PINS_RS 19
#define LCD_PINS_ENABLE 42
#define LCD_PINS_D4 18
#define LCD_PINS_D5 38
#define LCD_PINS_D5 38
#define LCD_PINS_D6 41
#define LCD_PINS_D7 40
#define BTN_EN1 11
#define BTN_EN2 12
#define BTN_ENC 43
//encoder rotation values
#define BLEN_C 2
#define BLEN_B 1
#define BLEN_A 0
#define encrot0 0
#define encrot1 2
#define encrot2 3
#define encrot3 1
#endif //MOTHERBOARD==80
@ -1256,7 +1201,7 @@
#define LED_PIN -1
#define FAN_PIN -1
#define FAN_PIN -1
#define PS_ON_PIN 14
#define KILL_PIN -1
@ -1295,7 +1240,7 @@
* MISO (D 6) PB6 7| |34 PA6 (AI 6 / D25)
* SCK (D 7) PB7 8| |33 PA7 (AI 7 / D24)
* RST 9| |32 AREF
* VCC 10| |31 GND
* VCC 10| |31 GND
* GND 11| |30 AVCC
* XTAL2 12| |29 PC7 (D 23)
* XTAL1 13| |28 PC6 (D 22)
@ -1352,7 +1297,7 @@
#define KILL_PIN -1
#define HEATER_0_PIN 4
#define HEATER_1_PIN -1 // 12
#define HEATER_1_PIN -1 // 12
#define HEATER_2_PIN -1 // 13
#define TEMP_0_PIN 0 //D27 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!!
#define TEMP_1_PIN -1 // 1
@ -1390,12 +1335,12 @@
#define E0_ENABLE_PIN 10
/* future proofing */
#define __FS 20
#define __FD 19
#define __GS 18
#define __GD 13
#define __FS 20
#define __FD 19
#define __GS 18
#define __GD 13
#define UNUSED_PWM 14 /* PWM on LEFT connector */
#define UNUSED_PWM 14 /* PWM on LEFT connector */
#define E1_STEP_PIN -1 // 21
#define E1_DIR_PIN -1 // 20
@ -1414,18 +1359,18 @@
#define KILL_PIN -1
#define HEATER_0_PIN 3 /*DONE PWM on RIGHT connector */
#define HEATER_1_PIN -1
#define HEATER_1_PIN -1
#define HEATER_2_PIN -1
#define HEATER_1_PIN -1
#define HEATER_1_PIN -1
#define HEATER_2_PIN -1
#define TEMP_0_PIN 0 // ANALOG INPUT NUMBERING
#define TEMP_0_PIN 0 // ANALOG INPUT NUMBERING
#define TEMP_1_PIN 1 // ANALOG
#define TEMP_2_PIN -1 // 2
#define HEATER_BED_PIN 4
#define TEMP_BED_PIN 2 // 1,2 or I2C
#define I2C_SCL 16
#define I2C_SDA 17
#define I2C_SCL 16
#define I2C_SDA 17
#endif
@ -1466,7 +1411,7 @@
#define Z_MS2_PIN 67
#define HEATER_BED_PIN 3
#define TEMP_BED_PIN 2
#define TEMP_BED_PIN 2
#define HEATER_0_PIN 9
#define TEMP_0_PIN 0
@ -1474,7 +1419,11 @@
#define HEATER_1_PIN 7
#define TEMP_1_PIN 1
#ifdef BARICUDA
#define HEATER_2_PIN 6
#else
#define HEATER_2_PIN -1
#endif
#define TEMP_2_PIN -1
#define E0_STEP_PIN 34
@ -1555,9 +1504,9 @@
#define HEATER_0_PIN 9 // EXTRUDER 1
#define HEATER_1_PIN 8 // EXTRUDER 2 (FAN On Sprinter)
#define HEATER_2_PIN -1
#define HEATER_2_PIN -1
#if TEMP_SENSOR_0 == -1
#if TEMP_SENSOR_0 == -1
#define TEMP_0_PIN 8 // ANALOG NUMBERING
#else
#define TEMP_0_PIN 13 // ANALOG NUMBERING
@ -1569,37 +1518,27 @@
#define HEATER_BED_PIN 10 // BED
#define TEMP_BED_PIN 14 // ANALOG NUMBERING
#define BEEPER 33 // Beeper on AUX-4
#define BEEPER 33 // Beeper on AUX-4
#ifdef ULTRA_LCD
#ifdef NEWPANEL
//arduino pin which triggers an piezzo beeper
#define LCD_PINS_RS 16
#define LCD_PINS_RS 16
#define LCD_PINS_ENABLE 17
#define LCD_PINS_D4 23
#define LCD_PINS_D5 25
#define LCD_PINS_D5 25
#define LCD_PINS_D6 27
#define LCD_PINS_D7 29
//buttons are directly attached using AUX-2
#define BTN_EN1 59
#define BTN_EN2 64
#define BTN_ENC 43 //the click
#define BLEN_C 2
#define BLEN_B 1
#define BLEN_A 0
#define SDCARDDETECT -1 // Ramps does not use this port
//encoder rotation values
#define encrot0 0
#define encrot1 2
#define encrot2 3
#define encrot3 1
#define SDCARDDETECT -1 // Ramps does not use this port
#endif
#endif //ULTRA_LCD
@ -1610,7 +1549,7 @@
#endif
//List of pins which to ignore when asked to change by gcode, 0 and 1 are RX and TX, do not mess with those!
#define _E0_PINS E0_STEP_PIN, E0_DIR_PIN, E0_ENABLE_PIN, HEATER_0_PIN,
#define _E0_PINS E0_STEP_PIN, E0_DIR_PIN, E0_ENABLE_PIN, HEATER_0_PIN,
#if EXTRUDERS > 1
#define _E1_PINS E1_STEP_PIN, E1_DIR_PIN, E1_ENABLE_PIN, HEATER_1_PIN,
#else

22
Marlin/planner.cpp

@ -439,12 +439,20 @@ void check_axes_activity()
unsigned char z_active = 0;
unsigned char e_active = 0;
unsigned char tail_fan_speed = fanSpeed;
#ifdef BARICUDA
unsigned char tail_valve_pressure = ValvePressure;
unsigned char tail_e_to_p_pressure = EtoPPressure;
#endif
block_t *block;
if(block_buffer_tail != block_buffer_head)
{
uint8_t block_index = block_buffer_tail;
tail_fan_speed = block_buffer[block_index].fan_speed;
#ifdef BARICUDA
tail_valve_pressure = block_buffer[block_index].valve_pressure;
tail_e_to_p_pressure = block_buffer[block_index].e_to_p_pressure;
#endif
while(block_index != block_buffer_head)
{
block = &block_buffer[block_index];
@ -486,6 +494,16 @@ void check_axes_activity()
#ifdef AUTOTEMP
getHighESpeed();
#endif
#ifdef BARICUDA
#if HEATER_1_PIN > -1
analogWrite(HEATER_1_PIN,tail_valve_pressure);
#endif
#if HEATER_2_PIN > -1
analogWrite(HEATER_2_PIN,tail_e_to_p_pressure);
#endif
#endif
}
@ -559,6 +577,10 @@ void plan_buffer_line(const float &x, const float &y, const float &z, const floa
}
block->fan_speed = fanSpeed;
#ifdef BARICUDA
block->valve_pressure = ValvePressure;
block->e_to_p_pressure = EtoPPressure;
#endif
// Compute direction bits for this block
block->direction_bits = 0;

4
Marlin/planner.h

@ -60,6 +60,10 @@ typedef struct {
unsigned long final_rate; // The minimal rate at exit
unsigned long acceleration_st; // acceleration steps/sec^2
unsigned long fan_speed;
#ifdef BARICUDA
unsigned long valve_pressure;
unsigned long e_to_p_pressure;
#endif
volatile char busy;
} block_t;

24
Marlin/stepper.cpp

@ -69,9 +69,9 @@ volatile long endstops_stepsTotal,endstops_stepsDone;
static volatile bool endstop_x_hit=false;
static volatile bool endstop_y_hit=false;
static volatile bool endstop_z_hit=false;
#ifdef ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED
bool abort_on_endstop_hit = false;
#endif
#ifdef ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED
bool abort_on_endstop_hit = false;
#endif
static bool old_x_min_endstop=false;
static bool old_x_max_endstop=false;
@ -184,20 +184,20 @@ void checkHitEndstops()
SERIAL_ECHOPAIR(" Z:",(float)endstops_trigsteps[Z_AXIS]/axis_steps_per_unit[Z_AXIS]);
LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT "Z");
}
SERIAL_ECHOLN("");
SERIAL_ECHOLN("");
endstop_x_hit=false;
endstop_y_hit=false;
endstop_z_hit=false;
#ifdef ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED
if (abort_on_endstop_hit)
{
endstop_z_hit=false;
#ifdef ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED
if (abort_on_endstop_hit)
{
card.sdprinting = false;
card.closefile();
quickStop();
quickStop();
setTargetHotend0(0);
setTargetHotend1(0);
setTargetHotend2(0);
}
}
#endif
}
}
@ -879,10 +879,6 @@ void st_init()
disable_e2();
#endif
#ifdef CONTROLLERFAN_PIN
SET_OUTPUT(CONTROLLERFAN_PIN); //Set pin used for driver cooling fan
#endif
// waveform generation = 0100 = CTC
TCCR1B &= ~(1<<WGM13);
TCCR1B |= (1<<WGM12);

96
Marlin/temperature.cpp

@ -99,8 +99,9 @@ static volatile bool temp_meas_ready = false;
#ifdef FAN_SOFT_PWM
static unsigned char soft_pwm_fan;
#endif
#if EXTRUDER_0_AUTO_FAN_PIN > 0 || EXTRUDER_1_AUTO_FAN_PIN > 0 || EXTRUDER_2_AUTO_FAN_PIN > 0
static unsigned long extruder_autofan_last_check;
#endif
#if EXTRUDERS > 3
# error Unsupported number of extruders
@ -306,6 +307,76 @@ int getHeaterPower(int heater) {
return soft_pwm[heater];
}
#if EXTRUDER_0_AUTO_FAN_PIN > 0 || EXTRUDER_1_AUTO_FAN_PIN > 0 || EXTRUDER_2_AUTO_FAN_PIN > 0
#if FAN_PIN > 0
#if EXTRUDER_0_AUTO_FAN_PIN == FAN_PIN
#error "You cannot set EXTRUDER_0_AUTO_FAN_PIN equal to FAN_PIN"
#endif
#if EXTRUDER_1_AUTO_FAN_PIN == FAN_PIN
#error "You cannot set EXTRUDER_1_AUTO_FAN_PIN equal to FAN_PIN"
#endif
#if EXTRUDER_2_AUTO_FAN_PIN == FAN_PIN
#error "You cannot set EXTRUDER_2_AUTO_FAN_PIN equal to FAN_PIN"
#endif
#endif
void setExtruderAutoFanState(int pin, bool state)
{
unsigned char newFanSpeed = (state != 0) ? EXTRUDER_AUTO_FAN_SPEED : 0;
// this idiom allows both digital and PWM fan outputs (see M42 handling).
pinMode(pin, OUTPUT);
digitalWrite(pin, newFanSpeed);
analogWrite(pin, newFanSpeed);
}
void checkExtruderAutoFans()
{
uint8_t fanState = 0;
// which fan pins need to be turned on?
#if EXTRUDER_0_AUTO_FAN_PIN > 0
if (current_temperature[0] > EXTRUDER_AUTO_FAN_TEMPERATURE)
fanState |= 1;
#endif
#if EXTRUDER_1_AUTO_FAN_PIN > 0
if (current_temperature[1] > EXTRUDER_AUTO_FAN_TEMPERATURE)
{
if (EXTRUDER_1_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
fanState |= 1;
else
fanState |= 2;
}
#endif
#if EXTRUDER_2_AUTO_FAN_PIN > 0
if (current_temperature[2] > EXTRUDER_AUTO_FAN_TEMPERATURE)
{
if (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
fanState |= 1;
else if (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_1_AUTO_FAN_PIN)
fanState |= 2;
else
fanState |= 4;
}
#endif
// update extruder auto fan states
#if EXTRUDER_0_AUTO_FAN_PIN > 0
setExtruderAutoFanState(EXTRUDER_0_AUTO_FAN_PIN, (fanState & 1) != 0);
#endif
#if EXTRUDER_1_AUTO_FAN_PIN > 0
if (EXTRUDER_1_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN)
setExtruderAutoFanState(EXTRUDER_1_AUTO_FAN_PIN, (fanState & 2) != 0);
#endif
#if EXTRUDER_2_AUTO_FAN_PIN > 0
if (EXTRUDER_2_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN
&& EXTRUDER_2_AUTO_FAN_PIN != EXTRUDER_1_AUTO_FAN_PIN)
setExtruderAutoFanState(EXTRUDER_2_AUTO_FAN_PIN, (fanState & 4) != 0);
#endif
}
#endif // any extruder auto fan pins set
void manage_heater()
{
float pid_input;
@ -398,8 +469,15 @@ void manage_heater()
#endif
} // End extruder for loop
#if EXTRUDER_0_AUTO_FAN_PIN > 0 || EXTRUDER_1_AUTO_FAN_PIN > 0 || EXTRUDER_2_AUTO_FAN_PIN > 0
if(millis() - extruder_autofan_last_check > 2500) // only need to check fan state very infrequently
{
checkExtruderAutoFans();
extruder_autofan_last_check = millis();
}
#endif
#ifndef PIDTEMPBED
if(millis() - previous_millis_bed_heater < BED_CHECK_INTERVAL)
return;
@ -571,6 +649,12 @@ static void updateTemperaturesFromRawValues()
void tp_init()
{
#if (MOTHERBOARD == 80) && ((TEMP_SENSOR_0==-1)||(TEMP_SENSOR_1==-1)||(TEMP_SENSOR_2==-1)||(TEMP_SENSOR_BED==-1))
//disable RUMBA JTAG in case the thermocouple extension is plugged on top of JTAG connector
MCUCR=(1<<JTD);
MCUCR=(1<<JTD);
#endif
// Finish init of mult extruder arrays
for(int e = 0; e < EXTRUDERS; e++) {
// populate with the first value
@ -647,7 +731,7 @@ void tp_init()
#if TEMP_2_PIN < 8
DIDR0 |= 1 << TEMP_2_PIN;
#else
DIDR2 = 1<<(TEMP_2_PIN - 8);
DIDR2 |= 1<<(TEMP_2_PIN - 8);
#endif
#endif
#if (TEMP_BED_PIN > -1)
@ -689,7 +773,7 @@ void tp_init()
#if (EXTRUDERS > 1) && defined(HEATER_1_MINTEMP)
minttemp[1] = HEATER_1_MINTEMP;
while(analog2temp(minttemp_raw[1], 1) > HEATER_1_MINTEMP) {
while(analog2temp(minttemp_raw[1], 1) < HEATER_1_MINTEMP) {
#if HEATER_1_RAW_LO_TEMP < HEATER_1_RAW_HI_TEMP
minttemp_raw[1] += OVERSAMPLENR;
#else
@ -710,7 +794,7 @@ void tp_init()
#if (EXTRUDERS > 2) && defined(HEATER_2_MINTEMP)
minttemp[2] = HEATER_2_MINTEMP;
while(analog2temp(minttemp_raw[2], 2) > HEATER_2_MINTEMP) {
while(analog2temp(minttemp_raw[2], 2) < HEATER_2_MINTEMP) {
#if HEATER_2_RAW_LO_TEMP < HEATER_2_RAW_HI_TEMP
minttemp_raw[2] += OVERSAMPLENR;
#else

245
Marlin/ultralcd.cpp

@ -79,6 +79,13 @@ static void menu_action_setting_edit_callback_long5(const char* pstr, unsigned l
#define ENCODER_STEPS_PER_MENU_ITEM 5
#define ENCODER_FEEDRATE_DEADZONE 10
#if !defined(LCD_I2C_VIKI)
#define ENCODER_STEPS_PER_MENU_ITEM 5
#else
#define ENCODER_STEPS_PER_MENU_ITEM 2 // VIKI LCD rotary encoder uses a different number of steps per rotation
#endif
/* Helper macros for menus */
#define START_MENU() do { \
if (encoderPosition > 0x8000) encoderPosition = 0; \
@ -113,15 +120,18 @@ static void menu_action_setting_edit_callback_long5(const char* pstr, unsigned l
} } while(0)
/** Used variables to keep track of the menu */
#ifndef REPRAPWORLD_KEYPAD
volatile uint8_t buttons;//Contains the bits of the currently pressed buttons.
volatile uint8_t buttons_reprapworld_keypad; // to store the reprapworld_keypad shiftregister values
#else
volatile uint16_t buttons;//Contains the bits of the currently pressed buttons (extended).
#endif
uint8_t currentMenuViewOffset; /* scroll offset in the current menu */
uint32_t blocking_enc;
uint8_t lastEncoderBits;
int8_t encoderDiff; /* encoderDiff is updated from interrupt context and added to encoderPosition every LCD update */
uint32_t encoderPosition;
#if (SDCARDDETECT > -1)
#if (SDCARDDETECT > 0)
bool lcd_oldcardstatus;
#endif
#endif//ULTIPANEL
@ -163,28 +173,28 @@ static void lcd_status_screen()
lcd_quick_feedback();
}
// Dead zone at 100% feedrate
if (feedmultiply < 100 && (feedmultiply + int(encoderPosition)) > 100 ||
feedmultiply > 100 && (feedmultiply + int(encoderPosition)) < 100)
{
encoderPosition = 0;
feedmultiply = 100;
}
if (feedmultiply == 100 && int(encoderPosition) > ENCODER_FEEDRATE_DEADZONE)
{
feedmultiply += int(encoderPosition) - ENCODER_FEEDRATE_DEADZONE;
encoderPosition = 0;
}
else if (feedmultiply == 100 && int(encoderPosition) < -ENCODER_FEEDRATE_DEADZONE)
{
feedmultiply += int(encoderPosition) + ENCODER_FEEDRATE_DEADZONE;
encoderPosition = 0;
}
else if (feedmultiply != 100)
{
feedmultiply += int(encoderPosition);
encoderPosition = 0;
// Dead zone at 100% feedrate
if (feedmultiply < 100 && (feedmultiply + int(encoderPosition)) > 100 ||
feedmultiply > 100 && (feedmultiply + int(encoderPosition)) < 100)
{
encoderPosition = 0;
feedmultiply = 100;
}
if (feedmultiply == 100 && int(encoderPosition) > ENCODER_FEEDRATE_DEADZONE)
{
feedmultiply += int(encoderPosition) - ENCODER_FEEDRATE_DEADZONE;
encoderPosition = 0;
}
else if (feedmultiply == 100 && int(encoderPosition) < -ENCODER_FEEDRATE_DEADZONE)
{
feedmultiply += int(encoderPosition) + ENCODER_FEEDRATE_DEADZONE;
encoderPosition = 0;
}
else if (feedmultiply != 100)
{
feedmultiply += int(encoderPosition);
encoderPosition = 0;
}
if (feedmultiply < 10)
@ -247,14 +257,14 @@ static void lcd_main_menu()
}else{
MENU_ITEM(submenu, MSG_CARD_MENU, lcd_sdcard_menu);
#if SDCARDDETECT < 1
MENU_ITEM(gcode, MSG_CNG_SDCARD, PSTR("M21")); // SD-card changed by user
#endif
MENU_ITEM(gcode, MSG_CNG_SDCARD, PSTR("M21")); // SD-card changed by user
#endif
}
}else{
MENU_ITEM(submenu, MSG_NO_CARD, lcd_sdcard_menu);
#if SDCARDDETECT < 1
MENU_ITEM(gcode, MSG_INIT_SDCARD, PSTR("M21")); // Manually initialize the SD-card via user interface
#endif
#if SDCARDDETECT < 1
MENU_ITEM(gcode, MSG_INIT_SDCARD, PSTR("M21")); // Manually initialize the SD-card via user interface
#endif
}
#endif
END_MENU();
@ -277,7 +287,7 @@ void lcd_preheat_pla()
setTargetBed(plaPreheatHPBTemp);
fanSpeed = plaPreheatFanSpeed;
lcd_return_to_status();
setWatch(); // heater sanity check timer
setWatch(); // heater sanity check timer
}
void lcd_preheat_abs()
@ -288,16 +298,16 @@ void lcd_preheat_abs()
setTargetBed(absPreheatHPBTemp);
fanSpeed = absPreheatFanSpeed;
lcd_return_to_status();
setWatch(); // heater sanity check timer
setWatch(); // heater sanity check timer
}
static void lcd_cooldown()
{
setTargetHotend0(0);
setTargetHotend1(0);
setTargetHotend2(0);
setTargetBed(0);
lcd_return_to_status();
setTargetHotend0(0);
setTargetHotend1(0);
setTargetHotend2(0);
setTargetBed(0);
lcd_return_to_status();
}
static void lcd_tune_menu()
@ -496,10 +506,10 @@ static void lcd_control_menu()
static void lcd_control_temperature_menu()
{
// set up temp variables - undo the default scaling
raw_Ki = unscalePID_i(Ki);
raw_Kd = unscalePID_d(Kd);
// set up temp variables - undo the default scaling
raw_Ki = unscalePID_i(Ki);
raw_Kd = unscalePID_d(Kd);
START_MENU();
MENU_ITEM(back, MSG_CONTROL, lcd_control_menu);
MENU_ITEM_EDIT(int3, MSG_NOZZLE, &target_temperature[0], 0, HEATER_0_MAXTEMP - 15);
@ -521,7 +531,7 @@ static void lcd_control_temperature_menu()
#endif
#ifdef PIDTEMP
MENU_ITEM_EDIT(float52, MSG_PID_P, &Kp, 1, 9990);
// i is typically a small value so allows values below 1
// i is typically a small value so allows values below 1
MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_I, &raw_Ki, 0.01, 9990, copy_and_scalePID_i);
MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_D, &raw_Kd, 1, 9990, copy_and_scalePID_d);
# ifdef PID_ADD_EXTRUSION_RATE
@ -725,21 +735,21 @@ menu_edit_type(float, float52, ftostr52, 100)
menu_edit_type(unsigned long, long5, ftostr5, 0.01)
#ifdef REPRAPWORLD_KEYPAD
static void reprapworld_keypad_move_y_down() {
static void reprapworld_keypad_move_y_down() {
encoderPosition = 1;
move_menu_scale = REPRAPWORLD_KEYPAD_MOVE_STEP;
lcd_move_y();
}
static void reprapworld_keypad_move_y_up() {
encoderPosition = -1;
move_menu_scale = REPRAPWORLD_KEYPAD_MOVE_STEP;
lcd_move_y();
}
static void reprapworld_keypad_move_home() {
//enquecommand_P((PSTR("G28"))); // move all axis home
// TODO gregor: move all axis home, i have currently only one axis on my prusa i3
enquecommand_P((PSTR("G28 Y")));
}
lcd_move_y();
}
static void reprapworld_keypad_move_y_up() {
encoderPosition = -1;
move_menu_scale = REPRAPWORLD_KEYPAD_MOVE_STEP;
lcd_move_y();
}
static void reprapworld_keypad_move_home() {
//enquecommand_P((PSTR("G28"))); // move all axis home
// TODO gregor: move all axis home, i have currently only one axis on my prusa i3
enquecommand_P((PSTR("G28 Y")));
}
#endif
/** End of menus **/
@ -800,18 +810,20 @@ void lcd_init()
#ifdef NEWPANEL
pinMode(BTN_EN1,INPUT);
pinMode(BTN_EN2,INPUT);
pinMode(BTN_ENC,INPUT);
pinMode(SDCARDDETECT,INPUT);
WRITE(BTN_EN1,HIGH);
WRITE(BTN_EN2,HIGH);
#if BTN_ENC > 0
pinMode(BTN_ENC,INPUT);
WRITE(BTN_ENC,HIGH);
#ifdef REPRAPWORLD_KEYPAD
pinMode(SHIFT_CLK,OUTPUT);
pinMode(SHIFT_LD,OUTPUT);
pinMode(SHIFT_OUT,INPUT);
WRITE(SHIFT_OUT,HIGH);
WRITE(SHIFT_LD,HIGH);
#endif
#endif
#ifdef REPRAPWORLD_KEYPAD
pinMode(SHIFT_CLK,OUTPUT);
pinMode(SHIFT_LD,OUTPUT);
pinMode(SHIFT_OUT,INPUT);
WRITE(SHIFT_OUT,HIGH);
WRITE(SHIFT_LD,HIGH);
#endif
#else
pinMode(SHIFT_CLK,OUTPUT);
pinMode(SHIFT_LD,OUTPUT);
@ -821,12 +833,14 @@ void lcd_init()
WRITE(SHIFT_LD,HIGH);
WRITE(SHIFT_EN,LOW);
#endif//!NEWPANEL
#if (SDCARDDETECT > -1)
#if (SDCARDDETECT > 0)
WRITE(SDCARDDETECT, HIGH);
lcd_oldcardstatus = IS_SD_INSERTED;
#endif//(SDCARDDETECT > -1)
#endif//(SDCARDDETECT > 0)
lcd_buttons_update();
#ifdef ULTIPANEL
encoderDiff = 0;
#endif
}
void lcd_update()
@ -835,7 +849,11 @@ void lcd_update()
lcd_buttons_update();
#if (SDCARDDETECT > -1)
#ifdef LCD_HAS_SLOW_BUTTONS
buttons |= lcd_implementation_read_slow_buttons(); // buttons which take too long to read in interrupt context
#endif
#if (SDCARDDETECT > 0)
if((IS_SD_INSERTED != lcd_oldcardstatus))
{
lcdDrawUpdate = 2;
@ -858,17 +876,17 @@ void lcd_update()
if (lcd_next_update_millis < millis())
{
#ifdef ULTIPANEL
#ifdef REPRAPWORLD_KEYPAD
if (REPRAPWORLD_KEYPAD_MOVE_Y_DOWN) {
reprapworld_keypad_move_y_down();
}
if (REPRAPWORLD_KEYPAD_MOVE_Y_UP) {
reprapworld_keypad_move_y_up();
}
if (REPRAPWORLD_KEYPAD_MOVE_HOME) {
reprapworld_keypad_move_home();
}
#endif
#ifdef REPRAPWORLD_KEYPAD
if (REPRAPWORLD_KEYPAD_MOVE_Y_DOWN) {
reprapworld_keypad_move_y_down();
}
if (REPRAPWORLD_KEYPAD_MOVE_Y_UP) {
reprapworld_keypad_move_y_up();
}
if (REPRAPWORLD_KEYPAD_MOVE_HOME) {
reprapworld_keypad_move_home();
}
#endif
if (encoderDiff)
{
lcdDrawUpdate = 1;
@ -881,21 +899,26 @@ void lcd_update()
#endif//ULTIPANEL
#ifdef DOGLCD // Changes due to different driver architecture of the DOGM display
blink++; // Variable for fan animation and alive dot
u8g.firstPage();
do {
u8g.setFont(u8g_font_6x10_marlin);
u8g.setPrintPos(125,0);
if (blink % 2) u8g.setColorIndex(1); else u8g.setColorIndex(0); // Set color for the alive dot
u8g.drawPixel(127,63); // draw alive dot
u8g.setColorIndex(1); // black on white
(*currentMenu)();
if (!lcdDrawUpdate) break; // Terminate display update, when nothing new to draw. This must be done before the last dogm.next()
} while( u8g.nextPage() );
blink++; // Variable for fan animation and alive dot
u8g.firstPage();
do
{
u8g.setFont(u8g_font_6x10_marlin);
u8g.setPrintPos(125,0);
if (blink % 2) u8g.setColorIndex(1); else u8g.setColorIndex(0); // Set color for the alive dot
u8g.drawPixel(127,63); // draw alive dot
u8g.setColorIndex(1); // black on white
(*currentMenu)();
if (!lcdDrawUpdate) break; // Terminate display update, when nothing new to draw. This must be done before the last dogm.next()
} while( u8g.nextPage() );
#else
(*currentMenu)();
#endif
#ifdef LCD_HAS_STATUS_INDICATORS
lcd_implementation_update_indicators();
#endif
#ifdef ULTIPANEL
if(timeoutToStatus < millis() && currentMenu != lcd_status_screen)
{
@ -946,23 +969,25 @@ void lcd_buttons_update()
uint8_t newbutton=0;
if(READ(BTN_EN1)==0) newbutton|=EN_A;
if(READ(BTN_EN2)==0) newbutton|=EN_B;
#if BTN_ENC > 0
if((blocking_enc<millis()) && (READ(BTN_ENC)==0))
newbutton |= EN_C;
#endif
#ifdef REPRAPWORLD_KEYPAD
// for the reprapworld_keypad
uint8_t newbutton_reprapworld_keypad=0;
WRITE(SHIFT_LD,LOW);
WRITE(SHIFT_LD,HIGH);
for(int8_t i=0;i<8;i++) {
newbutton_reprapworld_keypad = newbutton_reprapworld_keypad>>1;
if(READ(SHIFT_OUT))
newbutton_reprapworld_keypad|=(1<<7);
WRITE(SHIFT_CLK,HIGH);
WRITE(SHIFT_CLK,LOW);
}
newbutton |= ((~newbutton_reprapworld_keypad) << REPRAPWORLD_BTN_OFFSET); //invert it, because a pressed switch produces a logical 0
#endif
buttons = newbutton;
#ifdef REPRAPWORLD_KEYPAD
// for the reprapworld_keypad
uint8_t newbutton_reprapworld_keypad=0;
WRITE(SHIFT_LD,LOW);
WRITE(SHIFT_LD,HIGH);
for(int8_t i=0;i<8;i++) {
newbutton_reprapworld_keypad = newbutton_reprapworld_keypad>>1;
if(READ(SHIFT_OUT))
newbutton_reprapworld_keypad|=(1<<7);
WRITE(SHIFT_CLK,HIGH);
WRITE(SHIFT_CLK,LOW);
}
buttons_reprapworld_keypad=~newbutton_reprapworld_keypad; //invert it, because a pressed switch produces a logical 0
#endif
#else //read it from the shift register
uint8_t newbutton=0;
WRITE(SHIFT_LD,LOW);
@ -1017,6 +1042,18 @@ void lcd_buttons_update()
}
lastEncoderBits = enc;
}
void lcd_buzz(long duration, uint16_t freq)
{
#ifdef LCD_USE_I2C_BUZZER
lcd.buzz(duration,freq);
#endif
}
bool lcd_clicked()
{
return LCD_CLICKED;
}
#endif//ULTIPANEL
/********************************/
@ -1218,7 +1255,7 @@ void copy_and_scalePID_i()
{
Ki = scalePID_i(raw_Ki);
updatePID();
}
}
// Callback for after editing PID d value
// grab the pid d value out of the temp variable; scale it; then update the PID driver
@ -1226,6 +1263,6 @@ void copy_and_scalePID_d()
{
Kd = scalePID_d(raw_Kd);
updatePID();
}
}
#endif //ULTRA_LCD

41
Marlin/ultralcd.h

@ -22,10 +22,6 @@
#ifdef ULTIPANEL
void lcd_buttons_update();
extern volatile uint8_t buttons; //the last checked buttons in a bit array.
#ifdef REPRAPWORLD_KEYPAD
extern volatile uint8_t buttons_reprapworld_keypad; // to store the keypad shiftregister values
#endif
#else
FORCE_INLINE void lcd_buttons_update() {}
#endif
@ -38,40 +34,8 @@
extern int absPreheatHPBTemp;
extern int absPreheatFanSpeed;
#ifdef NEWPANEL
#define EN_C (1<<BLEN_C)
#define EN_B (1<<BLEN_B)
#define EN_A (1<<BLEN_A)
#define LCD_CLICKED (buttons&EN_C)
#ifdef REPRAPWORLD_KEYPAD
#define EN_REPRAPWORLD_KEYPAD_F3 (1<<BLEN_REPRAPWORLD_KEYPAD_F3)
#define EN_REPRAPWORLD_KEYPAD_F2 (1<<BLEN_REPRAPWORLD_KEYPAD_F2)
#define EN_REPRAPWORLD_KEYPAD_F1 (1<<BLEN_REPRAPWORLD_KEYPAD_F1)
#define EN_REPRAPWORLD_KEYPAD_UP (1<<BLEN_REPRAPWORLD_KEYPAD_UP)
#define EN_REPRAPWORLD_KEYPAD_RIGHT (1<<BLEN_REPRAPWORLD_KEYPAD_RIGHT)
#define EN_REPRAPWORLD_KEYPAD_MIDDLE (1<<BLEN_REPRAPWORLD_KEYPAD_MIDDLE)
#define EN_REPRAPWORLD_KEYPAD_DOWN (1<<BLEN_REPRAPWORLD_KEYPAD_DOWN)
#define EN_REPRAPWORLD_KEYPAD_LEFT (1<<BLEN_REPRAPWORLD_KEYPAD_LEFT)
#define LCD_CLICKED ((buttons&EN_C) || (buttons_reprapworld_keypad&EN_REPRAPWORLD_KEYPAD_F1))
#define REPRAPWORLD_KEYPAD_MOVE_Y_DOWN (buttons_reprapworld_keypad&EN_REPRAPWORLD_KEYPAD_DOWN)
#define REPRAPWORLD_KEYPAD_MOVE_Y_UP (buttons_reprapworld_keypad&EN_REPRAPWORLD_KEYPAD_UP)
#define REPRAPWORLD_KEYPAD_MOVE_HOME (buttons_reprapworld_keypad&EN_REPRAPWORLD_KEYPAD_MIDDLE)
#endif //REPRAPWORLD_KEYPAD
#else
//atomatic, do not change
#define B_LE (1<<BL_LE)
#define B_UP (1<<BL_UP)
#define B_MI (1<<BL_MI)
#define B_DW (1<<BL_DW)
#define B_RI (1<<BL_RI)
#define B_ST (1<<BL_ST)
#define EN_B (1<<BLEN_B)
#define EN_A (1<<BLEN_A)
#define LCD_CLICKED ((buttons&B_MI)||(buttons&B_ST))
#endif//NEWPANEL
void lcd_buzz(long duration,uint16_t freq);
bool lcd_clicked();
#else //no lcd
FORCE_INLINE void lcd_update() {}
@ -79,6 +43,7 @@
FORCE_INLINE void lcd_setstatus(const char* message) {}
FORCE_INLINE void lcd_buttons_update() {}
FORCE_INLINE void lcd_reset_alert_level() {}
FORCE_INLINE void lcd_buzz(long duration,uint16_t freq) {}
#define LCD_MESSAGEPGM(x)
#define LCD_ALERTMESSAGEPGM(x)

1263
Marlin/ultralcd_implementation_hitachi_HD44780.h

File diff suppressed because it is too large

450
README.md

@ -1,223 +1,227 @@
WARNING:
--------
THIS IS RELEASE CANDIDATE 2 FOR MARLIN 1.0.0
The configuration is now split in two files
Configuration.h for the normal settings
Configuration_adv.h for the advanced settings
Gen7T is not supported.
Quick Information
===================
This RepRap firmware is a mashup between <a href="https://github.com/kliment/Sprinter">Sprinter</a>, <a href="https://github.com/simen/grbl/tree">grbl</a> and many original parts.
Derived from Sprinter and Grbl by Erik van der Zalm.
Sprinters lead developers are Kliment and caru.
Grbls lead developer is Simen Svale Skogsrud. Sonney Jeon (Chamnit) improved some parts of grbl
A fork by bkubicek for the Ultimaker was merged, and further development was aided by him.
Some features have been added by:
Lampmaker, Bradley Feldman, and others...
Features:
* Interrupt based movement with real linear acceleration
* High steprate
* Look ahead (Keep the speed high when possible. High cornering speed)
* Interrupt based temperature protection
* preliminary support for Matthew Roberts advance algorithm
For more info see: http://reprap.org/pipermail/reprap-dev/2011-May/003323.html
* Full endstop support
* SD Card support
* SD Card folders (works in pronterface)
* SD Card autostart support
* LCD support (ideally 20x4)
* LCD menu system for autonomous SD card printing, controlled by an click-encoder.
* EEPROM storage of e.g. max-velocity, max-acceleration, and similar variables
* many small but handy things originating from bkubicek's fork.
* Arc support
* Temperature oversampling
* Dynamic Temperature setpointing aka "AutoTemp"
* Support for QTMarlin, a very beta GUI for PID-tuning and velocity-acceleration testing. https://github.com/bkubicek/QTMarlin
* Endstop trigger reporting to the host software.
* Updated sdcardlib
* Heater power reporting. Useful for PID monitoring.
* PID tuning
* CoreXY kinematics (www.corexy.com/theory.html)
* Configurable serial port to support connection of wireless adaptors.
The default baudrate is 250000. This baudrate has less jitter and hence errors than the usual 115200 baud, but is less supported by drivers and host-environments.
Differences and additions to the already good Sprinter firmware:
================================================================
*Look-ahead:*
Marlin has look-ahead. While sprinter has to break and re-accelerate at each corner,
lookahead will only decelerate and accelerate to a velocity,
so that the change in vectorial velocity magnitude is less than the xy_jerk_velocity.
This is only possible, if some future moves are already processed, hence the name.
It leads to less over-deposition at corners, especially at flat angles.
*Arc support:*
Slic3r can find curves that, although broken into segments, were ment to describe an arc.
Marlin is able to print those arcs. The advantage is the firmware can choose the resolution,
and can perform the arc with nearly constant velocity, resulting in a nice finish.
Also, less serial communication is needed.
*Temperature Oversampling:*
To reduce noise and make the PID-differential term more useful, 16 ADC conversion results are averaged.
*AutoTemp:*
If your gcode contains a wide spread of extruder velocities, or you realtime change the building speed, the temperature should be changed accordingly.
Usually, higher speed requires higher temperature.
This can now be performed by the AutoTemp function
By calling M109 S<mintemp> T<maxtemp> F<factor> you enter the autotemp mode.
You can leave it by calling M109 without any F.
If active, the maximal extruder stepper rate of all buffered moves will be calculated, and named "maxerate" [steps/sec].
The wanted temperature then will be set to t=tempmin+factor*maxerate, while being limited between tempmin and tempmax.
If the target temperature is set manually or by gcode to a value less then tempmin, it will be kept without change.
Ideally, your gcode can be completely free of temperature controls, apart from a M109 S T F in the start.gcode, and a M109 S0 in the end.gcode.
*EEPROM:*
If you know your PID values, the acceleration and max-velocities of your unique machine, you can set them, and finally store them in the EEPROM.
After each reboot, it will magically load them from EEPROM, independent what your Configuration.h says.
*LCD Menu:*
If your hardware supports it, you can build yourself a LCD-CardReader+Click+encoder combination. It will enable you to realtime tune temperatures,
accelerations, velocities, flow rates, select and print files from the SD card, preheat, disable the steppers, and do other fancy stuff.
One working hardware is documented here: http://www.thingiverse.com/thing:12663
Also, with just a 20x4 or 16x2 display, useful data is shown.
*SD card folders:*
If you have an SD card reader attached to your controller, also folders work now. Listing the files in pronterface will show "/path/subpath/file.g".
You can write to file in a subfolder by specifying a similar text using small letters in the path.
Also, backup copies of various operating systems are hidden, as well as files not ending with ".g".
*SD card folders:*
If you place a file auto[0-9].g into the root of the sd card, it will be automatically executed if you boot the printer. The same file will be executed by selecting "Autostart" from the menu.
First *0 will be performed, than *1 and so on. That way, you can heat up or even print automatically without user interaction.
*Endstop trigger reporting:*
If an endstop is hit while moving towards the endstop, the location at which the firmware thinks that the endstop was triggered is outputed on the serial port.
This is useful, because the user gets a warning message.
However, also tools like QTMarlin can use this for finding acceptable combinations of velocity+acceleration.
*Coding paradigm:*
Not relevant from a user side, but Marlin was split into thematic junks, and has tried to partially enforced private variables.
This is intended to make it clearer, what interacts which what, and leads to a higher level of modularization.
We think that this is a useful prestep for porting this firmware to e.g. an ARM platform in the future.
A lot of RAM (with enabled LCD ~2200 bytes) was saved by storing char []="some message" in Program memory.
In the serial communication, a #define based level of abstraction was enforced, so that it is clear that
some transfer is information (usually beginning with "echo:"), an error "error:", or just normal protocol,
necessary for backwards compatibility.
*Interrupt based temperature measurements:*
An interrupt is used to manage ADC conversions, and enforce checking for critical temperatures.
This leads to less blocking in the heater management routine.
Non-standard M-Codes, different to an old version of sprinter:
==============================================================
Movement:
* G2 - CW ARC
* G3 - CCW ARC
General:
* M17 - Enable/Power all stepper motors. Compatibility to ReplicatorG.
* M18 - Disable all stepper motors; same as M84.Compatibility to ReplicatorG.
* M30 - Print time since last M109 or SD card start to serial
* M42 - Change pin status via gcode
* M80 - Turn on Power Supply
* M81 - Turn off Power Supply
* M114 - Output current position to serial port
* M119 - Output Endstop status to serial port
Movement variables:
* M202 - Set max acceleration in units/s^2 for travel moves (M202 X1000 Y1000) Unused in Marlin!!
* M203 - Set maximum feedrate that your machine can sustain (M203 X200 Y200 Z300 E10000) in mm/sec
* M204 - Set default acceleration: S normal moves T filament only moves (M204 S3000 T7000) im mm/sec^2 also sets minimum segment time in ms (B20000) to prevent buffer underruns and M20 minimum feedrate
* M206 - set home offsets. This sets the X,Y,Z coordinates of the endstops (and is added to the {X,Y,Z}_HOME_POS configuration options (and is also added to the coordinates, if any, provided to G82, as with earlier firmware)
* M220 - set build speed mulitplying S:factor in percent ; aka "realtime tuneing in the gcode". So you can slow down if you have islands in one height-range, and speed up otherwise.
* M221 - set the extrude multiplying S:factor in percent
* M400 - Finish all buffered moves.
Temperature variables:
* M301 - Set PID parameters P I and D
* M302 - Allow cold extrudes
* M303 - PID relay autotune S<temperature> sets the target temperature. (default target temperature = 150C)
Advance:
* M200 - Set filament diameter for advance
* M205 - advanced settings: minimum travel speed S=while printing T=travel only, B=minimum segment time X= maximum xy jerk, Z=maximum Z jerk
EEPROM:
* M500 - stores paramters in EEPROM. This parameters are stored: axis_steps_per_unit, max_feedrate, max_acceleration ,acceleration,retract_acceleration,
minimumfeedrate,mintravelfeedrate,minsegmenttime, jerk velocities, PID
* M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily).
* M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to.
* M503 - print the current settings (from memory not from eeprom)
MISC:
* M240 - Trigger a camera to take a photograph
* M999 - Restart after being stopped by error
Configuring and compilation:
============================
Install the arduino software IDE/toolset v23 (Some configurations also work with 1.x.x)
http://www.arduino.cc/en/Main/Software
For gen6/gen7 and sanguinololu the Sanguino directory in the Marlin dir needs to be copied to the arduino environment.
copy ArduinoAddons\Arduino_x.x.x\sanguino <arduino home>\hardware\Sanguino
Install Ultimaker's RepG 25 build
http://software.ultimaker.com
For SD handling and as better substitute (apart from stl manipulation) download
the very nice Kliment's printrun/pronterface https://github.com/kliment/Printrun
Copy the Ultimaker Marlin firmware
https://github.com/ErikZalm/Marlin/tree/Marlin_v1
(Use the download button)
Start the arduino IDE.
Select Tools -> Board -> Arduino Mega 2560 or your microcontroller
Select the correct serial port in Tools ->Serial Port
Open Marlin.pde
Click the Verify/Compile button
Click the Upload button
If all goes well the firmware is uploading
Start Ultimaker's Custom RepG 25
Make sure Show Experimental Profiles is enabled in Preferences
Select Sprinter as the Driver
Press the Connect button.
KNOWN ISSUES: RepG will display: Unknown: marlin x.y.z
That's ok. Enjoy Silky Smooth Printing.
==========================
Marlin 3D Printer Firmware
==========================
Notes:
-----
The configuration is now split in two files:
Configuration.h for the normal settings
Configuration_adv.h for the advanced settings
Gen7T is not supported.
Quick Information
===================
This RepRap firmware is a mashup between <a href="https://github.com/kliment/Sprinter">Sprinter</a>, <a href="https://github.com/simen/grbl/tree">grbl</a> and many original parts.
Derived from Sprinter and Grbl by Erik van der Zalm.
Sprinters lead developers are Kliment and caru.
Grbls lead developer is Simen Svale Skogsrud. Sonney Jeon (Chamnit) improved some parts of grbl
A fork by bkubicek for the Ultimaker was merged, and further development was aided by him.
Some features have been added by:
Lampmaker, Bradley Feldman, and others...
Features:
* Interrupt based movement with real linear acceleration
* High steprate
* Look ahead (Keep the speed high when possible. High cornering speed)
* Interrupt based temperature protection
* preliminary support for Matthew Roberts advance algorithm
For more info see: http://reprap.org/pipermail/reprap-dev/2011-May/003323.html
* Full endstop support
* SD Card support
* SD Card folders (works in pronterface)
* SD Card autostart support
* LCD support (ideally 20x4)
* LCD menu system for autonomous SD card printing, controlled by an click-encoder.
* EEPROM storage of e.g. max-velocity, max-acceleration, and similar variables
* many small but handy things originating from bkubicek's fork.
* Arc support
* Temperature oversampling
* Dynamic Temperature setpointing aka "AutoTemp"
* Support for QTMarlin, a very beta GUI for PID-tuning and velocity-acceleration testing. https://github.com/bkubicek/QTMarlin
* Endstop trigger reporting to the host software.
* Updated sdcardlib
* Heater power reporting. Useful for PID monitoring.
* PID tuning
* CoreXY kinematics (www.corexy.com/theory.html)
* Configurable serial port to support connection of wireless adaptors.
* Automatic operation of extruder/cold-end cooling fans based on nozzle temperature
The default baudrate is 250000. This baudrate has less jitter and hence errors than the usual 115200 baud, but is less supported by drivers and host-environments.
Differences and additions to the already good Sprinter firmware:
================================================================
*Look-ahead:*
Marlin has look-ahead. While sprinter has to break and re-accelerate at each corner,
lookahead will only decelerate and accelerate to a velocity,
so that the change in vectorial velocity magnitude is less than the xy_jerk_velocity.
This is only possible, if some future moves are already processed, hence the name.
It leads to less over-deposition at corners, especially at flat angles.
*Arc support:*
Slic3r can find curves that, although broken into segments, were ment to describe an arc.
Marlin is able to print those arcs. The advantage is the firmware can choose the resolution,
and can perform the arc with nearly constant velocity, resulting in a nice finish.
Also, less serial communication is needed.
*Temperature Oversampling:*
To reduce noise and make the PID-differential term more useful, 16 ADC conversion results are averaged.
*AutoTemp:*
If your gcode contains a wide spread of extruder velocities, or you realtime change the building speed, the temperature should be changed accordingly.
Usually, higher speed requires higher temperature.
This can now be performed by the AutoTemp function
By calling M109 S<mintemp> T<maxtemp> F<factor> you enter the autotemp mode.
You can leave it by calling M109 without any F.
If active, the maximal extruder stepper rate of all buffered moves will be calculated, and named "maxerate" [steps/sec].
The wanted temperature then will be set to t=tempmin+factor*maxerate, while being limited between tempmin and tempmax.
If the target temperature is set manually or by gcode to a value less then tempmin, it will be kept without change.
Ideally, your gcode can be completely free of temperature controls, apart from a M109 S T F in the start.gcode, and a M109 S0 in the end.gcode.
*EEPROM:*
If you know your PID values, the acceleration and max-velocities of your unique machine, you can set them, and finally store them in the EEPROM.
After each reboot, it will magically load them from EEPROM, independent what your Configuration.h says.
*LCD Menu:*
If your hardware supports it, you can build yourself a LCD-CardReader+Click+encoder combination. It will enable you to realtime tune temperatures,
accelerations, velocities, flow rates, select and print files from the SD card, preheat, disable the steppers, and do other fancy stuff.
One working hardware is documented here: http://www.thingiverse.com/thing:12663
Also, with just a 20x4 or 16x2 display, useful data is shown.
*SD card folders:*
If you have an SD card reader attached to your controller, also folders work now. Listing the files in pronterface will show "/path/subpath/file.g".
You can write to file in a subfolder by specifying a similar text using small letters in the path.
Also, backup copies of various operating systems are hidden, as well as files not ending with ".g".
*SD card folders:*
If you place a file auto[0-9].g into the root of the sd card, it will be automatically executed if you boot the printer. The same file will be executed by selecting "Autostart" from the menu.
First *0 will be performed, than *1 and so on. That way, you can heat up or even print automatically without user interaction.
*Endstop trigger reporting:*
If an endstop is hit while moving towards the endstop, the location at which the firmware thinks that the endstop was triggered is outputed on the serial port.
This is useful, because the user gets a warning message.
However, also tools like QTMarlin can use this for finding acceptable combinations of velocity+acceleration.
*Coding paradigm:*
Not relevant from a user side, but Marlin was split into thematic junks, and has tried to partially enforced private variables.
This is intended to make it clearer, what interacts which what, and leads to a higher level of modularization.
We think that this is a useful prestep for porting this firmware to e.g. an ARM platform in the future.
A lot of RAM (with enabled LCD ~2200 bytes) was saved by storing char []="some message" in Program memory.
In the serial communication, a #define based level of abstraction was enforced, so that it is clear that
some transfer is information (usually beginning with "echo:"), an error "error:", or just normal protocol,
necessary for backwards compatibility.
*Interrupt based temperature measurements:*
An interrupt is used to manage ADC conversions, and enforce checking for critical temperatures.
This leads to less blocking in the heater management routine.
Non-standard M-Codes, different to an old version of sprinter:
==============================================================
Movement:
* G2 - CW ARC
* G3 - CCW ARC
General:
* M17 - Enable/Power all stepper motors. Compatibility to ReplicatorG.
* M18 - Disable all stepper motors; same as M84.Compatibility to ReplicatorG.
* M30 - Print time since last M109 or SD card start to serial
* M42 - Change pin status via gcode
* M80 - Turn on Power Supply
* M81 - Turn off Power Supply
* M114 - Output current position to serial port
* M119 - Output Endstop status to serial port
Movement variables:
* M202 - Set max acceleration in units/s^2 for travel moves (M202 X1000 Y1000) Unused in Marlin!!
* M203 - Set maximum feedrate that your machine can sustain (M203 X200 Y200 Z300 E10000) in mm/sec
* M204 - Set default acceleration: S normal moves T filament only moves (M204 S3000 T7000) im mm/sec^2 also sets minimum segment time in ms (B20000) to prevent buffer underruns and M20 minimum feedrate
* M206 - set home offsets. This sets the X,Y,Z coordinates of the endstops (and is added to the {X,Y,Z}_HOME_POS configuration options (and is also added to the coordinates, if any, provided to G82, as with earlier firmware)
* M220 - set build speed mulitplying S:factor in percent ; aka "realtime tuneing in the gcode". So you can slow down if you have islands in one height-range, and speed up otherwise.
* M221 - set the extrude multiplying S:factor in percent
* M400 - Finish all buffered moves.
Temperature variables:
* M301 - Set PID parameters P I and D
* M302 - Allow cold extrudes
* M303 - PID relay autotune S<temperature> sets the target temperature. (default target temperature = 150C)
Advance:
* M200 - Set filament diameter for advance
* M205 - advanced settings: minimum travel speed S=while printing T=travel only, B=minimum segment time X= maximum xy jerk, Z=maximum Z jerk
EEPROM:
* M500 - stores paramters in EEPROM. This parameters are stored: axis_steps_per_unit, max_feedrate, max_acceleration ,acceleration,retract_acceleration,
minimumfeedrate,mintravelfeedrate,minsegmenttime, jerk velocities, PID
* M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily).
* M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to.
* M503 - print the current settings (from memory not from eeprom)
MISC:
* M240 - Trigger a camera to take a photograph
* M999 - Restart after being stopped by error
Configuring and compilation:
============================
Install the arduino software IDE/toolset v23 (Some configurations also work with 1.x.x)
http://www.arduino.cc/en/Main/Software
For gen6/gen7 and sanguinololu the Sanguino directory in the Marlin dir needs to be copied to the arduino environment.
copy ArduinoAddons\Arduino_x.x.x\sanguino <arduino home>\hardware\Sanguino
Install Ultimaker's RepG 25 build
http://software.ultimaker.com
For SD handling and as better substitute (apart from stl manipulation) download
the very nice Kliment's printrun/pronterface https://github.com/kliment/Printrun
Copy the Ultimaker Marlin firmware
https://github.com/ErikZalm/Marlin/tree/Marlin_v1
(Use the download button)
Start the arduino IDE.
Select Tools -> Board -> Arduino Mega 2560 or your microcontroller
Select the correct serial port in Tools ->Serial Port
Open Marlin.pde
Click the Verify/Compile button
Click the Upload button
If all goes well the firmware is uploading
Start Ultimaker's Custom RepG 25
Make sure Show Experimental Profiles is enabled in Preferences
Select Sprinter as the Driver
Press the Connect button.
KNOWN ISSUES: RepG will display: Unknown: marlin x.y.z
That's ok. Enjoy Silky Smooth Printing.

Loading…
Cancel
Save