diff --git a/.gitignore b/.gitignore index 0a12acfd7..a24cf9370 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ applet/ *~ *.orig *.rej +*.bak diff --git a/ArduinoAddons/Arduino_0.xx/Sanguino/boards.txt b/ArduinoAddons/Arduino_0.xx/Sanguino/boards.txt index f18a5ffa3..4e4d214b1 100644 --- a/ArduinoAddons/Arduino_0.xx/Sanguino/boards.txt +++ b/ArduinoAddons/Arduino_0.xx/Sanguino/boards.txt @@ -44,9 +44,9 @@ atmega12848m.upload.protocol=stk500 atmega12848m.upload.maximum_size=131072 atmega12848m.upload.speed=19200 -atmega12848m.bootloader.low_fuses=0xFD -atmega12848m.bootloader.high_fuses=0x9A -atmega12848m.bootloader.extended_fuses=0xFF +atmega12848m.bootloader.low_fuses=0xD6 +atmega12848m.bootloader.high_fuses=0xDA +atmega12848m.bootloader.extended_fuses=0xFD atmega12848m.bootloader.path=atmega atmega12848m.bootloader.file=ATmegaBOOT_168_atmega1284p_8m.hex atmega12848m.bootloader.unlock_bits=0x3F @@ -64,9 +64,9 @@ atmega1284.upload.protocol=stk500 atmega1284.upload.maximum_size=131072 atmega1284.upload.speed=57600 -atmega1284.bootloader.low_fuses=0xFF -atmega1284.bootloader.high_fuses=0x9A -atmega1284.bootloader.extended_fuses=0xFF +atmega1284.bootloader.low_fuses=0xD6 +atmega1284.bootloader.high_fuses=0xDA +atmega1284.bootloader.extended_fuses=0xFD atmega1284.bootloader.path=atmega atmega1284.bootloader.file=ATmegaBOOT_168_atmega1284p.hex atmega1284.bootloader.unlock_bits=0x3F @@ -85,9 +85,9 @@ atmega1284s.upload.protocol=stk500 atmega1284s.upload.maximum_size=131072 atmega1284s.upload.speed=57600 -atmega1284s.bootloader.low_fuses=0xFF -atmega1284s.bootloader.high_fuses=0x9A -atmega1284s.bootloader.extended_fuses=0xFF +atmega1284s.bootloader.low_fuses=0xD6 +atmega1284s.bootloader.high_fuses=0xDA +atmega1284s.bootloader.extended_fuses=0xFD atmega1284s.bootloader.path=atmega atmega1284s.bootloader.file=ATmegaBOOT_168_atmega1284p.hex atmega1284s.bootloader.unlock_bits=0x3F diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/boards.txt b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/boards.txt similarity index 65% rename from ArduinoAddons/Arduino_1.x.x/sanguino/boards.txt rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/boards.txt index ca2d74baf..2bec14eab 100644 --- a/ArduinoAddons/Arduino_1.x.x/sanguino/boards.txt +++ b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/boards.txt @@ -27,9 +27,9 @@ atmega12848m.upload.protocol=stk500 atmega12848m.upload.maximum_size=131072 atmega12848m.upload.speed=19200 -atmega12848m.bootloader.low_fuses=0xFD -atmega12848m.bootloader.high_fuses=0x9A -atmega12848m.bootloader.extended_fuses=0xFF +atmega1284.bootloader.low_fuses=0xD6 +atmega1284.bootloader.high_fuses=0xDA +atmega1284.bootloader.extended_fuses=0xFD atmega12848m.bootloader.path=atmega atmega12848m.bootloader.file=ATmegaBOOT_168_atmega1284p_8m.hex atmega12848m.bootloader.unlock_bits=0x3F @@ -48,9 +48,9 @@ atmega1284.upload.protocol=stk500 atmega1284.upload.maximum_size=131072 atmega1284.upload.speed=57600 -atmega1284.bootloader.low_fuses=0xFF -atmega1284.bootloader.high_fuses=0x9A -atmega1284.bootloader.extended_fuses=0xFF +atmega1284.bootloader.low_fuses=0xD6 +atmega1284.bootloader.high_fuses=0xDA +atmega1284.bootloader.extended_fuses=0xFD atmega1284.bootloader.path=atmega atmega1284.bootloader.file=ATmegaBOOT_168_atmega1284p.hex atmega1284.bootloader.unlock_bits=0x3F @@ -60,4 +60,24 @@ atmega1284.build.mcu=atmega1284p atmega1284.build.f_cpu=16000000L atmega1284.build.core=arduino atmega1284.build.variant=standard +############################################################## + +atmega1284m.name=Sanguino W/ ATmega1284p 20mhz + +atmega1284m.upload.protocol=stk500 +atmega1284m.upload.maximum_size=131072 +atmega1284m.upload.speed=57600 + +atmega1284m.bootloader.low_fuses=0xD6 +atmega1284m.bootloader.high_fuses=0xDA +atmega1284m.bootloader.extended_fuses=0xFD +atmega1284m.bootloader.path=atmega +atmega1284m.bootloader.file=ATmegaBOOT_168_atmega1284p.hex +atmega1284m.bootloader.unlock_bits=0x3F +atmega1284m.bootloader.lock_bits=0x0F + +atmega1284m.build.mcu=atmega1284p +atmega1284m.build.f_cpu=20000000L +atmega1284m.build.core=arduino +atmega1284m.build.variant=standard # diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/bootloaders/atmega/ATmegaBOOT_168.c b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/bootloaders/atmega/ATmegaBOOT_168.c similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/bootloaders/atmega/ATmegaBOOT_168.c rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/bootloaders/atmega/ATmegaBOOT_168.c diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/bootloaders/atmega/ATmegaBOOT_168_atmega1284p.hex b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/bootloaders/atmega/ATmegaBOOT_168_atmega1284p.hex similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/bootloaders/atmega/ATmegaBOOT_168_atmega1284p.hex rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/bootloaders/atmega/ATmegaBOOT_168_atmega1284p.hex diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/bootloaders/atmega/ATmegaBOOT_168_atmega1284p_8m.hex b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/bootloaders/atmega/ATmegaBOOT_168_atmega1284p_8m.hex similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/bootloaders/atmega/ATmegaBOOT_168_atmega1284p_8m.hex rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/bootloaders/atmega/ATmegaBOOT_168_atmega1284p_8m.hex diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/bootloaders/atmega/ATmegaBOOT_168_atmega644p.hex b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/bootloaders/atmega/ATmegaBOOT_168_atmega644p.hex similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/bootloaders/atmega/ATmegaBOOT_168_atmega644p.hex rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/bootloaders/atmega/ATmegaBOOT_168_atmega644p.hex diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/bootloaders/atmega/Makefile b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/bootloaders/atmega/Makefile similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/bootloaders/atmega/Makefile rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/bootloaders/atmega/Makefile diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/bootloaders/atmega644p/ATmegaBOOT.c b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/bootloaders/atmega644p/ATmegaBOOT.c similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/bootloaders/atmega644p/ATmegaBOOT.c rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/bootloaders/atmega644p/ATmegaBOOT.c diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/bootloaders/atmega644p/ATmegaBOOT.c.tst b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/bootloaders/atmega644p/ATmegaBOOT.c.tst similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/bootloaders/atmega644p/ATmegaBOOT.c.tst rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/bootloaders/atmega644p/ATmegaBOOT.c.tst diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/bootloaders/atmega644p/ATmegaBOOT_644P.elf b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/bootloaders/atmega644p/ATmegaBOOT_644P.elf similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/bootloaders/atmega644p/ATmegaBOOT_644P.elf rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/bootloaders/atmega644p/ATmegaBOOT_644P.elf diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/bootloaders/atmega644p/ATmegaBOOT_644P.hex b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/bootloaders/atmega644p/ATmegaBOOT_644P.hex similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/bootloaders/atmega644p/ATmegaBOOT_644P.hex rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/bootloaders/atmega644p/ATmegaBOOT_644P.hex diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/bootloaders/atmega644p/Makefile b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/bootloaders/atmega644p/Makefile similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/bootloaders/atmega644p/Makefile rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/bootloaders/atmega644p/Makefile diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/bootloaders/atmega644p/README.txt b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/bootloaders/atmega644p/README.txt similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/bootloaders/atmega644p/README.txt rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/bootloaders/atmega644p/README.txt diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/Arduino.h b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/Arduino.h similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/Arduino.h rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/Arduino.h diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/CDC.cpp b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/CDC.cpp similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/CDC.cpp rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/CDC.cpp diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/Client.h b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/Client.h similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/Client.h rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/Client.h diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/HID.cpp b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/HID.cpp similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/HID.cpp rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/HID.cpp diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/HardwareSerial.cpp b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/HardwareSerial.cpp similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/HardwareSerial.cpp rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/HardwareSerial.cpp diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/HardwareSerial.h b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/HardwareSerial.h similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/HardwareSerial.h rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/HardwareSerial.h diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/IPAddress.cpp b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/IPAddress.cpp similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/IPAddress.cpp rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/IPAddress.cpp diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/IPAddress.h b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/IPAddress.h similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/IPAddress.h rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/IPAddress.h diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/Platform.h b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/Platform.h similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/Platform.h rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/Platform.h diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/Print.cpp b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/Print.cpp similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/Print.cpp rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/Print.cpp diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/Print.h b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/Print.h similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/Print.h rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/Print.h diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/Printable.h b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/Printable.h similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/Printable.h rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/Printable.h diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/Server.h b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/Server.h similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/Server.h rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/Server.h diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/Stream.cpp b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/Stream.cpp similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/Stream.cpp rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/Stream.cpp diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/Stream.h b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/Stream.h similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/Stream.h rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/Stream.h diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/Tone.cpp b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/Tone.cpp similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/Tone.cpp rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/Tone.cpp diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/USBAPI.h b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/USBAPI.h similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/USBAPI.h rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/USBAPI.h diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/USBCore.cpp b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/USBCore.cpp similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/USBCore.cpp rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/USBCore.cpp diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/USBCore.h b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/USBCore.h similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/USBCore.h rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/USBCore.h diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/USBDesc.h b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/USBDesc.h similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/USBDesc.h rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/USBDesc.h diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/Udp.h b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/Udp.h similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/Udp.h rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/Udp.h diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/WCharacter.h b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/WCharacter.h similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/WCharacter.h rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/WCharacter.h diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/WInterrupts.c b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/WInterrupts.c similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/WInterrupts.c rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/WInterrupts.c diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/WMath.cpp b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/WMath.cpp similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/WMath.cpp rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/WMath.cpp diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/WString.cpp b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/WString.cpp similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/WString.cpp rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/WString.cpp diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/WString.h b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/WString.h similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/WString.h rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/WString.h diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/binary.h b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/binary.h similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/binary.h rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/binary.h diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/main.cpp b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/main.cpp similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/main.cpp rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/main.cpp diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/new.cpp b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/new.cpp similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/new.cpp rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/new.cpp diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/new.h b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/new.h similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/new.h rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/new.h diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/wiring.c b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/wiring.c similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/wiring.c rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/wiring.c diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/wiring_analog.c b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/wiring_analog.c similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/wiring_analog.c rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/wiring_analog.c diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/wiring_digital.c b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/wiring_digital.c similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/wiring_digital.c rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/wiring_digital.c diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/wiring_private.h b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/wiring_private.h similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/wiring_private.h rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/wiring_private.h diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/wiring_pulse.c b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/wiring_pulse.c similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/wiring_pulse.c rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/wiring_pulse.c diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/wiring_shift.c b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/wiring_shift.c similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/cores/arduino/wiring_shift.c rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/cores/arduino/wiring_shift.c diff --git a/ArduinoAddons/Arduino_1.x.x/sanguino/variants/standard/pins_arduino.h b/ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/variants/standard/pins_arduino.h similarity index 100% rename from ArduinoAddons/Arduino_1.x.x/sanguino/variants/standard/pins_arduino.h rename to ArduinoAddons/Arduino_1.x.x/hardware/Sanguino/variants/standard/pins_arduino.h diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/boards.txt b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/boards.txt new file mode 100644 index 000000000..d0901653c --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/boards.txt @@ -0,0 +1,22 @@ +# See: http://code.google.com/p/arduino/wiki/Platforms + +############################################################## + +mega2560.name=RAMBo + +mega2560.upload.protocol=wiring +mega2560.upload.maximum_size=258048 +mega2560.upload.speed=115200 + +mega2560.bootloader.low_fuses=0xFF +mega2560.bootloader.high_fuses=0xD8 +mega2560.bootloader.extended_fuses=0xFD +mega2560.bootloader.path=stk500v2 +mega2560.bootloader.file=stk500boot_v2_mega2560.hex +mega2560.bootloader.unlock_bits=0x3F +mega2560.bootloader.lock_bits=0x0F + +mega2560.build.mcu=atmega2560 +mega2560.build.f_cpu=16000000L +mega2560.build.core=arduino +mega2560.build.variant=standard diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Arduino.h b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Arduino.h new file mode 100644 index 000000000..b26582589 --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Arduino.h @@ -0,0 +1,215 @@ +#ifndef Arduino_h +#define Arduino_h + +#include +#include +#include + +#include +#include +#include + +#include "binary.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +#define HIGH 0x1 +#define LOW 0x0 + +#define INPUT 0x0 +#define OUTPUT 0x1 +#define INPUT_PULLUP 0x2 + +#define true 0x1 +#define false 0x0 + +#define PI 3.1415926535897932384626433832795 +#define HALF_PI 1.5707963267948966192313216916398 +#define TWO_PI 6.283185307179586476925286766559 +#define DEG_TO_RAD 0.017453292519943295769236907684886 +#define RAD_TO_DEG 57.295779513082320876798154814105 + +#define SERIAL 0x0 +#define DISPLAY 0x1 + +#define LSBFIRST 0 +#define MSBFIRST 1 + +#define CHANGE 1 +#define FALLING 2 +#define RISING 3 + +#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) +#define DEFAULT 0 +#define EXTERNAL 1 +#define INTERNAL 2 +#else +#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644P__) +#define INTERNAL1V1 2 +#define INTERNAL2V56 3 +#else +#define INTERNAL 3 +#endif +#define DEFAULT 1 +#define EXTERNAL 0 +#endif + +// undefine stdlib's abs if encountered +#ifdef abs +#undef abs +#endif + +#define min(a,b) ((a)<(b)?(a):(b)) +#define max(a,b) ((a)>(b)?(a):(b)) +#define abs(x) ((x)>0?(x):-(x)) +#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) +#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) +#define radians(deg) ((deg)*DEG_TO_RAD) +#define degrees(rad) ((rad)*RAD_TO_DEG) +#define sq(x) ((x)*(x)) + +#define interrupts() sei() +#define noInterrupts() cli() + +#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L ) +#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() ) +#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() ) + +#define lowByte(w) ((uint8_t) ((w) & 0xff)) +#define highByte(w) ((uint8_t) ((w) >> 8)) + +#define bitRead(value, bit) (((value) >> (bit)) & 0x01) +#define bitSet(value, bit) ((value) |= (1UL << (bit))) +#define bitClear(value, bit) ((value) &= ~(1UL << (bit))) +#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit)) + + +typedef unsigned int word; + +#define bit(b) (1UL << (b)) + +typedef uint8_t boolean; +typedef uint8_t byte; + +void init(void); + +void pinMode(uint8_t, uint8_t); +void digitalWrite(uint8_t, uint8_t); +int digitalRead(uint8_t); +int analogRead(uint8_t); +void analogReference(uint8_t mode); +void analogWrite(uint8_t, int); + +unsigned long millis(void); +unsigned long micros(void); +void delay(unsigned long); +void delayMicroseconds(unsigned int us); +unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout); + +void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val); +uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder); + +void attachInterrupt(uint8_t, void (*)(void), int mode); +void detachInterrupt(uint8_t); + +void setup(void); +void loop(void); + +// Get the bit location within the hardware port of the given virtual pin. +// This comes from the pins_*.c file for the active board configuration. + +#define analogInPinToBit(P) (P) + +// On the ATmega1280, the addresses of some of the port registers are +// greater than 255, so we can't store them in uint8_t's. +extern const uint16_t PROGMEM port_to_mode_PGM[]; +extern const uint16_t PROGMEM port_to_input_PGM[]; +extern const uint16_t PROGMEM port_to_output_PGM[]; + +extern const uint8_t PROGMEM digital_pin_to_port_PGM[]; +// extern const uint8_t PROGMEM digital_pin_to_bit_PGM[]; +extern const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[]; +extern const uint8_t PROGMEM digital_pin_to_timer_PGM[]; + +// Get the bit location within the hardware port of the given virtual pin. +// This comes from the pins_*.c file for the active board configuration. +// +// These perform slightly better as macros compared to inline functions +// +#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) ) +#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) ) +#define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) ) +#define analogInPinToBit(P) (P) +#define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) ) +#define portInputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + (P))) ) +#define portModeRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_mode_PGM + (P))) ) + +#define NOT_A_PIN 0 +#define NOT_A_PORT 0 + +#ifdef ARDUINO_MAIN +#define PA 1 +#define PB 2 +#define PC 3 +#define PD 4 +#define PE 5 +#define PF 6 +#define PG 7 +#define PH 8 +#define PJ 10 +#define PK 11 +#define PL 12 +#endif + +#define NOT_ON_TIMER 0 +#define TIMER0A 1 +#define TIMER0B 2 +#define TIMER1A 3 +#define TIMER1B 4 +#define TIMER2 5 +#define TIMER2A 6 +#define TIMER2B 7 + +#define TIMER3A 8 +#define TIMER3B 9 +#define TIMER3C 10 +#define TIMER4A 11 +#define TIMER4B 12 +#define TIMER4C 13 +#define TIMER4D 14 +#define TIMER5A 15 +#define TIMER5B 16 +#define TIMER5C 17 + +#ifdef __cplusplus +} // extern "C" +#endif + +#ifdef __cplusplus +#include "WCharacter.h" +#include "WString.h" +#include "HardwareSerial.h" + +uint16_t makeWord(uint16_t w); +uint16_t makeWord(byte h, byte l); + +#define word(...) makeWord(__VA_ARGS__) + +unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); + +void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0); +void noTone(uint8_t _pin); + +// WMath prototypes +long random(long); +long random(long, long); +void randomSeed(unsigned int); +long map(long, long, long, long, long); + +#endif + +#include "pins_arduino.h" + +#endif diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/CDC.cpp b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/CDC.cpp new file mode 100644 index 000000000..701e48398 --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/CDC.cpp @@ -0,0 +1,239 @@ + + +/* Copyright (c) 2011, Peter Barrett +** +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + +#include "Platform.h" +#include "USBAPI.h" +#include + +#if defined(USBCON) +#ifdef CDC_ENABLED + +#if (RAMEND < 1000) +#define SERIAL_BUFFER_SIZE 16 +#else +#define SERIAL_BUFFER_SIZE 64 +#endif + +struct ring_buffer +{ + unsigned char buffer[SERIAL_BUFFER_SIZE]; + volatile int head; + volatile int tail; +}; + +ring_buffer cdc_rx_buffer = { { 0 }, 0, 0}; + +typedef struct +{ + u32 dwDTERate; + u8 bCharFormat; + u8 bParityType; + u8 bDataBits; + u8 lineState; +} LineInfo; + +static volatile LineInfo _usbLineInfo = { 57600, 0x00, 0x00, 0x00, 0x00 }; + +#define WEAK __attribute__ ((weak)) + +extern const CDCDescriptor _cdcInterface PROGMEM; +const CDCDescriptor _cdcInterface = +{ + D_IAD(0,2,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,1), + + // CDC communication interface + D_INTERFACE(CDC_ACM_INTERFACE,1,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,0), + D_CDCCS(CDC_HEADER,0x10,0x01), // Header (1.10 bcd) + D_CDCCS(CDC_CALL_MANAGEMENT,1,1), // Device handles call management (not) + D_CDCCS4(CDC_ABSTRACT_CONTROL_MANAGEMENT,6), // SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported + D_CDCCS(CDC_UNION,CDC_ACM_INTERFACE,CDC_DATA_INTERFACE), // Communication interface is master, data interface is slave 0 + D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_ACM),USB_ENDPOINT_TYPE_INTERRUPT,0x10,0x40), + + // CDC data interface + D_INTERFACE(CDC_DATA_INTERFACE,2,CDC_DATA_INTERFACE_CLASS,0,0), + D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,0x40,0), + D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,0x40,0) +}; + +int WEAK CDC_GetInterface(u8* interfaceNum) +{ + interfaceNum[0] += 2; // uses 2 + return USB_SendControl(TRANSFER_PGM,&_cdcInterface,sizeof(_cdcInterface)); +} + +bool WEAK CDC_Setup(Setup& setup) +{ + u8 r = setup.bRequest; + u8 requestType = setup.bmRequestType; + + if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType) + { + if (CDC_GET_LINE_CODING == r) + { + USB_SendControl(0,(void*)&_usbLineInfo,7); + return true; + } + } + + if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType) + { + if (CDC_SET_LINE_CODING == r) + { + USB_RecvControl((void*)&_usbLineInfo,7); + return true; + } + + if (CDC_SET_CONTROL_LINE_STATE == r) + { + _usbLineInfo.lineState = setup.wValueL; + + // auto-reset into the bootloader is triggered when the port, already + // open at 1200 bps, is closed. this is the signal to start the watchdog + // with a relatively long period so it can finish housekeeping tasks + // like servicing endpoints before the sketch ends + if (1200 == _usbLineInfo.dwDTERate) { + // We check DTR state to determine if host port is open (bit 0 of lineState). + if ((_usbLineInfo.lineState & 0x01) == 0) { + *(uint16_t *)0x0800 = 0x7777; + wdt_enable(WDTO_120MS); + } else { + // Most OSs do some intermediate steps when configuring ports and DTR can + // twiggle more than once before stabilizing. + // To avoid spurious resets we set the watchdog to 250ms and eventually + // cancel if DTR goes back high. + + wdt_disable(); + wdt_reset(); + *(uint16_t *)0x0800 = 0x0; + } + } + return true; + } + } + return false; +} + + +int _serialPeek = -1; +void Serial_::begin(uint16_t baud_count) +{ +} + +void Serial_::end(void) +{ +} + +void Serial_::accept(void) +{ + ring_buffer *buffer = &cdc_rx_buffer; + int i = (unsigned int)(buffer->head+1) % SERIAL_BUFFER_SIZE; + + // if we should be storing the received character into the location + // just before the tail (meaning that the head would advance to the + // current location of the tail), we're about to overflow the buffer + // and so we don't write the character or advance the head. + + // while we have room to store a byte + while (i != buffer->tail) { + int c = USB_Recv(CDC_RX); + if (c == -1) + break; // no more data + buffer->buffer[buffer->head] = c; + buffer->head = i; + + i = (unsigned int)(buffer->head+1) % SERIAL_BUFFER_SIZE; + } +} + +int Serial_::available(void) +{ + ring_buffer *buffer = &cdc_rx_buffer; + return (unsigned int)(SERIAL_BUFFER_SIZE + buffer->head - buffer->tail) % SERIAL_BUFFER_SIZE; +} + +int Serial_::peek(void) +{ + ring_buffer *buffer = &cdc_rx_buffer; + if (buffer->head == buffer->tail) { + return -1; + } else { + return buffer->buffer[buffer->tail]; + } +} + +int Serial_::read(void) +{ + ring_buffer *buffer = &cdc_rx_buffer; + // if the head isn't ahead of the tail, we don't have any characters + if (buffer->head == buffer->tail) { + return -1; + } else { + unsigned char c = buffer->buffer[buffer->tail]; + buffer->tail = (unsigned int)(buffer->tail + 1) % SERIAL_BUFFER_SIZE; + return c; + } +} + +void Serial_::flush(void) +{ + USB_Flush(CDC_TX); +} + +size_t Serial_::write(uint8_t c) +{ + /* only try to send bytes if the high-level CDC connection itself + is open (not just the pipe) - the OS should set lineState when the port + is opened and clear lineState when the port is closed. + bytes sent before the user opens the connection or after + the connection is closed are lost - just like with a UART. */ + + // TODO - ZE - check behavior on different OSes and test what happens if an + // open connection isn't broken cleanly (cable is yanked out, host dies + // or locks up, or host virtual serial port hangs) + if (_usbLineInfo.lineState > 0) { + int r = USB_Send(CDC_TX,&c,1); + if (r > 0) { + return r; + } else { + setWriteError(); + return 0; + } + } + setWriteError(); + return 0; +} + +// This operator is a convenient way for a sketch to check whether the +// port has actually been configured and opened by the host (as opposed +// to just being connected to the host). It can be used, for example, in +// setup() before printing to ensure that an application on the host is +// actually ready to receive and display the data. +// We add a short delay before returning to fix a bug observed by Federico +// where the port is configured (lineState != 0) but not quite opened. +Serial_::operator bool() { + bool result = false; + if (_usbLineInfo.lineState > 0) + result = true; + delay(10); + return result; +} + +Serial_ Serial; + +#endif +#endif /* if defined(USBCON) */ diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Client.h b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Client.h new file mode 100644 index 000000000..ea134838a --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Client.h @@ -0,0 +1,26 @@ +#ifndef client_h +#define client_h +#include "Print.h" +#include "Stream.h" +#include "IPAddress.h" + +class Client : public Stream { + +public: + virtual int connect(IPAddress ip, uint16_t port) =0; + virtual int connect(const char *host, uint16_t port) =0; + virtual size_t write(uint8_t) =0; + virtual size_t write(const uint8_t *buf, size_t size) =0; + virtual int available() = 0; + virtual int read() = 0; + virtual int read(uint8_t *buf, size_t size) = 0; + virtual int peek() = 0; + virtual void flush() = 0; + virtual void stop() = 0; + virtual uint8_t connected() = 0; + virtual operator bool() = 0; +protected: + uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); }; +}; + +#endif diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/HID.cpp b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/HID.cpp new file mode 100644 index 000000000..ac6360844 --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/HID.cpp @@ -0,0 +1,520 @@ + + +/* Copyright (c) 2011, Peter Barrett +** +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + +#include "Platform.h" +#include "USBAPI.h" +#include "USBDesc.h" + +#if defined(USBCON) +#ifdef HID_ENABLED + +//#define RAWHID_ENABLED + +// Singletons for mouse and keyboard + +Mouse_ Mouse; +Keyboard_ Keyboard; + +//================================================================================ +//================================================================================ + +// HID report descriptor + +#define LSB(_x) ((_x) & 0xFF) +#define MSB(_x) ((_x) >> 8) + +#define RAWHID_USAGE_PAGE 0xFFC0 +#define RAWHID_USAGE 0x0C00 +#define RAWHID_TX_SIZE 64 +#define RAWHID_RX_SIZE 64 + +extern const u8 _hidReportDescriptor[] PROGMEM; +const u8 _hidReportDescriptor[] = { + + // Mouse + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 54 + 0x09, 0x02, // USAGE (Mouse) + 0xa1, 0x01, // COLLECTION (Application) + 0x09, 0x01, // USAGE (Pointer) + 0xa1, 0x00, // COLLECTION (Physical) + 0x85, 0x01, // REPORT_ID (1) + 0x05, 0x09, // USAGE_PAGE (Button) + 0x19, 0x01, // USAGE_MINIMUM (Button 1) + 0x29, 0x03, // USAGE_MAXIMUM (Button 3) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x95, 0x03, // REPORT_COUNT (3) + 0x75, 0x01, // REPORT_SIZE (1) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x95, 0x01, // REPORT_COUNT (1) + 0x75, 0x05, // REPORT_SIZE (5) + 0x81, 0x03, // INPUT (Cnst,Var,Abs) + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x30, // USAGE (X) + 0x09, 0x31, // USAGE (Y) + 0x09, 0x38, // USAGE (Wheel) + 0x15, 0x81, // LOGICAL_MINIMUM (-127) + 0x25, 0x7f, // LOGICAL_MAXIMUM (127) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x03, // REPORT_COUNT (3) + 0x81, 0x06, // INPUT (Data,Var,Rel) + 0xc0, // END_COLLECTION + 0xc0, // END_COLLECTION + + // Keyboard + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 47 + 0x09, 0x06, // USAGE (Keyboard) + 0xa1, 0x01, // COLLECTION (Application) + 0x85, 0x02, // REPORT_ID (2) + 0x05, 0x07, // USAGE_PAGE (Keyboard) + + 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl) + 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x75, 0x01, // REPORT_SIZE (1) + + 0x95, 0x08, // REPORT_COUNT (8) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x95, 0x01, // REPORT_COUNT (1) + 0x75, 0x08, // REPORT_SIZE (8) + 0x81, 0x03, // INPUT (Cnst,Var,Abs) + + 0x95, 0x06, // REPORT_COUNT (6) + 0x75, 0x08, // REPORT_SIZE (8) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x65, // LOGICAL_MAXIMUM (101) + 0x05, 0x07, // USAGE_PAGE (Keyboard) + + 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated)) + 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application) + 0x81, 0x00, // INPUT (Data,Ary,Abs) + 0xc0, // END_COLLECTION + +#if RAWHID_ENABLED + // RAW HID + 0x06, LSB(RAWHID_USAGE_PAGE), MSB(RAWHID_USAGE_PAGE), // 30 + 0x0A, LSB(RAWHID_USAGE), MSB(RAWHID_USAGE), + + 0xA1, 0x01, // Collection 0x01 + 0x85, 0x03, // REPORT_ID (3) + 0x75, 0x08, // report size = 8 bits + 0x15, 0x00, // logical minimum = 0 + 0x26, 0xFF, 0x00, // logical maximum = 255 + + 0x95, 64, // report count TX + 0x09, 0x01, // usage + 0x81, 0x02, // Input (array) + + 0x95, 64, // report count RX + 0x09, 0x02, // usage + 0x91, 0x02, // Output (array) + 0xC0 // end collection +#endif +}; + +extern const HIDDescriptor _hidInterface PROGMEM; +const HIDDescriptor _hidInterface = +{ + D_INTERFACE(HID_INTERFACE,1,3,0,0), + D_HIDREPORT(sizeof(_hidReportDescriptor)), + D_ENDPOINT(USB_ENDPOINT_IN (HID_ENDPOINT_INT),USB_ENDPOINT_TYPE_INTERRUPT,0x40,0x01) +}; + +//================================================================================ +//================================================================================ +// Driver + +u8 _hid_protocol = 1; +u8 _hid_idle = 1; + +#define WEAK __attribute__ ((weak)) + +int WEAK HID_GetInterface(u8* interfaceNum) +{ + interfaceNum[0] += 1; // uses 1 + return USB_SendControl(TRANSFER_PGM,&_hidInterface,sizeof(_hidInterface)); +} + +int WEAK HID_GetDescriptor(int i) +{ + return USB_SendControl(TRANSFER_PGM,_hidReportDescriptor,sizeof(_hidReportDescriptor)); +} + +void WEAK HID_SendReport(u8 id, const void* data, int len) +{ + USB_Send(HID_TX, &id, 1); + USB_Send(HID_TX | TRANSFER_RELEASE,data,len); +} + +bool WEAK HID_Setup(Setup& setup) +{ + u8 r = setup.bRequest; + u8 requestType = setup.bmRequestType; + if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType) + { + if (HID_GET_REPORT == r) + { + //HID_GetReport(); + return true; + } + if (HID_GET_PROTOCOL == r) + { + //Send8(_hid_protocol); // TODO + return true; + } + } + + if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType) + { + if (HID_SET_PROTOCOL == r) + { + _hid_protocol = setup.wValueL; + return true; + } + + if (HID_SET_IDLE == r) + { + _hid_idle = setup.wValueL; + return true; + } + } + return false; +} + +//================================================================================ +//================================================================================ +// Mouse + +Mouse_::Mouse_(void) : _buttons(0) +{ +} + +void Mouse_::begin(void) +{ +} + +void Mouse_::end(void) +{ +} + +void Mouse_::click(uint8_t b) +{ + _buttons = b; + move(0,0,0); + _buttons = 0; + move(0,0,0); +} + +void Mouse_::move(signed char x, signed char y, signed char wheel) +{ + u8 m[4]; + m[0] = _buttons; + m[1] = x; + m[2] = y; + m[3] = wheel; + HID_SendReport(1,m,4); +} + +void Mouse_::buttons(uint8_t b) +{ + if (b != _buttons) + { + _buttons = b; + move(0,0,0); + } +} + +void Mouse_::press(uint8_t b) +{ + buttons(_buttons | b); +} + +void Mouse_::release(uint8_t b) +{ + buttons(_buttons & ~b); +} + +bool Mouse_::isPressed(uint8_t b) +{ + if ((b & _buttons) > 0) + return true; + return false; +} + +//================================================================================ +//================================================================================ +// Keyboard + +Keyboard_::Keyboard_(void) +{ +} + +void Keyboard_::begin(void) +{ +} + +void Keyboard_::end(void) +{ +} + +void Keyboard_::sendReport(KeyReport* keys) +{ + HID_SendReport(2,keys,sizeof(KeyReport)); +} + +extern +const uint8_t _asciimap[128] PROGMEM; + +#define SHIFT 0x80 +const uint8_t _asciimap[128] = +{ + 0x00, // NUL + 0x00, // SOH + 0x00, // STX + 0x00, // ETX + 0x00, // EOT + 0x00, // ENQ + 0x00, // ACK + 0x00, // BEL + 0x2a, // BS Backspace + 0x2b, // TAB Tab + 0x28, // LF Enter + 0x00, // VT + 0x00, // FF + 0x00, // CR + 0x00, // SO + 0x00, // SI + 0x00, // DEL + 0x00, // DC1 + 0x00, // DC2 + 0x00, // DC3 + 0x00, // DC4 + 0x00, // NAK + 0x00, // SYN + 0x00, // ETB + 0x00, // CAN + 0x00, // EM + 0x00, // SUB + 0x00, // ESC + 0x00, // FS + 0x00, // GS + 0x00, // RS + 0x00, // US + + 0x2c, // ' ' + 0x1e|SHIFT, // ! + 0x34|SHIFT, // " + 0x20|SHIFT, // # + 0x21|SHIFT, // $ + 0x22|SHIFT, // % + 0x24|SHIFT, // & + 0x34, // ' + 0x26|SHIFT, // ( + 0x27|SHIFT, // ) + 0x25|SHIFT, // * + 0x2e|SHIFT, // + + 0x36, // , + 0x2d, // - + 0x37, // . + 0x38, // / + 0x27, // 0 + 0x1e, // 1 + 0x1f, // 2 + 0x20, // 3 + 0x21, // 4 + 0x22, // 5 + 0x23, // 6 + 0x24, // 7 + 0x25, // 8 + 0x26, // 9 + 0x33|SHIFT, // : + 0x33, // ; + 0x36|SHIFT, // < + 0x2e, // = + 0x37|SHIFT, // > + 0x38|SHIFT, // ? + 0x1f|SHIFT, // @ + 0x04|SHIFT, // A + 0x05|SHIFT, // B + 0x06|SHIFT, // C + 0x07|SHIFT, // D + 0x08|SHIFT, // E + 0x09|SHIFT, // F + 0x0a|SHIFT, // G + 0x0b|SHIFT, // H + 0x0c|SHIFT, // I + 0x0d|SHIFT, // J + 0x0e|SHIFT, // K + 0x0f|SHIFT, // L + 0x10|SHIFT, // M + 0x11|SHIFT, // N + 0x12|SHIFT, // O + 0x13|SHIFT, // P + 0x14|SHIFT, // Q + 0x15|SHIFT, // R + 0x16|SHIFT, // S + 0x17|SHIFT, // T + 0x18|SHIFT, // U + 0x19|SHIFT, // V + 0x1a|SHIFT, // W + 0x1b|SHIFT, // X + 0x1c|SHIFT, // Y + 0x1d|SHIFT, // Z + 0x2f, // [ + 0x31, // bslash + 0x30, // ] + 0x23|SHIFT, // ^ + 0x2d|SHIFT, // _ + 0x35, // ` + 0x04, // a + 0x05, // b + 0x06, // c + 0x07, // d + 0x08, // e + 0x09, // f + 0x0a, // g + 0x0b, // h + 0x0c, // i + 0x0d, // j + 0x0e, // k + 0x0f, // l + 0x10, // m + 0x11, // n + 0x12, // o + 0x13, // p + 0x14, // q + 0x15, // r + 0x16, // s + 0x17, // t + 0x18, // u + 0x19, // v + 0x1a, // w + 0x1b, // x + 0x1c, // y + 0x1d, // z + 0x2f|SHIFT, // + 0x31|SHIFT, // | + 0x30|SHIFT, // } + 0x35|SHIFT, // ~ + 0 // DEL +}; + +uint8_t USBPutChar(uint8_t c); + +// press() adds the specified key (printing, non-printing, or modifier) +// to the persistent key report and sends the report. Because of the way +// USB HID works, the host acts like the key remains pressed until we +// call release(), releaseAll(), or otherwise clear the report and resend. +size_t Keyboard_::press(uint8_t k) +{ + uint8_t i; + if (k >= 136) { // it's a non-printing key (not a modifier) + k = k - 136; + } else if (k >= 128) { // it's a modifier key + _keyReport.modifiers |= (1<<(k-128)); + k = 0; + } else { // it's a printing key + k = pgm_read_byte(_asciimap + k); + if (!k) { + setWriteError(); + return 0; + } + if (k & 0x80) { // it's a capital letter or other character reached with shift + _keyReport.modifiers |= 0x02; // the left shift modifier + k &= 0x7F; + } + } + + // Add k to the key report only if it's not already present + // and if there is an empty slot. + if (_keyReport.keys[0] != k && _keyReport.keys[1] != k && + _keyReport.keys[2] != k && _keyReport.keys[3] != k && + _keyReport.keys[4] != k && _keyReport.keys[5] != k) { + + for (i=0; i<6; i++) { + if (_keyReport.keys[i] == 0x00) { + _keyReport.keys[i] = k; + break; + } + } + if (i == 6) { + setWriteError(); + return 0; + } + } + sendReport(&_keyReport); + return 1; +} + +// release() takes the specified key out of the persistent key report and +// sends the report. This tells the OS the key is no longer pressed and that +// it shouldn't be repeated any more. +size_t Keyboard_::release(uint8_t k) +{ + uint8_t i; + if (k >= 136) { // it's a non-printing key (not a modifier) + k = k - 136; + } else if (k >= 128) { // it's a modifier key + _keyReport.modifiers &= ~(1<<(k-128)); + k = 0; + } else { // it's a printing key + k = pgm_read_byte(_asciimap + k); + if (!k) { + return 0; + } + if (k & 0x80) { // it's a capital letter or other character reached with shift + _keyReport.modifiers &= ~(0x02); // the left shift modifier + k &= 0x7F; + } + } + + // Test the key report to see if k is present. Clear it if it exists. + // Check all positions in case the key is present more than once (which it shouldn't be) + for (i=0; i<6; i++) { + if (0 != k && _keyReport.keys[i] == k) { + _keyReport.keys[i] = 0x00; + } + } + + sendReport(&_keyReport); + return 1; +} + +void Keyboard_::releaseAll(void) +{ + _keyReport.keys[0] = 0; + _keyReport.keys[1] = 0; + _keyReport.keys[2] = 0; + _keyReport.keys[3] = 0; + _keyReport.keys[4] = 0; + _keyReport.keys[5] = 0; + _keyReport.modifiers = 0; + sendReport(&_keyReport); +} + +size_t Keyboard_::write(uint8_t c) +{ + uint8_t p = press(c); // Keydown + uint8_t r = release(c); // Keyup + return (p); // just return the result of press() since release() almost always returns 1 +} + +#endif + +#endif /* if defined(USBCON) */ \ No newline at end of file diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/HardwareSerial.cpp b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/HardwareSerial.cpp new file mode 100644 index 000000000..794a7be89 --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/HardwareSerial.cpp @@ -0,0 +1,519 @@ +/* + HardwareSerial.cpp - Hardware serial library for Wiring + Copyright (c) 2006 Nicholas Zambetti. 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 + + Modified 23 November 2006 by David A. Mellis + Modified 28 September 2010 by Mark Sproul + Modified 14 August 2012 by Alarus +*/ + +#include +#include +#include +#include +#include "Arduino.h" +#include "wiring_private.h" + +// this next line disables the entire HardwareSerial.cpp, +// this is so I can support Attiny series and any other chip without a uart +#if defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H) + +#include "HardwareSerial.h" + +/* + * on ATmega8, the uart and its bits are not numbered, so there is no "TXC0" + * definition. + */ +#if !defined(TXC0) +#if defined(TXC) +#define TXC0 TXC +#elif defined(TXC1) +// Some devices have uart1 but no uart0 +#define TXC0 TXC1 +#else +#error TXC0 not definable in HardwareSerial.h +#endif +#endif + +// Define constants and variables for buffering incoming serial data. We're +// using a ring buffer (I think), in which head is the index of the location +// to which to write the next incoming character and tail is the index of the +// location from which to read. +#if (RAMEND < 1000) + #define SERIAL_BUFFER_SIZE 16 +#else + #define SERIAL_BUFFER_SIZE 64 +#endif + +struct ring_buffer +{ + unsigned char buffer[SERIAL_BUFFER_SIZE]; + volatile unsigned int head; + volatile unsigned int tail; +}; + +#if defined(USBCON) + ring_buffer rx_buffer = { { 0 }, 0, 0}; + ring_buffer tx_buffer = { { 0 }, 0, 0}; +#endif +#if defined(UBRRH) || defined(UBRR0H) + ring_buffer rx_buffer = { { 0 }, 0, 0 }; + ring_buffer tx_buffer = { { 0 }, 0, 0 }; +#endif +#if defined(UBRR1H) + ring_buffer rx_buffer1 = { { 0 }, 0, 0 }; + ring_buffer tx_buffer1 = { { 0 }, 0, 0 }; +#endif +#if defined(UBRR2H) + ring_buffer rx_buffer2 = { { 0 }, 0, 0 }; + ring_buffer tx_buffer2 = { { 0 }, 0, 0 }; +#endif +#if defined(UBRR3H) + ring_buffer rx_buffer3 = { { 0 }, 0, 0 }; + ring_buffer tx_buffer3 = { { 0 }, 0, 0 }; +#endif + +inline void store_char(unsigned char c, ring_buffer *buffer) +{ + int i = (unsigned int)(buffer->head + 1) % SERIAL_BUFFER_SIZE; + + // if we should be storing the received character into the location + // just before the tail (meaning that the head would advance to the + // current location of the tail), we're about to overflow the buffer + // and so we don't write the character or advance the head. + if (i != buffer->tail) { + buffer->buffer[buffer->head] = c; + buffer->head = i; + } +} + +#if !defined(USART0_RX_vect) && defined(USART1_RX_vect) +// do nothing - on the 32u4 the first USART is USART1 +#else +#if !defined(USART_RX_vect) && !defined(SIG_USART0_RECV) && \ + !defined(SIG_UART0_RECV) && !defined(USART0_RX_vect) && \ + !defined(SIG_UART_RECV) + #error "Don't know what the Data Received vector is called for the first UART" +#else + void serialEvent() __attribute__((weak)); + void serialEvent() {} + #define serialEvent_implemented +#if defined(USART_RX_vect) + SIGNAL(USART_RX_vect) +#elif defined(SIG_USART0_RECV) + SIGNAL(SIG_USART0_RECV) +#elif defined(SIG_UART0_RECV) + SIGNAL(SIG_UART0_RECV) +#elif defined(USART0_RX_vect) + SIGNAL(USART0_RX_vect) +#elif defined(SIG_UART_RECV) + SIGNAL(SIG_UART_RECV) +#endif + { + #if defined(UDR0) + if (bit_is_clear(UCSR0A, UPE0)) { + unsigned char c = UDR0; + store_char(c, &rx_buffer); + } else { + unsigned char c = UDR0; + }; + #elif defined(UDR) + if (bit_is_clear(UCSRA, PE)) { + unsigned char c = UDR; + store_char(c, &rx_buffer); + } else { + unsigned char c = UDR; + }; + #else + #error UDR not defined + #endif + } +#endif +#endif + +#if defined(USART1_RX_vect) + void serialEvent1() __attribute__((weak)); + void serialEvent1() {} + #define serialEvent1_implemented + SIGNAL(USART1_RX_vect) + { + if (bit_is_clear(UCSR1A, UPE1)) { + unsigned char c = UDR1; + store_char(c, &rx_buffer1); + } else { + unsigned char c = UDR1; + }; + } +#elif defined(SIG_USART1_RECV) + #error SIG_USART1_RECV +#endif + +#if defined(USART2_RX_vect) && defined(UDR2) + void serialEvent2() __attribute__((weak)); + void serialEvent2() {} + #define serialEvent2_implemented + SIGNAL(USART2_RX_vect) + { + if (bit_is_clear(UCSR2A, UPE2)) { + unsigned char c = UDR2; + store_char(c, &rx_buffer2); + } else { + unsigned char c = UDR2; + }; + } +#elif defined(SIG_USART2_RECV) + #error SIG_USART2_RECV +#endif + +#if defined(USART3_RX_vect) && defined(UDR3) + void serialEvent3() __attribute__((weak)); + void serialEvent3() {} + #define serialEvent3_implemented + SIGNAL(USART3_RX_vect) + { + if (bit_is_clear(UCSR3A, UPE3)) { + unsigned char c = UDR3; + store_char(c, &rx_buffer3); + } else { + unsigned char c = UDR3; + }; + } +#elif defined(SIG_USART3_RECV) + #error SIG_USART3_RECV +#endif + +void serialEventRun(void) +{ +#ifdef serialEvent_implemented + if (Serial.available()) serialEvent(); +#endif +#ifdef serialEvent1_implemented + if (Serial1.available()) serialEvent1(); +#endif +#ifdef serialEvent2_implemented + if (Serial2.available()) serialEvent2(); +#endif +#ifdef serialEvent3_implemented + if (Serial3.available()) serialEvent3(); +#endif +} + + +#if !defined(USART0_UDRE_vect) && defined(USART1_UDRE_vect) +// do nothing - on the 32u4 the first USART is USART1 +#else +#if !defined(UART0_UDRE_vect) && !defined(UART_UDRE_vect) && !defined(USART0_UDRE_vect) && !defined(USART_UDRE_vect) + #error "Don't know what the Data Register Empty vector is called for the first UART" +#else +#if defined(UART0_UDRE_vect) +ISR(UART0_UDRE_vect) +#elif defined(UART_UDRE_vect) +ISR(UART_UDRE_vect) +#elif defined(USART0_UDRE_vect) +ISR(USART0_UDRE_vect) +#elif defined(USART_UDRE_vect) +ISR(USART_UDRE_vect) +#endif +{ + if (tx_buffer.head == tx_buffer.tail) { + // Buffer empty, so disable interrupts +#if defined(UCSR0B) + cbi(UCSR0B, UDRIE0); +#else + cbi(UCSRB, UDRIE); +#endif + } + else { + // There is more data in the output buffer. Send the next byte + unsigned char c = tx_buffer.buffer[tx_buffer.tail]; + tx_buffer.tail = (tx_buffer.tail + 1) % SERIAL_BUFFER_SIZE; + + #if defined(UDR0) + UDR0 = c; + #elif defined(UDR) + UDR = c; + #else + #error UDR not defined + #endif + } +} +#endif +#endif + +#ifdef USART1_UDRE_vect +ISR(USART1_UDRE_vect) +{ + if (tx_buffer1.head == tx_buffer1.tail) { + // Buffer empty, so disable interrupts + cbi(UCSR1B, UDRIE1); + } + else { + // There is more data in the output buffer. Send the next byte + unsigned char c = tx_buffer1.buffer[tx_buffer1.tail]; + tx_buffer1.tail = (tx_buffer1.tail + 1) % SERIAL_BUFFER_SIZE; + + UDR1 = c; + } +} +#endif + +#ifdef USART2_UDRE_vect +ISR(USART2_UDRE_vect) +{ + if (tx_buffer2.head == tx_buffer2.tail) { + // Buffer empty, so disable interrupts + cbi(UCSR2B, UDRIE2); + } + else { + // There is more data in the output buffer. Send the next byte + unsigned char c = tx_buffer2.buffer[tx_buffer2.tail]; + tx_buffer2.tail = (tx_buffer2.tail + 1) % SERIAL_BUFFER_SIZE; + + UDR2 = c; + } +} +#endif + +#ifdef USART3_UDRE_vect +ISR(USART3_UDRE_vect) +{ + if (tx_buffer3.head == tx_buffer3.tail) { + // Buffer empty, so disable interrupts + cbi(UCSR3B, UDRIE3); + } + else { + // There is more data in the output buffer. Send the next byte + unsigned char c = tx_buffer3.buffer[tx_buffer3.tail]; + tx_buffer3.tail = (tx_buffer3.tail + 1) % SERIAL_BUFFER_SIZE; + + UDR3 = c; + } +} +#endif + + +// Constructors //////////////////////////////////////////////////////////////// + +HardwareSerial::HardwareSerial(ring_buffer *rx_buffer, ring_buffer *tx_buffer, + volatile uint8_t *ubrrh, volatile uint8_t *ubrrl, + volatile uint8_t *ucsra, volatile uint8_t *ucsrb, + volatile uint8_t *ucsrc, volatile uint8_t *udr, + uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udrie, uint8_t u2x) +{ + _rx_buffer = rx_buffer; + _tx_buffer = tx_buffer; + _ubrrh = ubrrh; + _ubrrl = ubrrl; + _ucsra = ucsra; + _ucsrb = ucsrb; + _ucsrc = ucsrc; + _udr = udr; + _rxen = rxen; + _txen = txen; + _rxcie = rxcie; + _udrie = udrie; + _u2x = u2x; +} + +// Public Methods ////////////////////////////////////////////////////////////// + +void HardwareSerial::begin(unsigned long baud) +{ + uint16_t baud_setting; + bool use_u2x = true; + +#if F_CPU == 16000000UL + // hardcoded exception for compatibility with the bootloader shipped + // with the Duemilanove and previous boards and the firmware on the 8U2 + // on the Uno and Mega 2560. + if (baud == 57600) { + use_u2x = false; + } +#endif + +try_again: + + if (use_u2x) { + *_ucsra = 1 << _u2x; + baud_setting = (F_CPU / 4 / baud - 1) / 2; + } else { + *_ucsra = 0; + baud_setting = (F_CPU / 8 / baud - 1) / 2; + } + + if ((baud_setting > 4095) && use_u2x) + { + use_u2x = false; + goto try_again; + } + + // assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register) + *_ubrrh = baud_setting >> 8; + *_ubrrl = baud_setting; + + transmitting = false; + + sbi(*_ucsrb, _rxen); + sbi(*_ucsrb, _txen); + sbi(*_ucsrb, _rxcie); + cbi(*_ucsrb, _udrie); +} + +void HardwareSerial::begin(unsigned long baud, byte config) +{ + uint16_t baud_setting; + uint8_t current_config; + bool use_u2x = true; + +#if F_CPU == 16000000UL + // hardcoded exception for compatibility with the bootloader shipped + // with the Duemilanove and previous boards and the firmware on the 8U2 + // on the Uno and Mega 2560. + if (baud == 57600) { + use_u2x = false; + } +#endif + +try_again: + + if (use_u2x) { + *_ucsra = 1 << _u2x; + baud_setting = (F_CPU / 4 / baud - 1) / 2; + } else { + *_ucsra = 0; + baud_setting = (F_CPU / 8 / baud - 1) / 2; + } + + if ((baud_setting > 4095) && use_u2x) + { + use_u2x = false; + goto try_again; + } + + // assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register) + *_ubrrh = baud_setting >> 8; + *_ubrrl = baud_setting; + + //set the data bits, parity, and stop bits +#if defined(__AVR_ATmega8__) + config |= 0x80; // select UCSRC register (shared with UBRRH) +#endif + *_ucsrc = config; + + sbi(*_ucsrb, _rxen); + sbi(*_ucsrb, _txen); + sbi(*_ucsrb, _rxcie); + cbi(*_ucsrb, _udrie); +} + +void HardwareSerial::end() +{ + // wait for transmission of outgoing data + while (_tx_buffer->head != _tx_buffer->tail) + ; + + cbi(*_ucsrb, _rxen); + cbi(*_ucsrb, _txen); + cbi(*_ucsrb, _rxcie); + cbi(*_ucsrb, _udrie); + + // clear any received data + _rx_buffer->head = _rx_buffer->tail; +} + +int HardwareSerial::available(void) +{ + return (unsigned int)(SERIAL_BUFFER_SIZE + _rx_buffer->head - _rx_buffer->tail) % SERIAL_BUFFER_SIZE; +} + +int HardwareSerial::peek(void) +{ + if (_rx_buffer->head == _rx_buffer->tail) { + return -1; + } else { + return _rx_buffer->buffer[_rx_buffer->tail]; + } +} + +int HardwareSerial::read(void) +{ + // if the head isn't ahead of the tail, we don't have any characters + if (_rx_buffer->head == _rx_buffer->tail) { + return -1; + } else { + unsigned char c = _rx_buffer->buffer[_rx_buffer->tail]; + _rx_buffer->tail = (unsigned int)(_rx_buffer->tail + 1) % SERIAL_BUFFER_SIZE; + return c; + } +} + +void HardwareSerial::flush() +{ + // UDR is kept full while the buffer is not empty, so TXC triggers when EMPTY && SENT + while (transmitting && ! (*_ucsra & _BV(TXC0))); + transmitting = false; +} + +size_t HardwareSerial::write(uint8_t c) +{ + int i = (_tx_buffer->head + 1) % SERIAL_BUFFER_SIZE; + + // If the output buffer is full, there's nothing for it other than to + // wait for the interrupt handler to empty it a bit + // ???: return 0 here instead? + while (i == _tx_buffer->tail) + ; + + _tx_buffer->buffer[_tx_buffer->head] = c; + _tx_buffer->head = i; + + sbi(*_ucsrb, _udrie); + // clear the TXC bit -- "can be cleared by writing a one to its bit location" + transmitting = true; + sbi(*_ucsra, TXC0); + + return 1; +} + +HardwareSerial::operator bool() { + return true; +} + +// Preinstantiate Objects ////////////////////////////////////////////////////// + +#if defined(UBRRH) && defined(UBRRL) + HardwareSerial Serial(&rx_buffer, &tx_buffer, &UBRRH, &UBRRL, &UCSRA, &UCSRB, &UCSRC, &UDR, RXEN, TXEN, RXCIE, UDRIE, U2X); +#elif defined(UBRR0H) && defined(UBRR0L) + HardwareSerial Serial(&rx_buffer, &tx_buffer, &UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UCSR0C, &UDR0, RXEN0, TXEN0, RXCIE0, UDRIE0, U2X0); +#elif defined(USBCON) + // do nothing - Serial object and buffers are initialized in CDC code +#else + #error no serial port defined (port 0) +#endif + +#if defined(UBRR1H) + HardwareSerial Serial1(&rx_buffer1, &tx_buffer1, &UBRR1H, &UBRR1L, &UCSR1A, &UCSR1B, &UCSR1C, &UDR1, RXEN1, TXEN1, RXCIE1, UDRIE1, U2X1); +#endif +#if defined(UBRR2H) + HardwareSerial Serial2(&rx_buffer2, &tx_buffer2, &UBRR2H, &UBRR2L, &UCSR2A, &UCSR2B, &UCSR2C, &UDR2, RXEN2, TXEN2, RXCIE2, UDRIE2, U2X2); +#endif +#if defined(UBRR3H) + HardwareSerial Serial3(&rx_buffer3, &tx_buffer3, &UBRR3H, &UBRR3L, &UCSR3A, &UCSR3B, &UCSR3C, &UDR3, RXEN3, TXEN3, RXCIE3, UDRIE3, U2X3); +#endif + +#endif // whole file + diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/HardwareSerial.h b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/HardwareSerial.h new file mode 100644 index 000000000..a73117f56 --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/HardwareSerial.h @@ -0,0 +1,115 @@ +/* + HardwareSerial.h - Hardware serial library for Wiring + Copyright (c) 2006 Nicholas Zambetti. 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 + + Modified 28 September 2010 by Mark Sproul + Modified 14 August 2012 by Alarus +*/ + +#ifndef HardwareSerial_h +#define HardwareSerial_h + +#include + +#include "Stream.h" + +struct ring_buffer; + +class HardwareSerial : public Stream +{ + private: + ring_buffer *_rx_buffer; + ring_buffer *_tx_buffer; + volatile uint8_t *_ubrrh; + volatile uint8_t *_ubrrl; + volatile uint8_t *_ucsra; + volatile uint8_t *_ucsrb; + volatile uint8_t *_ucsrc; + volatile uint8_t *_udr; + uint8_t _rxen; + uint8_t _txen; + uint8_t _rxcie; + uint8_t _udrie; + uint8_t _u2x; + bool transmitting; + public: + HardwareSerial(ring_buffer *rx_buffer, ring_buffer *tx_buffer, + volatile uint8_t *ubrrh, volatile uint8_t *ubrrl, + volatile uint8_t *ucsra, volatile uint8_t *ucsrb, + volatile uint8_t *ucsrc, volatile uint8_t *udr, + uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udrie, uint8_t u2x); + void begin(unsigned long); + void begin(unsigned long, uint8_t); + void end(); + virtual int available(void); + virtual int peek(void); + virtual int read(void); + virtual void flush(void); + virtual size_t write(uint8_t); + inline size_t write(unsigned long n) { return write((uint8_t)n); } + inline size_t write(long n) { return write((uint8_t)n); } + inline size_t write(unsigned int n) { return write((uint8_t)n); } + inline size_t write(int n) { return write((uint8_t)n); } + using Print::write; // pull in write(str) and write(buf, size) from Print + operator bool(); +}; + +// Define config for Serial.begin(baud, config); +#define SERIAL_5N1 0x00 +#define SERIAL_6N1 0x02 +#define SERIAL_7N1 0x04 +#define SERIAL_8N1 0x06 +#define SERIAL_5N2 0x08 +#define SERIAL_6N2 0x0A +#define SERIAL_7N2 0x0C +#define SERIAL_8N2 0x0E +#define SERIAL_5E1 0x20 +#define SERIAL_6E1 0x22 +#define SERIAL_7E1 0x24 +#define SERIAL_8E1 0x26 +#define SERIAL_5E2 0x28 +#define SERIAL_6E2 0x2A +#define SERIAL_7E2 0x2C +#define SERIAL_8E2 0x2E +#define SERIAL_5O1 0x30 +#define SERIAL_6O1 0x32 +#define SERIAL_7O1 0x34 +#define SERIAL_8O1 0x36 +#define SERIAL_5O2 0x38 +#define SERIAL_6O2 0x3A +#define SERIAL_7O2 0x3C +#define SERIAL_8O2 0x3E + +#if defined(UBRRH) || defined(UBRR0H) + extern HardwareSerial Serial; +#elif defined(USBCON) + #include "USBAPI.h" +// extern HardwareSerial Serial_; +#endif +#if defined(UBRR1H) + extern HardwareSerial Serial1; +#endif +#if defined(UBRR2H) + extern HardwareSerial Serial2; +#endif +#if defined(UBRR3H) + extern HardwareSerial Serial3; +#endif + +extern void serialEventRun(void) __attribute__((weak)); + +#endif diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/IPAddress.cpp b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/IPAddress.cpp new file mode 100644 index 000000000..fe3deb77a --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/IPAddress.cpp @@ -0,0 +1,56 @@ + +#include +#include + +IPAddress::IPAddress() +{ + memset(_address, 0, sizeof(_address)); +} + +IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet) +{ + _address[0] = first_octet; + _address[1] = second_octet; + _address[2] = third_octet; + _address[3] = fourth_octet; +} + +IPAddress::IPAddress(uint32_t address) +{ + memcpy(_address, &address, sizeof(_address)); +} + +IPAddress::IPAddress(const uint8_t *address) +{ + memcpy(_address, address, sizeof(_address)); +} + +IPAddress& IPAddress::operator=(const uint8_t *address) +{ + memcpy(_address, address, sizeof(_address)); + return *this; +} + +IPAddress& IPAddress::operator=(uint32_t address) +{ + memcpy(_address, (const uint8_t *)&address, sizeof(_address)); + return *this; +} + +bool IPAddress::operator==(const uint8_t* addr) +{ + return memcmp(addr, _address, sizeof(_address)) == 0; +} + +size_t IPAddress::printTo(Print& p) const +{ + size_t n = 0; + for (int i =0; i < 3; i++) + { + n += p.print(_address[i], DEC); + n += p.print('.'); + } + n += p.print(_address[3], DEC); + return n; +} + diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/IPAddress.h b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/IPAddress.h new file mode 100644 index 000000000..2585aec0e --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/IPAddress.h @@ -0,0 +1,76 @@ +/* + * + * MIT License: + * Copyright (c) 2011 Adrian McEwen + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * adrianm@mcqn.com 1/1/2011 + */ + +#ifndef IPAddress_h +#define IPAddress_h + +#include + +// A class to make it easier to handle and pass around IP addresses + +class IPAddress : public Printable { +private: + uint8_t _address[4]; // IPv4 address + // Access the raw byte array containing the address. Because this returns a pointer + // to the internal structure rather than a copy of the address this function should only + // be used when you know that the usage of the returned uint8_t* will be transient and not + // stored. + uint8_t* raw_address() { return _address; }; + +public: + // Constructors + IPAddress(); + IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet); + IPAddress(uint32_t address); + IPAddress(const uint8_t *address); + + // Overloaded cast operator to allow IPAddress objects to be used where a pointer + // to a four-byte uint8_t array is expected + operator uint32_t() { return *((uint32_t*)_address); }; + bool operator==(const IPAddress& addr) { return (*((uint32_t*)_address)) == (*((uint32_t*)addr._address)); }; + bool operator==(const uint8_t* addr); + + // Overloaded index operator to allow getting and setting individual octets of the address + uint8_t operator[](int index) const { return _address[index]; }; + uint8_t& operator[](int index) { return _address[index]; }; + + // Overloaded copy operators to allow initialisation of IPAddress objects from other types + IPAddress& operator=(const uint8_t *address); + IPAddress& operator=(uint32_t address); + + virtual size_t printTo(Print& p) const; + + friend class EthernetClass; + friend class UDP; + friend class Client; + friend class Server; + friend class DhcpClass; + friend class DNSClient; +}; + +const IPAddress INADDR_NONE(0,0,0,0); + + +#endif diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Platform.h b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Platform.h new file mode 100644 index 000000000..8b8f74277 --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Platform.h @@ -0,0 +1,23 @@ + +#ifndef __PLATFORM_H__ +#define __PLATFORM_H__ + +#include +#include +#include +#include +#include + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned long u32; + +#include "Arduino.h" + +#if defined(USBCON) + #include "USBDesc.h" + #include "USBCore.h" + #include "USBAPI.h" +#endif /* if defined(USBCON) */ + +#endif diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Print.cpp b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Print.cpp new file mode 100644 index 000000000..53961ec47 --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Print.cpp @@ -0,0 +1,268 @@ +/* + Print.cpp - Base class that provides print() and println() + Copyright (c) 2008 David A. Mellis. 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 + + Modified 23 November 2006 by David A. Mellis + */ + +#include +#include +#include +#include +#include "Arduino.h" + +#include "Print.h" + +// Public Methods ////////////////////////////////////////////////////////////// + +/* default implementation: may be overridden */ +size_t Print::write(const uint8_t *buffer, size_t size) +{ + size_t n = 0; + while (size--) { + n += write(*buffer++); + } + return n; +} + +size_t Print::print(const __FlashStringHelper *ifsh) +{ + const char PROGMEM *p = (const char PROGMEM *)ifsh; + size_t n = 0; + while (1) { + unsigned char c = pgm_read_byte(p++); + if (c == 0) break; + n += write(c); + } + return n; +} + +size_t Print::print(const String &s) +{ + size_t n = 0; + for (uint16_t i = 0; i < s.length(); i++) { + n += write(s[i]); + } + return n; +} + +size_t Print::print(const char str[]) +{ + return write(str); +} + +size_t Print::print(char c) +{ + return write(c); +} + +size_t Print::print(unsigned char b, int base) +{ + return print((unsigned long) b, base); +} + +size_t Print::print(int n, int base) +{ + return print((long) n, base); +} + +size_t Print::print(unsigned int n, int base) +{ + return print((unsigned long) n, base); +} + +size_t Print::print(long n, int base) +{ + if (base == 0) { + return write(n); + } else if (base == 10) { + if (n < 0) { + int t = print('-'); + n = -n; + return printNumber(n, 10) + t; + } + return printNumber(n, 10); + } else { + return printNumber(n, base); + } +} + +size_t Print::print(unsigned long n, int base) +{ + if (base == 0) return write(n); + else return printNumber(n, base); +} + +size_t Print::print(double n, int digits) +{ + return printFloat(n, digits); +} + +size_t Print::println(const __FlashStringHelper *ifsh) +{ + size_t n = print(ifsh); + n += println(); + return n; +} + +size_t Print::print(const Printable& x) +{ + return x.printTo(*this); +} + +size_t Print::println(void) +{ + size_t n = print('\r'); + n += print('\n'); + return n; +} + +size_t Print::println(const String &s) +{ + size_t n = print(s); + n += println(); + return n; +} + +size_t Print::println(const char c[]) +{ + size_t n = print(c); + n += println(); + return n; +} + +size_t Print::println(char c) +{ + size_t n = print(c); + n += println(); + return n; +} + +size_t Print::println(unsigned char b, int base) +{ + size_t n = print(b, base); + n += println(); + return n; +} + +size_t Print::println(int num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(unsigned int num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(unsigned long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(double num, int digits) +{ + size_t n = print(num, digits); + n += println(); + return n; +} + +size_t Print::println(const Printable& x) +{ + size_t n = print(x); + n += println(); + return n; +} + +// Private Methods ///////////////////////////////////////////////////////////// + +size_t Print::printNumber(unsigned long n, uint8_t base) { + char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte. + char *str = &buf[sizeof(buf) - 1]; + + *str = '\0'; + + // prevent crash if called with base == 1 + if (base < 2) base = 10; + + do { + unsigned long m = n; + n /= base; + char c = m - base * n; + *--str = c < 10 ? c + '0' : c + 'A' - 10; + } while(n); + + return write(str); +} + +size_t Print::printFloat(double number, uint8_t digits) +{ + size_t n = 0; + + if (isnan(number)) return print("nan"); + if (isinf(number)) return print("inf"); + if (number > 4294967040.0) return print ("ovf"); // constant determined empirically + if (number <-4294967040.0) return print ("ovf"); // constant determined empirically + + // Handle negative numbers + if (number < 0.0) + { + n += print('-'); + number = -number; + } + + // Round correctly so that print(1.999, 2) prints as "2.00" + double rounding = 0.5; + for (uint8_t i=0; i 0) { + n += print("."); + } + + // Extract digits from the remainder one at a time + while (digits-- > 0) + { + remainder *= 10.0; + int toPrint = int(remainder); + n += print(toPrint); + remainder -= toPrint; + } + + return n; +} diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Print.h b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Print.h new file mode 100644 index 000000000..dc7615087 --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Print.h @@ -0,0 +1,81 @@ +/* + Print.h - Base class that provides print() and println() + Copyright (c) 2008 David A. Mellis. 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 +*/ + +#ifndef Print_h +#define Print_h + +#include +#include // for size_t + +#include "WString.h" +#include "Printable.h" + +#define DEC 10 +#define HEX 16 +#define OCT 8 +#define BIN 2 + +class Print +{ + private: + int write_error; + size_t printNumber(unsigned long, uint8_t); + size_t printFloat(double, uint8_t); + protected: + void setWriteError(int err = 1) { write_error = err; } + public: + Print() : write_error(0) {} + + int getWriteError() { return write_error; } + void clearWriteError() { setWriteError(0); } + + virtual size_t write(uint8_t) = 0; + size_t write(const char *str) { + if (str == NULL) return 0; + return write((const uint8_t *)str, strlen(str)); + } + virtual size_t write(const uint8_t *buffer, size_t size); + + size_t print(const __FlashStringHelper *); + size_t print(const String &); + size_t print(const char[]); + size_t print(char); + size_t print(unsigned char, int = DEC); + size_t print(int, int = DEC); + size_t print(unsigned int, int = DEC); + size_t print(long, int = DEC); + size_t print(unsigned long, int = DEC); + size_t print(double, int = 2); + size_t print(const Printable&); + + size_t println(const __FlashStringHelper *); + size_t println(const String &s); + size_t println(const char[]); + size_t println(char); + size_t println(unsigned char, int = DEC); + size_t println(int, int = DEC); + size_t println(unsigned int, int = DEC); + size_t println(long, int = DEC); + size_t println(unsigned long, int = DEC); + size_t println(double, int = 2); + size_t println(const Printable&); + size_t println(void); +}; + +#endif diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Printable.h b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Printable.h new file mode 100644 index 000000000..d03c9af62 --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Printable.h @@ -0,0 +1,40 @@ +/* + Printable.h - Interface class that allows printing of complex types + Copyright (c) 2011 Adrian McEwen. 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 +*/ + +#ifndef Printable_h +#define Printable_h + +#include + +class Print; + +/** The Printable class provides a way for new classes to allow themselves to be printed. + By deriving from Printable and implementing the printTo method, it will then be possible + for users to print out instances of this class by passing them into the usual + Print::print and Print::println methods. +*/ + +class Printable +{ + public: + virtual size_t printTo(Print& p) const = 0; +}; + +#endif + diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Server.h b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Server.h new file mode 100644 index 000000000..9674c7626 --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Server.h @@ -0,0 +1,9 @@ +#ifndef server_h +#define server_h + +class Server : public Print { +public: + virtual void begin() =0; +}; + +#endif diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Stream.cpp b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Stream.cpp new file mode 100644 index 000000000..aafb7fcf9 --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Stream.cpp @@ -0,0 +1,270 @@ +/* + Stream.cpp - adds parsing methods to Stream class + Copyright (c) 2008 David A. Mellis. 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 + + Created July 2011 + parsing functions based on TextFinder library by Michael Margolis + */ + +#include "Arduino.h" +#include "Stream.h" + +#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait +#define NO_SKIP_CHAR 1 // a magic char not found in a valid ASCII numeric field + +// private method to read stream with timeout +int Stream::timedRead() +{ + int c; + _startMillis = millis(); + do { + c = read(); + if (c >= 0) return c; + } while(millis() - _startMillis < _timeout); + return -1; // -1 indicates timeout +} + +// private method to peek stream with timeout +int Stream::timedPeek() +{ + int c; + _startMillis = millis(); + do { + c = peek(); + if (c >= 0) return c; + } while(millis() - _startMillis < _timeout); + return -1; // -1 indicates timeout +} + +// returns peek of the next digit in the stream or -1 if timeout +// discards non-numeric characters +int Stream::peekNextDigit() +{ + int c; + while (1) { + c = timedPeek(); + if (c < 0) return c; // timeout + if (c == '-') return c; + if (c >= '0' && c <= '9') return c; + read(); // discard non-numeric + } +} + +// Public Methods +////////////////////////////////////////////////////////////// + +void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait +{ + _timeout = timeout; +} + + // find returns true if the target string is found +bool Stream::find(char *target) +{ + return findUntil(target, NULL); +} + +// reads data from the stream until the target string of given length is found +// returns true if target string is found, false if timed out +bool Stream::find(char *target, size_t length) +{ + return findUntil(target, length, NULL, 0); +} + +// as find but search ends if the terminator string is found +bool Stream::findUntil(char *target, char *terminator) +{ + return findUntil(target, strlen(target), terminator, strlen(terminator)); +} + +// reads data from the stream until the target string of the given length is found +// search terminated if the terminator string is found +// returns true if target string is found, false if terminated or timed out +bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen) +{ + size_t index = 0; // maximum target string length is 64k bytes! + size_t termIndex = 0; + int c; + + if( *target == 0) + return true; // return true if target is a null string + while( (c = timedRead()) > 0){ + + if(c != target[index]) + index = 0; // reset index if any char does not match + + if( c == target[index]){ + //////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1); + if(++index >= targetLen){ // return true if all chars in the target match + return true; + } + } + + if(termLen > 0 && c == terminator[termIndex]){ + if(++termIndex >= termLen) + return false; // return false if terminate string found before target string + } + else + termIndex = 0; + } + return false; +} + + +// returns the first valid (long) integer value from the current position. +// initial characters that are not digits (or the minus sign) are skipped +// function is terminated by the first character that is not a digit. +long Stream::parseInt() +{ + return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout) +} + +// as above but a given skipChar is ignored +// this allows format characters (typically commas) in values to be ignored +long Stream::parseInt(char skipChar) +{ + boolean isNegative = false; + long value = 0; + int c; + + c = peekNextDigit(); + // ignore non numeric leading characters + if(c < 0) + return 0; // zero returned if timeout + + do{ + if(c == skipChar) + ; // ignore this charactor + else if(c == '-') + isNegative = true; + else if(c >= '0' && c <= '9') // is c a digit? + value = value * 10 + c - '0'; + read(); // consume the character we got with peek + c = timedPeek(); + } + while( (c >= '0' && c <= '9') || c == skipChar ); + + if(isNegative) + value = -value; + return value; +} + + +// as parseInt but returns a floating point value +float Stream::parseFloat() +{ + return parseFloat(NO_SKIP_CHAR); +} + +// as above but the given skipChar is ignored +// this allows format characters (typically commas) in values to be ignored +float Stream::parseFloat(char skipChar){ + boolean isNegative = false; + boolean isFraction = false; + long value = 0; + char c; + float fraction = 1.0; + + c = peekNextDigit(); + // ignore non numeric leading characters + if(c < 0) + return 0; // zero returned if timeout + + do{ + if(c == skipChar) + ; // ignore + else if(c == '-') + isNegative = true; + else if (c == '.') + isFraction = true; + else if(c >= '0' && c <= '9') { // is c a digit? + value = value * 10 + c - '0'; + if(isFraction) + fraction *= 0.1; + } + read(); // consume the character we got with peek + c = timedPeek(); + } + while( (c >= '0' && c <= '9') || c == '.' || c == skipChar ); + + if(isNegative) + value = -value; + if(isFraction) + return value * fraction; + else + return value; +} + +// read characters from stream into buffer +// terminates if length characters have been read, or timeout (see setTimeout) +// returns the number of characters placed in the buffer +// the buffer is NOT null terminated. +// +size_t Stream::readBytes(char *buffer, size_t length) +{ + size_t count = 0; + while (count < length) { + int c = timedRead(); + if (c < 0) break; + *buffer++ = (char)c; + count++; + } + return count; +} + + +// as readBytes with terminator character +// terminates if length characters have been read, timeout, or if the terminator character detected +// returns the number of characters placed in the buffer (0 means no valid data found) + +size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length) +{ + if (length < 1) return 0; + size_t index = 0; + while (index < length) { + int c = timedRead(); + if (c < 0 || c == terminator) break; + *buffer++ = (char)c; + index++; + } + return index; // return number of characters, not including null terminator +} + +String Stream::readString() +{ + String ret; + int c = timedRead(); + while (c >= 0) + { + ret += (char)c; + c = timedRead(); + } + return ret; +} + +String Stream::readStringUntil(char terminator) +{ + String ret; + int c = timedRead(); + while (c >= 0 && c != terminator) + { + ret += (char)c; + c = timedRead(); + } + return ret; +} + diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Stream.h b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Stream.h new file mode 100644 index 000000000..58bbf752f --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Stream.h @@ -0,0 +1,96 @@ +/* + Stream.h - base class for character-based streams. + Copyright (c) 2010 David A. Mellis. 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 + + parsing functions based on TextFinder library by Michael Margolis +*/ + +#ifndef Stream_h +#define Stream_h + +#include +#include "Print.h" + +// compatability macros for testing +/* +#define getInt() parseInt() +#define getInt(skipChar) parseInt(skipchar) +#define getFloat() parseFloat() +#define getFloat(skipChar) parseFloat(skipChar) +#define getString( pre_string, post_string, buffer, length) +readBytesBetween( pre_string, terminator, buffer, length) +*/ + +class Stream : public Print +{ + private: + unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read + unsigned long _startMillis; // used for timeout measurement + int timedRead(); // private method to read stream with timeout + int timedPeek(); // private method to peek stream with timeout + int peekNextDigit(); // returns the next numeric digit in the stream or -1 if timeout + + public: + virtual int available() = 0; + virtual int read() = 0; + virtual int peek() = 0; + virtual void flush() = 0; + + Stream() {_timeout=1000;} + +// parsing methods + + void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second + + bool find(char *target); // reads data from the stream until the target string is found + // returns true if target string is found, false if timed out (see setTimeout) + + bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found + // returns true if target string is found, false if timed out + + bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found + + bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found + + + long parseInt(); // returns the first valid (long) integer value from the current position. + // initial characters that are not digits (or the minus sign) are skipped + // integer is terminated by the first character that is not a digit. + + float parseFloat(); // float version of parseInt + + size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer + // terminates if length characters have been read or timeout (see setTimeout) + // returns the number of characters placed in the buffer (0 means no valid data found) + + size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character + // terminates if length characters have been read, timeout, or if the terminator character detected + // returns the number of characters placed in the buffer (0 means no valid data found) + + // Arduino String functions to be added here + String readString(); + String readStringUntil(char terminator); + + protected: + long parseInt(char skipChar); // as above but the given skipChar is ignored + // as above but the given skipChar is ignored + // this allows format characters (typically commas) in values to be ignored + + float parseFloat(char skipChar); // as above but the given skipChar is ignored +}; + +#endif diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Tone.cpp b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Tone.cpp new file mode 100644 index 000000000..9bb6fe721 --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Tone.cpp @@ -0,0 +1,616 @@ +/* Tone.cpp + + A Tone Generator Library + + Written by Brett Hagman + + 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 + +Version Modified By Date Comments +------- ----------- -------- -------- +0001 B Hagman 09/08/02 Initial coding +0002 B Hagman 09/08/18 Multiple pins +0003 B Hagman 09/08/18 Moved initialization from constructor to begin() +0004 B Hagman 09/09/26 Fixed problems with ATmega8 +0005 B Hagman 09/11/23 Scanned prescalars for best fit on 8 bit timers + 09/11/25 Changed pin toggle method to XOR + 09/11/25 Fixed timer0 from being excluded +0006 D Mellis 09/12/29 Replaced objects with functions +0007 M Sproul 10/08/29 Changed #ifdefs from cpu to register +0008 S Kanemoto 12/06/22 Fixed for Leonardo by @maris_HY +*************************************************/ + +#include +#include +#include "Arduino.h" +#include "pins_arduino.h" + +#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega128__) +#define TCCR2A TCCR2 +#define TCCR2B TCCR2 +#define COM2A1 COM21 +#define COM2A0 COM20 +#define OCR2A OCR2 +#define TIMSK2 TIMSK +#define OCIE2A OCIE2 +#define TIMER2_COMPA_vect TIMER2_COMP_vect +#define TIMSK1 TIMSK +#endif + +// timerx_toggle_count: +// > 0 - duration specified +// = 0 - stopped +// < 0 - infinitely (until stop() method called, or new play() called) + +#if !defined(__AVR_ATmega8__) +volatile long timer0_toggle_count; +volatile uint8_t *timer0_pin_port; +volatile uint8_t timer0_pin_mask; +#endif + +volatile long timer1_toggle_count; +volatile uint8_t *timer1_pin_port; +volatile uint8_t timer1_pin_mask; +volatile long timer2_toggle_count; +volatile uint8_t *timer2_pin_port; +volatile uint8_t timer2_pin_mask; + +#if defined(TIMSK3) +volatile long timer3_toggle_count; +volatile uint8_t *timer3_pin_port; +volatile uint8_t timer3_pin_mask; +#endif + +#if defined(TIMSK4) +volatile long timer4_toggle_count; +volatile uint8_t *timer4_pin_port; +volatile uint8_t timer4_pin_mask; +#endif + +#if defined(TIMSK5) +volatile long timer5_toggle_count; +volatile uint8_t *timer5_pin_port; +volatile uint8_t timer5_pin_mask; +#endif + + +#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + +#define AVAILABLE_TONE_PINS 1 +#define USE_TIMER2 + +const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 3, 4, 5, 1, 0 */ }; +static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255, 255, 255, 255, 255 */ }; + +#elif defined(__AVR_ATmega8__) + +#define AVAILABLE_TONE_PINS 1 +#define USE_TIMER2 + +const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 1 */ }; +static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255 */ }; + +#elif defined(__AVR_ATmega32U4__) + +#define AVAILABLE_TONE_PINS 1 +#define USE_TIMER3 + +const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 3 /*, 1 */ }; +static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255 */ }; + +#else + +#define AVAILABLE_TONE_PINS 1 +#define USE_TIMER2 + +// Leave timer 0 to last. +const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 1, 0 */ }; +static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255, 255 */ }; + +#endif + + + +static int8_t toneBegin(uint8_t _pin) +{ + int8_t _timer = -1; + + // if we're already using the pin, the timer should be configured. + for (int i = 0; i < AVAILABLE_TONE_PINS; i++) { + if (tone_pins[i] == _pin) { + return pgm_read_byte(tone_pin_to_timer_PGM + i); + } + } + + // search for an unused timer. + for (int i = 0; i < AVAILABLE_TONE_PINS; i++) { + if (tone_pins[i] == 255) { + tone_pins[i] = _pin; + _timer = pgm_read_byte(tone_pin_to_timer_PGM + i); + break; + } + } + + if (_timer != -1) + { + // Set timer specific stuff + // All timers in CTC mode + // 8 bit timers will require changing prescalar values, + // whereas 16 bit timers are set to either ck/1 or ck/64 prescalar + switch (_timer) + { + #if defined(TCCR0A) && defined(TCCR0B) + case 0: + // 8 bit timer + TCCR0A = 0; + TCCR0B = 0; + bitWrite(TCCR0A, WGM01, 1); + bitWrite(TCCR0B, CS00, 1); + timer0_pin_port = portOutputRegister(digitalPinToPort(_pin)); + timer0_pin_mask = digitalPinToBitMask(_pin); + break; + #endif + + #if defined(TCCR1A) && defined(TCCR1B) && defined(WGM12) + case 1: + // 16 bit timer + TCCR1A = 0; + TCCR1B = 0; + bitWrite(TCCR1B, WGM12, 1); + bitWrite(TCCR1B, CS10, 1); + timer1_pin_port = portOutputRegister(digitalPinToPort(_pin)); + timer1_pin_mask = digitalPinToBitMask(_pin); + break; + #endif + + #if defined(TCCR2A) && defined(TCCR2B) + case 2: + // 8 bit timer + TCCR2A = 0; + TCCR2B = 0; + bitWrite(TCCR2A, WGM21, 1); + bitWrite(TCCR2B, CS20, 1); + timer2_pin_port = portOutputRegister(digitalPinToPort(_pin)); + timer2_pin_mask = digitalPinToBitMask(_pin); + break; + #endif + + #if defined(TCCR3A) && defined(TCCR3B) && defined(TIMSK3) + case 3: + // 16 bit timer + TCCR3A = 0; + TCCR3B = 0; + bitWrite(TCCR3B, WGM32, 1); + bitWrite(TCCR3B, CS30, 1); + timer3_pin_port = portOutputRegister(digitalPinToPort(_pin)); + timer3_pin_mask = digitalPinToBitMask(_pin); + break; + #endif + + #if defined(TCCR4A) && defined(TCCR4B) && defined(TIMSK4) + case 4: + // 16 bit timer + TCCR4A = 0; + TCCR4B = 0; + #if defined(WGM42) + bitWrite(TCCR4B, WGM42, 1); + #elif defined(CS43) + #warning this may not be correct + // atmega32u4 + bitWrite(TCCR4B, CS43, 1); + #endif + bitWrite(TCCR4B, CS40, 1); + timer4_pin_port = portOutputRegister(digitalPinToPort(_pin)); + timer4_pin_mask = digitalPinToBitMask(_pin); + break; + #endif + + #if defined(TCCR5A) && defined(TCCR5B) && defined(TIMSK5) + case 5: + // 16 bit timer + TCCR5A = 0; + TCCR5B = 0; + bitWrite(TCCR5B, WGM52, 1); + bitWrite(TCCR5B, CS50, 1); + timer5_pin_port = portOutputRegister(digitalPinToPort(_pin)); + timer5_pin_mask = digitalPinToBitMask(_pin); + break; + #endif + } + } + + return _timer; +} + + + +// frequency (in hertz) and duration (in milliseconds). + +void tone(uint8_t _pin, unsigned int frequency, unsigned long duration) +{ + uint8_t prescalarbits = 0b001; + long toggle_count = 0; + uint32_t ocr = 0; + int8_t _timer; + + _timer = toneBegin(_pin); + + if (_timer >= 0) + { + // Set the pinMode as OUTPUT + pinMode(_pin, OUTPUT); + + // if we are using an 8 bit timer, scan through prescalars to find the best fit + if (_timer == 0 || _timer == 2) + { + ocr = F_CPU / frequency / 2 - 1; + prescalarbits = 0b001; // ck/1: same for both timers + if (ocr > 255) + { + ocr = F_CPU / frequency / 2 / 8 - 1; + prescalarbits = 0b010; // ck/8: same for both timers + + if (_timer == 2 && ocr > 255) + { + ocr = F_CPU / frequency / 2 / 32 - 1; + prescalarbits = 0b011; + } + + if (ocr > 255) + { + ocr = F_CPU / frequency / 2 / 64 - 1; + prescalarbits = _timer == 0 ? 0b011 : 0b100; + + if (_timer == 2 && ocr > 255) + { + ocr = F_CPU / frequency / 2 / 128 - 1; + prescalarbits = 0b101; + } + + if (ocr > 255) + { + ocr = F_CPU / frequency / 2 / 256 - 1; + prescalarbits = _timer == 0 ? 0b100 : 0b110; + if (ocr > 255) + { + // can't do any better than /1024 + ocr = F_CPU / frequency / 2 / 1024 - 1; + prescalarbits = _timer == 0 ? 0b101 : 0b111; + } + } + } + } + +#if defined(TCCR0B) + if (_timer == 0) + { + TCCR0B = prescalarbits; + } + else +#endif +#if defined(TCCR2B) + { + TCCR2B = prescalarbits; + } +#else + { + // dummy place holder to make the above ifdefs work + } +#endif + } + else + { + // two choices for the 16 bit timers: ck/1 or ck/64 + ocr = F_CPU / frequency / 2 - 1; + + prescalarbits = 0b001; + if (ocr > 0xffff) + { + ocr = F_CPU / frequency / 2 / 64 - 1; + prescalarbits = 0b011; + } + + if (_timer == 1) + { +#if defined(TCCR1B) + TCCR1B = (TCCR1B & 0b11111000) | prescalarbits; +#endif + } +#if defined(TCCR3B) + else if (_timer == 3) + TCCR3B = (TCCR3B & 0b11111000) | prescalarbits; +#endif +#if defined(TCCR4B) + else if (_timer == 4) + TCCR4B = (TCCR4B & 0b11111000) | prescalarbits; +#endif +#if defined(TCCR5B) + else if (_timer == 5) + TCCR5B = (TCCR5B & 0b11111000) | prescalarbits; +#endif + + } + + + // Calculate the toggle count + if (duration > 0) + { + toggle_count = 2 * frequency * duration / 1000; + } + else + { + toggle_count = -1; + } + + // Set the OCR for the given timer, + // set the toggle count, + // then turn on the interrupts + switch (_timer) + { + +#if defined(OCR0A) && defined(TIMSK0) && defined(OCIE0A) + case 0: + OCR0A = ocr; + timer0_toggle_count = toggle_count; + bitWrite(TIMSK0, OCIE0A, 1); + break; +#endif + + case 1: +#if defined(OCR1A) && defined(TIMSK1) && defined(OCIE1A) + OCR1A = ocr; + timer1_toggle_count = toggle_count; + bitWrite(TIMSK1, OCIE1A, 1); +#elif defined(OCR1A) && defined(TIMSK) && defined(OCIE1A) + // this combination is for at least the ATmega32 + OCR1A = ocr; + timer1_toggle_count = toggle_count; + bitWrite(TIMSK, OCIE1A, 1); +#endif + break; + +#if defined(OCR2A) && defined(TIMSK2) && defined(OCIE2A) + case 2: + OCR2A = ocr; + timer2_toggle_count = toggle_count; + bitWrite(TIMSK2, OCIE2A, 1); + break; +#endif + +#if defined(TIMSK3) + case 3: + OCR3A = ocr; + timer3_toggle_count = toggle_count; + bitWrite(TIMSK3, OCIE3A, 1); + break; +#endif + +#if defined(TIMSK4) + case 4: + OCR4A = ocr; + timer4_toggle_count = toggle_count; + bitWrite(TIMSK4, OCIE4A, 1); + break; +#endif + +#if defined(OCR5A) && defined(TIMSK5) && defined(OCIE5A) + case 5: + OCR5A = ocr; + timer5_toggle_count = toggle_count; + bitWrite(TIMSK5, OCIE5A, 1); + break; +#endif + + } + } +} + + +// XXX: this function only works properly for timer 2 (the only one we use +// currently). for the others, it should end the tone, but won't restore +// proper PWM functionality for the timer. +void disableTimer(uint8_t _timer) +{ + switch (_timer) + { + case 0: + #if defined(TIMSK0) + TIMSK0 = 0; + #elif defined(TIMSK) + TIMSK = 0; // atmega32 + #endif + break; + +#if defined(TIMSK1) && defined(OCIE1A) + case 1: + bitWrite(TIMSK1, OCIE1A, 0); + break; +#endif + + case 2: + #if defined(TIMSK2) && defined(OCIE2A) + bitWrite(TIMSK2, OCIE2A, 0); // disable interrupt + #endif + #if defined(TCCR2A) && defined(WGM20) + TCCR2A = (1 << WGM20); + #endif + #if defined(TCCR2B) && defined(CS22) + TCCR2B = (TCCR2B & 0b11111000) | (1 << CS22); + #endif + #if defined(OCR2A) + OCR2A = 0; + #endif + break; + +#if defined(TIMSK3) + case 3: + TIMSK3 = 0; + break; +#endif + +#if defined(TIMSK4) + case 4: + TIMSK4 = 0; + break; +#endif + +#if defined(TIMSK5) + case 5: + TIMSK5 = 0; + break; +#endif + } +} + + +void noTone(uint8_t _pin) +{ + int8_t _timer = -1; + + for (int i = 0; i < AVAILABLE_TONE_PINS; i++) { + if (tone_pins[i] == _pin) { + _timer = pgm_read_byte(tone_pin_to_timer_PGM + i); + tone_pins[i] = 255; + } + } + + disableTimer(_timer); + + digitalWrite(_pin, 0); +} + +#ifdef USE_TIMER0 +ISR(TIMER0_COMPA_vect) +{ + if (timer0_toggle_count != 0) + { + // toggle the pin + *timer0_pin_port ^= timer0_pin_mask; + + if (timer0_toggle_count > 0) + timer0_toggle_count--; + } + else + { + disableTimer(0); + *timer0_pin_port &= ~(timer0_pin_mask); // keep pin low after stop + } +} +#endif + + +#ifdef USE_TIMER1 +ISR(TIMER1_COMPA_vect) +{ + if (timer1_toggle_count != 0) + { + // toggle the pin + *timer1_pin_port ^= timer1_pin_mask; + + if (timer1_toggle_count > 0) + timer1_toggle_count--; + } + else + { + disableTimer(1); + *timer1_pin_port &= ~(timer1_pin_mask); // keep pin low after stop + } +} +#endif + + +#ifdef USE_TIMER2 +ISR(TIMER2_COMPA_vect) +{ + + if (timer2_toggle_count != 0) + { + // toggle the pin + *timer2_pin_port ^= timer2_pin_mask; + + if (timer2_toggle_count > 0) + timer2_toggle_count--; + } + else + { + // need to call noTone() so that the tone_pins[] entry is reset, so the + // timer gets initialized next time we call tone(). + // XXX: this assumes timer 2 is always the first one used. + noTone(tone_pins[0]); +// disableTimer(2); +// *timer2_pin_port &= ~(timer2_pin_mask); // keep pin low after stop + } +} +#endif + + +#ifdef USE_TIMER3 +ISR(TIMER3_COMPA_vect) +{ + if (timer3_toggle_count != 0) + { + // toggle the pin + *timer3_pin_port ^= timer3_pin_mask; + + if (timer3_toggle_count > 0) + timer3_toggle_count--; + } + else + { + disableTimer(3); + *timer3_pin_port &= ~(timer3_pin_mask); // keep pin low after stop + } +} +#endif + + +#ifdef USE_TIMER4 +ISR(TIMER4_COMPA_vect) +{ + if (timer4_toggle_count != 0) + { + // toggle the pin + *timer4_pin_port ^= timer4_pin_mask; + + if (timer4_toggle_count > 0) + timer4_toggle_count--; + } + else + { + disableTimer(4); + *timer4_pin_port &= ~(timer4_pin_mask); // keep pin low after stop + } +} +#endif + + +#ifdef USE_TIMER5 +ISR(TIMER5_COMPA_vect) +{ + if (timer5_toggle_count != 0) + { + // toggle the pin + *timer5_pin_port ^= timer5_pin_mask; + + if (timer5_toggle_count > 0) + timer5_toggle_count--; + } + else + { + disableTimer(5); + *timer5_pin_port &= ~(timer5_pin_mask); // keep pin low after stop + } +} +#endif diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/USBAPI.h b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/USBAPI.h new file mode 100644 index 000000000..eb2e5937d --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/USBAPI.h @@ -0,0 +1,196 @@ + + +#ifndef __USBAPI__ +#define __USBAPI__ + +#if defined(USBCON) + +//================================================================================ +//================================================================================ +// USB + +class USBDevice_ +{ +public: + USBDevice_(); + bool configured(); + + void attach(); + void detach(); // Serial port goes down too... + void poll(); +}; +extern USBDevice_ USBDevice; + +//================================================================================ +//================================================================================ +// Serial over CDC (Serial1 is the physical port) + +class Serial_ : public Stream +{ +private: + ring_buffer *_cdc_rx_buffer; +public: + void begin(uint16_t baud_count); + void end(void); + + virtual int available(void); + virtual void accept(void); + virtual int peek(void); + virtual int read(void); + virtual void flush(void); + virtual size_t write(uint8_t); + using Print::write; // pull in write(str) and write(buf, size) from Print + operator bool(); +}; +extern Serial_ Serial; + +//================================================================================ +//================================================================================ +// Mouse + +#define MOUSE_LEFT 1 +#define MOUSE_RIGHT 2 +#define MOUSE_MIDDLE 4 +#define MOUSE_ALL (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE) + +class Mouse_ +{ +private: + uint8_t _buttons; + void buttons(uint8_t b); +public: + Mouse_(void); + void begin(void); + void end(void); + void click(uint8_t b = MOUSE_LEFT); + void move(signed char x, signed char y, signed char wheel = 0); + void press(uint8_t b = MOUSE_LEFT); // press LEFT by default + void release(uint8_t b = MOUSE_LEFT); // release LEFT by default + bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default +}; +extern Mouse_ Mouse; + +//================================================================================ +//================================================================================ +// Keyboard + +#define KEY_LEFT_CTRL 0x80 +#define KEY_LEFT_SHIFT 0x81 +#define KEY_LEFT_ALT 0x82 +#define KEY_LEFT_GUI 0x83 +#define KEY_RIGHT_CTRL 0x84 +#define KEY_RIGHT_SHIFT 0x85 +#define KEY_RIGHT_ALT 0x86 +#define KEY_RIGHT_GUI 0x87 + +#define KEY_UP_ARROW 0xDA +#define KEY_DOWN_ARROW 0xD9 +#define KEY_LEFT_ARROW 0xD8 +#define KEY_RIGHT_ARROW 0xD7 +#define KEY_BACKSPACE 0xB2 +#define KEY_TAB 0xB3 +#define KEY_RETURN 0xB0 +#define KEY_ESC 0xB1 +#define KEY_INSERT 0xD1 +#define KEY_DELETE 0xD4 +#define KEY_PAGE_UP 0xD3 +#define KEY_PAGE_DOWN 0xD6 +#define KEY_HOME 0xD2 +#define KEY_END 0xD5 +#define KEY_CAPS_LOCK 0xC1 +#define KEY_F1 0xC2 +#define KEY_F2 0xC3 +#define KEY_F3 0xC4 +#define KEY_F4 0xC5 +#define KEY_F5 0xC6 +#define KEY_F6 0xC7 +#define KEY_F7 0xC8 +#define KEY_F8 0xC9 +#define KEY_F9 0xCA +#define KEY_F10 0xCB +#define KEY_F11 0xCC +#define KEY_F12 0xCD + +// Low level key report: up to 6 keys and shift, ctrl etc at once +typedef struct +{ + uint8_t modifiers; + uint8_t reserved; + uint8_t keys[6]; +} KeyReport; + +class Keyboard_ : public Print +{ +private: + KeyReport _keyReport; + void sendReport(KeyReport* keys); +public: + Keyboard_(void); + void begin(void); + void end(void); + virtual size_t write(uint8_t k); + virtual size_t press(uint8_t k); + virtual size_t release(uint8_t k); + virtual void releaseAll(void); +}; +extern Keyboard_ Keyboard; + +//================================================================================ +//================================================================================ +// Low level API + +typedef struct +{ + uint8_t bmRequestType; + uint8_t bRequest; + uint8_t wValueL; + uint8_t wValueH; + uint16_t wIndex; + uint16_t wLength; +} Setup; + +//================================================================================ +//================================================================================ +// HID 'Driver' + +int HID_GetInterface(uint8_t* interfaceNum); +int HID_GetDescriptor(int i); +bool HID_Setup(Setup& setup); +void HID_SendReport(uint8_t id, const void* data, int len); + +//================================================================================ +//================================================================================ +// MSC 'Driver' + +int MSC_GetInterface(uint8_t* interfaceNum); +int MSC_GetDescriptor(int i); +bool MSC_Setup(Setup& setup); +bool MSC_Data(uint8_t rx,uint8_t tx); + +//================================================================================ +//================================================================================ +// CSC 'Driver' + +int CDC_GetInterface(uint8_t* interfaceNum); +int CDC_GetDescriptor(int i); +bool CDC_Setup(Setup& setup); + +//================================================================================ +//================================================================================ + +#define TRANSFER_PGM 0x80 +#define TRANSFER_RELEASE 0x40 +#define TRANSFER_ZERO 0x20 + +int USB_SendControl(uint8_t flags, const void* d, int len); +int USB_RecvControl(void* d, int len); + +uint8_t USB_Available(uint8_t ep); +int USB_Send(uint8_t ep, const void* data, int len); // blocking +int USB_Recv(uint8_t ep, void* data, int len); // non-blocking +int USB_Recv(uint8_t ep); // non-blocking +void USB_Flush(uint8_t ep); + +#endif + +#endif /* if defined(USBCON) */ \ No newline at end of file diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/USBCore.cpp b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/USBCore.cpp new file mode 100644 index 000000000..d3e017065 --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/USBCore.cpp @@ -0,0 +1,684 @@ + + +/* Copyright (c) 2010, Peter Barrett +** +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + +#include "Platform.h" +#include "USBAPI.h" +#include "USBDesc.h" + +#if defined(USBCON) + +#define EP_TYPE_CONTROL 0x00 +#define EP_TYPE_BULK_IN 0x81 +#define EP_TYPE_BULK_OUT 0x80 +#define EP_TYPE_INTERRUPT_IN 0xC1 +#define EP_TYPE_INTERRUPT_OUT 0xC0 +#define EP_TYPE_ISOCHRONOUS_IN 0x41 +#define EP_TYPE_ISOCHRONOUS_OUT 0x40 + +/** Pulse generation counters to keep track of the number of milliseconds remaining for each pulse type */ +#define TX_RX_LED_PULSE_MS 100 +volatile u8 TxLEDPulse; /**< Milliseconds remaining for data Tx LED pulse */ +volatile u8 RxLEDPulse; /**< Milliseconds remaining for data Rx LED pulse */ + +//================================================================== +//================================================================== + +extern const u16 STRING_LANGUAGE[] PROGMEM; +extern const u16 STRING_IPRODUCT[] PROGMEM; +extern const u16 STRING_IMANUFACTURER[] PROGMEM; +extern const DeviceDescriptor USB_DeviceDescriptor PROGMEM; +extern const DeviceDescriptor USB_DeviceDescriptorA PROGMEM; + +const u16 STRING_LANGUAGE[2] = { + (3<<8) | (2+2), + 0x0409 // English +}; + +const u16 STRING_IPRODUCT[17] = { + (3<<8) | (2+2*16), +#if USB_PID == 0x8036 + 'A','r','d','u','i','n','o',' ','L','e','o','n','a','r','d','o' +#elif USB_PID == 0x8037 + 'A','r','d','u','i','n','o',' ','M','i','c','r','o',' ',' ',' ' +#elif USB_PID == 0x803C + 'A','r','d','u','i','n','o',' ','E','s','p','l','o','r','a',' ' +#elif USB_PID == 0x9208 + 'L','i','l','y','P','a','d','U','S','B',' ',' ',' ',' ',' ',' ' +#else + 'U','S','B',' ','I','O',' ','B','o','a','r','d',' ',' ',' ',' ' +#endif +}; + +const u16 STRING_IMANUFACTURER[12] = { + (3<<8) | (2+2*11), +#if USB_VID == 0x2341 + 'A','r','d','u','i','n','o',' ','L','L','C' +#elif USB_VID == 0x1b4f + 'S','p','a','r','k','F','u','n',' ',' ',' ' +#else + 'U','n','k','n','o','w','n',' ',' ',' ',' ' +#endif +}; + +#ifdef CDC_ENABLED +#define DEVICE_CLASS 0x02 +#else +#define DEVICE_CLASS 0x00 +#endif + +// DEVICE DESCRIPTOR +const DeviceDescriptor USB_DeviceDescriptor = + D_DEVICE(0x00,0x00,0x00,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,0,1); + +const DeviceDescriptor USB_DeviceDescriptorA = + D_DEVICE(DEVICE_CLASS,0x00,0x00,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,0,1); + +//================================================================== +//================================================================== + +volatile u8 _usbConfiguration = 0; + +static inline void WaitIN(void) +{ + while (!(UEINTX & (1< len) + n = len; + len -= n; + { + LockEP lock(ep); + if (ep & TRANSFER_ZERO) + { + while (n--) + Send8(0); + } + else if (ep & TRANSFER_PGM) + { + while (n--) + Send8(pgm_read_byte(data++)); + } + else + { + while (n--) + Send8(*data++); + } + if (!ReadWriteAllowed() || ((len == 0) && (ep & TRANSFER_RELEASE))) // Release full buffer + ReleaseTX(); + } + } + TXLED1; // light the TX LED + TxLEDPulse = TX_RX_LED_PULSE_MS; + return r; +} + +extern const u8 _initEndpoints[] PROGMEM; +const u8 _initEndpoints[] = +{ + 0, + +#ifdef CDC_ENABLED + EP_TYPE_INTERRUPT_IN, // CDC_ENDPOINT_ACM + EP_TYPE_BULK_OUT, // CDC_ENDPOINT_OUT + EP_TYPE_BULK_IN, // CDC_ENDPOINT_IN +#endif + +#ifdef HID_ENABLED + EP_TYPE_INTERRUPT_IN // HID_ENDPOINT_INT +#endif +}; + +#define EP_SINGLE_64 0x32 // EP0 +#define EP_DOUBLE_64 0x36 // Other endpoints + +static +void InitEP(u8 index, u8 type, u8 size) +{ + UENUM = index; + UECONX = 1; + UECFG0X = type; + UECFG1X = size; +} + +static +void InitEndpoints() +{ + for (u8 i = 1; i < sizeof(_initEndpoints); i++) + { + UENUM = i; + UECONX = 1; + UECFG0X = pgm_read_byte(_initEndpoints+i); + UECFG1X = EP_DOUBLE_64; + } + UERST = 0x7E; // And reset them + UERST = 0; +} + +// Handle CLASS_INTERFACE requests +static +bool ClassInterfaceRequest(Setup& setup) +{ + u8 i = setup.wIndex; + +#ifdef CDC_ENABLED + if (CDC_ACM_INTERFACE == i) + return CDC_Setup(setup); +#endif + +#ifdef HID_ENABLED + if (HID_INTERFACE == i) + return HID_Setup(setup); +#endif + return false; +} + +int _cmark; +int _cend; +void InitControl(int end) +{ + SetEP(0); + _cmark = 0; + _cend = end; +} + +static +bool SendControl(u8 d) +{ + if (_cmark < _cend) + { + if (!WaitForINOrOUT()) + return false; + Send8(d); + if (!((_cmark + 1) & 0x3F)) + ClearIN(); // Fifo is full, release this packet + } + _cmark++; + return true; +}; + +// Clipped by _cmark/_cend +int USB_SendControl(u8 flags, const void* d, int len) +{ + int sent = len; + const u8* data = (const u8*)d; + bool pgm = flags & TRANSFER_PGM; + while (len--) + { + u8 c = pgm ? pgm_read_byte(data++) : *data++; + if (!SendControl(c)) + return -1; + } + return sent; +} + +// Does not timeout or cross fifo boundaries +// Will only work for transfers <= 64 bytes +// TODO +int USB_RecvControl(void* d, int len) +{ + WaitOUT(); + Recv((u8*)d,len); + ClearOUT(); + return len; +} + +int SendInterfaces() +{ + int total = 0; + u8 interfaces = 0; + +#ifdef CDC_ENABLED + total = CDC_GetInterface(&interfaces); +#endif + +#ifdef HID_ENABLED + total += HID_GetInterface(&interfaces); +#endif + + return interfaces; +} + +// Construct a dynamic configuration descriptor +// This really needs dynamic endpoint allocation etc +// TODO +static +bool SendConfiguration(int maxlen) +{ + // Count and measure interfaces + InitControl(0); + int interfaces = SendInterfaces(); + ConfigDescriptor config = D_CONFIG(_cmark + sizeof(ConfigDescriptor),interfaces); + + // Now send them + InitControl(maxlen); + USB_SendControl(0,&config,sizeof(ConfigDescriptor)); + SendInterfaces(); + return true; +} + +u8 _cdcComposite = 0; + +static +bool SendDescriptor(Setup& setup) +{ + u8 t = setup.wValueH; + if (USB_CONFIGURATION_DESCRIPTOR_TYPE == t) + return SendConfiguration(setup.wLength); + + InitControl(setup.wLength); +#ifdef HID_ENABLED + if (HID_REPORT_DESCRIPTOR_TYPE == t) + return HID_GetDescriptor(t); +#endif + + u8 desc_length = 0; + const u8* desc_addr = 0; + if (USB_DEVICE_DESCRIPTOR_TYPE == t) + { + if (setup.wLength == 8) + _cdcComposite = 1; + desc_addr = _cdcComposite ? (const u8*)&USB_DeviceDescriptorA : (const u8*)&USB_DeviceDescriptor; + } + else if (USB_STRING_DESCRIPTOR_TYPE == t) + { + if (setup.wValueL == 0) + desc_addr = (const u8*)&STRING_LANGUAGE; + else if (setup.wValueL == IPRODUCT) + desc_addr = (const u8*)&STRING_IPRODUCT; + else if (setup.wValueL == IMANUFACTURER) + desc_addr = (const u8*)&STRING_IMANUFACTURER; + else + return false; + } + + if (desc_addr == 0) + return false; + if (desc_length == 0) + desc_length = pgm_read_byte(desc_addr); + + USB_SendControl(TRANSFER_PGM,desc_addr,desc_length); + return true; +} + +// Endpoint 0 interrupt +ISR(USB_COM_vect) +{ + SetEP(0); + if (!ReceivedSetupInt()) + return; + + Setup setup; + Recv((u8*)&setup,8); + ClearSetupInt(); + + u8 requestType = setup.bmRequestType; + if (requestType & REQUEST_DEVICETOHOST) + WaitIN(); + else + ClearIN(); + + bool ok = true; + if (REQUEST_STANDARD == (requestType & REQUEST_TYPE)) + { + // Standard Requests + u8 r = setup.bRequest; + if (GET_STATUS == r) + { + Send8(0); // TODO + Send8(0); + } + else if (CLEAR_FEATURE == r) + { + } + else if (SET_FEATURE == r) + { + } + else if (SET_ADDRESS == r) + { + WaitIN(); + UDADDR = setup.wValueL | (1<> 8) & 0xFF) + +#define CDC_V1_10 0x0110 +#define CDC_COMMUNICATION_INTERFACE_CLASS 0x02 + +#define CDC_CALL_MANAGEMENT 0x01 +#define CDC_ABSTRACT_CONTROL_MODEL 0x02 +#define CDC_HEADER 0x00 +#define CDC_ABSTRACT_CONTROL_MANAGEMENT 0x02 +#define CDC_UNION 0x06 +#define CDC_CS_INTERFACE 0x24 +#define CDC_CS_ENDPOINT 0x25 +#define CDC_DATA_INTERFACE_CLASS 0x0A + +#define MSC_SUBCLASS_SCSI 0x06 +#define MSC_PROTOCOL_BULK_ONLY 0x50 + +#define HID_HID_DESCRIPTOR_TYPE 0x21 +#define HID_REPORT_DESCRIPTOR_TYPE 0x22 +#define HID_PHYSICAL_DESCRIPTOR_TYPE 0x23 + + +// Device +typedef struct { + u8 len; // 18 + u8 dtype; // 1 USB_DEVICE_DESCRIPTOR_TYPE + u16 usbVersion; // 0x200 + u8 deviceClass; + u8 deviceSubClass; + u8 deviceProtocol; + u8 packetSize0; // Packet 0 + u16 idVendor; + u16 idProduct; + u16 deviceVersion; // 0x100 + u8 iManufacturer; + u8 iProduct; + u8 iSerialNumber; + u8 bNumConfigurations; +} DeviceDescriptor; + +// Config +typedef struct { + u8 len; // 9 + u8 dtype; // 2 + u16 clen; // total length + u8 numInterfaces; + u8 config; + u8 iconfig; + u8 attributes; + u8 maxPower; +} ConfigDescriptor; + +// String + +// Interface +typedef struct +{ + u8 len; // 9 + u8 dtype; // 4 + u8 number; + u8 alternate; + u8 numEndpoints; + u8 interfaceClass; + u8 interfaceSubClass; + u8 protocol; + u8 iInterface; +} InterfaceDescriptor; + +// Endpoint +typedef struct +{ + u8 len; // 7 + u8 dtype; // 5 + u8 addr; + u8 attr; + u16 packetSize; + u8 interval; +} EndpointDescriptor; + +// Interface Association Descriptor +// Used to bind 2 interfaces together in CDC compostite device +typedef struct +{ + u8 len; // 8 + u8 dtype; // 11 + u8 firstInterface; + u8 interfaceCount; + u8 functionClass; + u8 funtionSubClass; + u8 functionProtocol; + u8 iInterface; +} IADDescriptor; + +// CDC CS interface descriptor +typedef struct +{ + u8 len; // 5 + u8 dtype; // 0x24 + u8 subtype; + u8 d0; + u8 d1; +} CDCCSInterfaceDescriptor; + +typedef struct +{ + u8 len; // 4 + u8 dtype; // 0x24 + u8 subtype; + u8 d0; +} CDCCSInterfaceDescriptor4; + +typedef struct +{ + u8 len; + u8 dtype; // 0x24 + u8 subtype; // 1 + u8 bmCapabilities; + u8 bDataInterface; +} CMFunctionalDescriptor; + +typedef struct +{ + u8 len; + u8 dtype; // 0x24 + u8 subtype; // 1 + u8 bmCapabilities; +} ACMFunctionalDescriptor; + +typedef struct +{ + // IAD + IADDescriptor iad; // Only needed on compound device + + // Control + InterfaceDescriptor cif; // + CDCCSInterfaceDescriptor header; + CMFunctionalDescriptor callManagement; // Call Management + ACMFunctionalDescriptor controlManagement; // ACM + CDCCSInterfaceDescriptor functionalDescriptor; // CDC_UNION + EndpointDescriptor cifin; + + // Data + InterfaceDescriptor dif; + EndpointDescriptor in; + EndpointDescriptor out; +} CDCDescriptor; + +typedef struct +{ + InterfaceDescriptor msc; + EndpointDescriptor in; + EndpointDescriptor out; +} MSCDescriptor; + +typedef struct +{ + u8 len; // 9 + u8 dtype; // 0x21 + u8 addr; + u8 versionL; // 0x101 + u8 versionH; // 0x101 + u8 country; + u8 desctype; // 0x22 report + u8 descLenL; + u8 descLenH; +} HIDDescDescriptor; + +typedef struct +{ + InterfaceDescriptor hid; + HIDDescDescriptor desc; + EndpointDescriptor in; +} HIDDescriptor; + + +#define D_DEVICE(_class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs) \ + { 18, 1, 0x200, _class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs } + +#define D_CONFIG(_totalLength,_interfaces) \ + { 9, 2, _totalLength,_interfaces, 1, 0, USB_CONFIG_BUS_POWERED, USB_CONFIG_POWER_MA(500) } + +#define D_INTERFACE(_n,_numEndpoints,_class,_subClass,_protocol) \ + { 9, 4, _n, 0, _numEndpoints, _class,_subClass, _protocol, 0 } + +#define D_ENDPOINT(_addr,_attr,_packetSize, _interval) \ + { 7, 5, _addr,_attr,_packetSize, _interval } + +#define D_IAD(_firstInterface, _count, _class, _subClass, _protocol) \ + { 8, 11, _firstInterface, _count, _class, _subClass, _protocol, 0 } + +#define D_HIDREPORT(_descriptorLength) \ + { 9, 0x21, 0x1, 0x1, 0, 1, 0x22, _descriptorLength, 0 } + +#define D_CDCCS(_subtype,_d0,_d1) { 5, 0x24, _subtype, _d0, _d1 } +#define D_CDCCS4(_subtype,_d0) { 4, 0x24, _subtype, _d0 } + + +#endif \ No newline at end of file diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/USBDesc.h b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/USBDesc.h new file mode 100644 index 000000000..900713e0f --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/USBDesc.h @@ -0,0 +1,63 @@ + + +/* Copyright (c) 2011, Peter Barrett +** +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + +#define CDC_ENABLED +#define HID_ENABLED + + +#ifdef CDC_ENABLED +#define CDC_INTERFACE_COUNT 2 +#define CDC_ENPOINT_COUNT 3 +#else +#define CDC_INTERFACE_COUNT 0 +#define CDC_ENPOINT_COUNT 0 +#endif + +#ifdef HID_ENABLED +#define HID_INTERFACE_COUNT 1 +#define HID_ENPOINT_COUNT 1 +#else +#define HID_INTERFACE_COUNT 0 +#define HID_ENPOINT_COUNT 0 +#endif + +#define CDC_ACM_INTERFACE 0 // CDC ACM +#define CDC_DATA_INTERFACE 1 // CDC Data +#define CDC_FIRST_ENDPOINT 1 +#define CDC_ENDPOINT_ACM (CDC_FIRST_ENDPOINT) // CDC First +#define CDC_ENDPOINT_OUT (CDC_FIRST_ENDPOINT+1) +#define CDC_ENDPOINT_IN (CDC_FIRST_ENDPOINT+2) + +#define HID_INTERFACE (CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT) // HID Interface +#define HID_FIRST_ENDPOINT (CDC_FIRST_ENDPOINT + CDC_ENPOINT_COUNT) +#define HID_ENDPOINT_INT (HID_FIRST_ENDPOINT) + +#define INTERFACE_COUNT (MSC_INTERFACE + MSC_INTERFACE_COUNT) + +#ifdef CDC_ENABLED +#define CDC_RX CDC_ENDPOINT_OUT +#define CDC_TX CDC_ENDPOINT_IN +#endif + +#ifdef HID_ENABLED +#define HID_TX HID_ENDPOINT_INT +#endif + +#define IMANUFACTURER 1 +#define IPRODUCT 2 + diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Udp.h b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Udp.h new file mode 100644 index 000000000..dc5644b9d --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/Udp.h @@ -0,0 +1,88 @@ +/* + * Udp.cpp: Library to send/receive UDP packets. + * + * NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these) + * 1) UDP does not guarantee the order in which assembled UDP packets are received. This + * might not happen often in practice, but in larger network topologies, a UDP + * packet can be received out of sequence. + * 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being + * aware of it. Again, this may not be a concern in practice on small local networks. + * For more information, see http://www.cafeaulait.org/course/week12/35.html + * + * MIT License: + * Copyright (c) 2008 Bjoern Hartmann + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * bjoern@cs.stanford.edu 12/30/2008 + */ + +#ifndef udp_h +#define udp_h + +#include +#include + +class UDP : public Stream { + +public: + virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use + virtual void stop() =0; // Finish with the UDP socket + + // Sending UDP packets + + // Start building up a packet to send to the remote host specific in ip and port + // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port + virtual int beginPacket(IPAddress ip, uint16_t port) =0; + // Start building up a packet to send to the remote host specific in host and port + // Returns 1 if successful, 0 if there was a problem resolving the hostname or port + virtual int beginPacket(const char *host, uint16_t port) =0; + // Finish off this packet and send it + // Returns 1 if the packet was sent successfully, 0 if there was an error + virtual int endPacket() =0; + // Write a single byte into the packet + virtual size_t write(uint8_t) =0; + // Write size bytes from buffer into the packet + virtual size_t write(const uint8_t *buffer, size_t size) =0; + + // Start processing the next available incoming packet + // Returns the size of the packet in bytes, or 0 if no packets are available + virtual int parsePacket() =0; + // Number of bytes remaining in the current packet + virtual int available() =0; + // Read a single byte from the current packet + virtual int read() =0; + // Read up to len bytes from the current packet and place them into buffer + // Returns the number of bytes read, or 0 if none are available + virtual int read(unsigned char* buffer, size_t len) =0; + // Read up to len characters from the current packet and place them into buffer + // Returns the number of characters read, or 0 if none are available + virtual int read(char* buffer, size_t len) =0; + // Return the next byte from the current packet without moving on to the next byte + virtual int peek() =0; + virtual void flush() =0; // Finish reading the current packet + + // Return the IP address of the host who sent the current incoming packet + virtual IPAddress remoteIP() =0; + // Return the port of the host who sent the current incoming packet + virtual uint16_t remotePort() =0; +protected: + uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); }; +}; + +#endif diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/WCharacter.h b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/WCharacter.h new file mode 100644 index 000000000..79733b50a --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/WCharacter.h @@ -0,0 +1,168 @@ +/* + WCharacter.h - Character utility functions for Wiring & Arduino + Copyright (c) 2010 Hernando Barragan. 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 + */ + +#ifndef Character_h +#define Character_h + +#include + +// WCharacter.h prototypes +inline boolean isAlphaNumeric(int c) __attribute__((always_inline)); +inline boolean isAlpha(int c) __attribute__((always_inline)); +inline boolean isAscii(int c) __attribute__((always_inline)); +inline boolean isWhitespace(int c) __attribute__((always_inline)); +inline boolean isControl(int c) __attribute__((always_inline)); +inline boolean isDigit(int c) __attribute__((always_inline)); +inline boolean isGraph(int c) __attribute__((always_inline)); +inline boolean isLowerCase(int c) __attribute__((always_inline)); +inline boolean isPrintable(int c) __attribute__((always_inline)); +inline boolean isPunct(int c) __attribute__((always_inline)); +inline boolean isSpace(int c) __attribute__((always_inline)); +inline boolean isUpperCase(int c) __attribute__((always_inline)); +inline boolean isHexadecimalDigit(int c) __attribute__((always_inline)); +inline int toAscii(int c) __attribute__((always_inline)); +inline int toLowerCase(int c) __attribute__((always_inline)); +inline int toUpperCase(int c)__attribute__((always_inline)); + + +// Checks for an alphanumeric character. +// It is equivalent to (isalpha(c) || isdigit(c)). +inline boolean isAlphaNumeric(int c) +{ + return ( isalnum(c) == 0 ? false : true); +} + + +// Checks for an alphabetic character. +// It is equivalent to (isupper(c) || islower(c)). +inline boolean isAlpha(int c) +{ + return ( isalpha(c) == 0 ? false : true); +} + + +// Checks whether c is a 7-bit unsigned char value +// that fits into the ASCII character set. +inline boolean isAscii(int c) +{ + return ( isascii (c) == 0 ? false : true); +} + + +// Checks for a blank character, that is, a space or a tab. +inline boolean isWhitespace(int c) +{ + return ( isblank (c) == 0 ? false : true); +} + + +// Checks for a control character. +inline boolean isControl(int c) +{ + return ( iscntrl (c) == 0 ? false : true); +} + + +// Checks for a digit (0 through 9). +inline boolean isDigit(int c) +{ + return ( isdigit (c) == 0 ? false : true); +} + + +// Checks for any printable character except space. +inline boolean isGraph(int c) +{ + return ( isgraph (c) == 0 ? false : true); +} + + +// Checks for a lower-case character. +inline boolean isLowerCase(int c) +{ + return (islower (c) == 0 ? false : true); +} + + +// Checks for any printable character including space. +inline boolean isPrintable(int c) +{ + return ( isprint (c) == 0 ? false : true); +} + + +// Checks for any printable character which is not a space +// or an alphanumeric character. +inline boolean isPunct(int c) +{ + return ( ispunct (c) == 0 ? false : true); +} + + +// Checks for white-space characters. For the avr-libc library, +// these are: space, formfeed ('\f'), newline ('\n'), carriage +// return ('\r'), horizontal tab ('\t'), and vertical tab ('\v'). +inline boolean isSpace(int c) +{ + return ( isspace (c) == 0 ? false : true); +} + + +// Checks for an uppercase letter. +inline boolean isUpperCase(int c) +{ + return ( isupper (c) == 0 ? false : true); +} + + +// Checks for a hexadecimal digits, i.e. one of 0 1 2 3 4 5 6 7 +// 8 9 a b c d e f A B C D E F. +inline boolean isHexadecimalDigit(int c) +{ + return ( isxdigit (c) == 0 ? false : true); +} + + +// Converts c to a 7-bit unsigned char value that fits into the +// ASCII character set, by clearing the high-order bits. +inline int toAscii(int c) +{ + return toascii (c); +} + + +// Warning: +// Many people will be unhappy if you use this function. +// This function will convert accented letters into random +// characters. + +// Converts the letter c to lower case, if possible. +inline int toLowerCase(int c) +{ + return tolower (c); +} + + +// Converts the letter c to upper case, if possible. +inline int toUpperCase(int c) +{ + return toupper (c); +} + +#endif \ No newline at end of file diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/WInterrupts.c b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/WInterrupts.c new file mode 100644 index 000000000..62efc9cad --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/WInterrupts.c @@ -0,0 +1,322 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Wiring project - http://wiring.uniandes.edu.co + + Copyright (c) 2004-05 Hernando Barragan + + 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., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + Modified 24 November 2006 by David A. Mellis + Modified 1 August 2010 by Mark Sproul +*/ + +#include +#include +#include +#include +#include + +#include "wiring_private.h" + +static volatile voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS]; +// volatile static voidFuncPtr twiIntFunc; + +void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) { + if(interruptNum < EXTERNAL_NUM_INTERRUPTS) { + intFunc[interruptNum] = userFunc; + + // Configure the interrupt mode (trigger on low input, any change, rising + // edge, or falling edge). The mode constants were chosen to correspond + // to the configuration bits in the hardware register, so we simply shift + // the mode into place. + + // Enable the interrupt. + + switch (interruptNum) { +#if defined(__AVR_ATmega32U4__) + // I hate doing this, but the register assignment differs between the 1280/2560 + // and the 32U4. Since avrlib defines registers PCMSK1 and PCMSK2 that aren't + // even present on the 32U4 this is the only way to distinguish between them. + case 0: + EICRA = (EICRA & ~((1<= howbig) { + return howsmall; + } + long diff = howbig - howsmall; + return random(diff) + howsmall; +} + +long map(long x, long in_min, long in_max, long out_min, long out_max) +{ + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; +} + +unsigned int makeWord(unsigned int w) { return w; } +unsigned int makeWord(unsigned char h, unsigned char l) { return (h << 8) | l; } \ No newline at end of file diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/WString.cpp b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/WString.cpp new file mode 100644 index 000000000..c6839fc0d --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/WString.cpp @@ -0,0 +1,645 @@ +/* + WString.cpp - String library for Wiring & Arduino + ...mostly rewritten by Paul Stoffregen... + Copyright (c) 2009-10 Hernando Barragan. All rights reserved. + Copyright 2011, Paul Stoffregen, paul@pjrc.com + + 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 +*/ + +#include "WString.h" + + +/*********************************************/ +/* Constructors */ +/*********************************************/ + +String::String(const char *cstr) +{ + init(); + if (cstr) copy(cstr, strlen(cstr)); +} + +String::String(const String &value) +{ + init(); + *this = value; +} + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ +String::String(String &&rval) +{ + init(); + move(rval); +} +String::String(StringSumHelper &&rval) +{ + init(); + move(rval); +} +#endif + +String::String(char c) +{ + init(); + char buf[2]; + buf[0] = c; + buf[1] = 0; + *this = buf; +} + +String::String(unsigned char value, unsigned char base) +{ + init(); + char buf[9]; + utoa(value, buf, base); + *this = buf; +} + +String::String(int value, unsigned char base) +{ + init(); + char buf[18]; + itoa(value, buf, base); + *this = buf; +} + +String::String(unsigned int value, unsigned char base) +{ + init(); + char buf[17]; + utoa(value, buf, base); + *this = buf; +} + +String::String(long value, unsigned char base) +{ + init(); + char buf[34]; + ltoa(value, buf, base); + *this = buf; +} + +String::String(unsigned long value, unsigned char base) +{ + init(); + char buf[33]; + ultoa(value, buf, base); + *this = buf; +} + +String::~String() +{ + free(buffer); +} + +/*********************************************/ +/* Memory Management */ +/*********************************************/ + +inline void String::init(void) +{ + buffer = NULL; + capacity = 0; + len = 0; + flags = 0; +} + +void String::invalidate(void) +{ + if (buffer) free(buffer); + buffer = NULL; + capacity = len = 0; +} + +unsigned char String::reserve(unsigned int size) +{ + if (buffer && capacity >= size) return 1; + if (changeBuffer(size)) { + if (len == 0) buffer[0] = 0; + return 1; + } + return 0; +} + +unsigned char String::changeBuffer(unsigned int maxStrLen) +{ + char *newbuffer = (char *)realloc(buffer, maxStrLen + 1); + if (newbuffer) { + buffer = newbuffer; + capacity = maxStrLen; + return 1; + } + return 0; +} + +/*********************************************/ +/* Copy and Move */ +/*********************************************/ + +String & String::copy(const char *cstr, unsigned int length) +{ + if (!reserve(length)) { + invalidate(); + return *this; + } + len = length; + strcpy(buffer, cstr); + return *this; +} + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ +void String::move(String &rhs) +{ + if (buffer) { + if (capacity >= rhs.len) { + strcpy(buffer, rhs.buffer); + len = rhs.len; + rhs.len = 0; + return; + } else { + free(buffer); + } + } + buffer = rhs.buffer; + capacity = rhs.capacity; + len = rhs.len; + rhs.buffer = NULL; + rhs.capacity = 0; + rhs.len = 0; +} +#endif + +String & String::operator = (const String &rhs) +{ + if (this == &rhs) return *this; + + if (rhs.buffer) copy(rhs.buffer, rhs.len); + else invalidate(); + + return *this; +} + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ +String & String::operator = (String &&rval) +{ + if (this != &rval) move(rval); + return *this; +} + +String & String::operator = (StringSumHelper &&rval) +{ + if (this != &rval) move(rval); + return *this; +} +#endif + +String & String::operator = (const char *cstr) +{ + if (cstr) copy(cstr, strlen(cstr)); + else invalidate(); + + return *this; +} + +/*********************************************/ +/* concat */ +/*********************************************/ + +unsigned char String::concat(const String &s) +{ + return concat(s.buffer, s.len); +} + +unsigned char String::concat(const char *cstr, unsigned int length) +{ + unsigned int newlen = len + length; + if (!cstr) return 0; + if (length == 0) return 1; + if (!reserve(newlen)) return 0; + strcpy(buffer + len, cstr); + len = newlen; + return 1; +} + +unsigned char String::concat(const char *cstr) +{ + if (!cstr) return 0; + return concat(cstr, strlen(cstr)); +} + +unsigned char String::concat(char c) +{ + char buf[2]; + buf[0] = c; + buf[1] = 0; + return concat(buf, 1); +} + +unsigned char String::concat(unsigned char num) +{ + char buf[4]; + itoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(int num) +{ + char buf[7]; + itoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(unsigned int num) +{ + char buf[6]; + utoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(long num) +{ + char buf[12]; + ltoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(unsigned long num) +{ + char buf[11]; + ultoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +/*********************************************/ +/* Concatenate */ +/*********************************************/ + +StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(rhs.buffer, rhs.len)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr) +{ + StringSumHelper &a = const_cast(lhs); + if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, char c) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(c)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, int num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, long num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +/*********************************************/ +/* Comparison */ +/*********************************************/ + +int String::compareTo(const String &s) const +{ + if (!buffer || !s.buffer) { + if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer; + if (buffer && len > 0) return *(unsigned char *)buffer; + return 0; + } + return strcmp(buffer, s.buffer); +} + +unsigned char String::equals(const String &s2) const +{ + return (len == s2.len && compareTo(s2) == 0); +} + +unsigned char String::equals(const char *cstr) const +{ + if (len == 0) return (cstr == NULL || *cstr == 0); + if (cstr == NULL) return buffer[0] == 0; + return strcmp(buffer, cstr) == 0; +} + +unsigned char String::operator<(const String &rhs) const +{ + return compareTo(rhs) < 0; +} + +unsigned char String::operator>(const String &rhs) const +{ + return compareTo(rhs) > 0; +} + +unsigned char String::operator<=(const String &rhs) const +{ + return compareTo(rhs) <= 0; +} + +unsigned char String::operator>=(const String &rhs) const +{ + return compareTo(rhs) >= 0; +} + +unsigned char String::equalsIgnoreCase( const String &s2 ) const +{ + if (this == &s2) return 1; + if (len != s2.len) return 0; + if (len == 0) return 1; + const char *p1 = buffer; + const char *p2 = s2.buffer; + while (*p1) { + if (tolower(*p1++) != tolower(*p2++)) return 0; + } + return 1; +} + +unsigned char String::startsWith( const String &s2 ) const +{ + if (len < s2.len) return 0; + return startsWith(s2, 0); +} + +unsigned char String::startsWith( const String &s2, unsigned int offset ) const +{ + if (offset > len - s2.len || !buffer || !s2.buffer) return 0; + return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0; +} + +unsigned char String::endsWith( const String &s2 ) const +{ + if ( len < s2.len || !buffer || !s2.buffer) return 0; + return strcmp(&buffer[len - s2.len], s2.buffer) == 0; +} + +/*********************************************/ +/* Character Access */ +/*********************************************/ + +char String::charAt(unsigned int loc) const +{ + return operator[](loc); +} + +void String::setCharAt(unsigned int loc, char c) +{ + if (loc < len) buffer[loc] = c; +} + +char & String::operator[](unsigned int index) +{ + static char dummy_writable_char; + if (index >= len || !buffer) { + dummy_writable_char = 0; + return dummy_writable_char; + } + return buffer[index]; +} + +char String::operator[]( unsigned int index ) const +{ + if (index >= len || !buffer) return 0; + return buffer[index]; +} + +void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const +{ + if (!bufsize || !buf) return; + if (index >= len) { + buf[0] = 0; + return; + } + unsigned int n = bufsize - 1; + if (n > len - index) n = len - index; + strncpy((char *)buf, buffer + index, n); + buf[n] = 0; +} + +/*********************************************/ +/* Search */ +/*********************************************/ + +int String::indexOf(char c) const +{ + return indexOf(c, 0); +} + +int String::indexOf( char ch, unsigned int fromIndex ) const +{ + if (fromIndex >= len) return -1; + const char* temp = strchr(buffer + fromIndex, ch); + if (temp == NULL) return -1; + return temp - buffer; +} + +int String::indexOf(const String &s2) const +{ + return indexOf(s2, 0); +} + +int String::indexOf(const String &s2, unsigned int fromIndex) const +{ + if (fromIndex >= len) return -1; + const char *found = strstr(buffer + fromIndex, s2.buffer); + if (found == NULL) return -1; + return found - buffer; +} + +int String::lastIndexOf( char theChar ) const +{ + return lastIndexOf(theChar, len - 1); +} + +int String::lastIndexOf(char ch, unsigned int fromIndex) const +{ + if (fromIndex >= len) return -1; + char tempchar = buffer[fromIndex + 1]; + buffer[fromIndex + 1] = '\0'; + char* temp = strrchr( buffer, ch ); + buffer[fromIndex + 1] = tempchar; + if (temp == NULL) return -1; + return temp - buffer; +} + +int String::lastIndexOf(const String &s2) const +{ + return lastIndexOf(s2, len - s2.len); +} + +int String::lastIndexOf(const String &s2, unsigned int fromIndex) const +{ + if (s2.len == 0 || len == 0 || s2.len > len) return -1; + if (fromIndex >= len) fromIndex = len - 1; + int found = -1; + for (char *p = buffer; p <= buffer + fromIndex; p++) { + p = strstr(p, s2.buffer); + if (!p) break; + if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer; + } + return found; +} + +String String::substring( unsigned int left ) const +{ + return substring(left, len); +} + +String String::substring(unsigned int left, unsigned int right) const +{ + if (left > right) { + unsigned int temp = right; + right = left; + left = temp; + } + String out; + if (left > len) return out; + if (right > len) right = len; + char temp = buffer[right]; // save the replaced character + buffer[right] = '\0'; + out = buffer + left; // pointer arithmetic + buffer[right] = temp; //restore character + return out; +} + +/*********************************************/ +/* Modification */ +/*********************************************/ + +void String::replace(char find, char replace) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) { + if (*p == find) *p = replace; + } +} + +void String::replace(const String& find, const String& replace) +{ + if (len == 0 || find.len == 0) return; + int diff = replace.len - find.len; + char *readFrom = buffer; + char *foundAt; + if (diff == 0) { + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + memcpy(foundAt, replace.buffer, replace.len); + readFrom = foundAt + replace.len; + } + } else if (diff < 0) { + char *writeTo = buffer; + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + unsigned int n = foundAt - readFrom; + memcpy(writeTo, readFrom, n); + writeTo += n; + memcpy(writeTo, replace.buffer, replace.len); + writeTo += replace.len; + readFrom = foundAt + find.len; + len += diff; + } + strcpy(writeTo, readFrom); + } else { + unsigned int size = len; // compute size needed for result + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + readFrom = foundAt + find.len; + size += diff; + } + if (size == len) return; + if (size > capacity && !changeBuffer(size)) return; // XXX: tell user! + int index = len - 1; + while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) { + readFrom = buffer + index + find.len; + memmove(readFrom + diff, readFrom, len - (readFrom - buffer)); + len += diff; + buffer[len] = 0; + memcpy(buffer + index, replace.buffer, replace.len); + index--; + } + } +} + +void String::toLowerCase(void) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) { + *p = tolower(*p); + } +} + +void String::toUpperCase(void) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) { + *p = toupper(*p); + } +} + +void String::trim(void) +{ + if (!buffer || len == 0) return; + char *begin = buffer; + while (isspace(*begin)) begin++; + char *end = buffer + len - 1; + while (isspace(*end) && end >= begin) end--; + len = end + 1 - begin; + if (begin > buffer) memcpy(buffer, begin, len); + buffer[len] = 0; +} + +/*********************************************/ +/* Parsing / Conversion */ +/*********************************************/ + +long String::toInt(void) const +{ + if (buffer) return atol(buffer); + return 0; +} + + diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/WString.h b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/WString.h new file mode 100644 index 000000000..947325e5f --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/WString.h @@ -0,0 +1,205 @@ +/* + WString.h - String library for Wiring & Arduino + ...mostly rewritten by Paul Stoffregen... + Copyright (c) 2009-10 Hernando Barragan. All right reserved. + Copyright 2011, Paul Stoffregen, paul@pjrc.com + + 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 +*/ + +#ifndef String_class_h +#define String_class_h +#ifdef __cplusplus + +#include +#include +#include +#include + +// When compiling programs with this class, the following gcc parameters +// dramatically increase performance and memory (RAM) efficiency, typically +// with little or no increase in code size. +// -felide-constructors +// -std=c++0x + +class __FlashStringHelper; +#define F(string_literal) (reinterpret_cast(PSTR(string_literal))) + +// An inherited class for holding the result of a concatenation. These +// result objects are assumed to be writable by subsequent concatenations. +class StringSumHelper; + +// The string class +class String +{ + // use a function pointer to allow for "if (s)" without the + // complications of an operator bool(). for more information, see: + // http://www.artima.com/cppsource/safebool.html + typedef void (String::*StringIfHelperType)() const; + void StringIfHelper() const {} + +public: + // constructors + // creates a copy of the initial value. + // if the initial value is null or invalid, or if memory allocation + // fails, the string will be marked as invalid (i.e. "if (s)" will + // be false). + String(const char *cstr = ""); + String(const String &str); + #ifdef __GXX_EXPERIMENTAL_CXX0X__ + String(String &&rval); + String(StringSumHelper &&rval); + #endif + explicit String(char c); + explicit String(unsigned char, unsigned char base=10); + explicit String(int, unsigned char base=10); + explicit String(unsigned int, unsigned char base=10); + explicit String(long, unsigned char base=10); + explicit String(unsigned long, unsigned char base=10); + ~String(void); + + // memory management + // return true on success, false on failure (in which case, the string + // is left unchanged). reserve(0), if successful, will validate an + // invalid string (i.e., "if (s)" will be true afterwards) + unsigned char reserve(unsigned int size); + inline unsigned int length(void) const {return len;} + + // creates a copy of the assigned value. if the value is null or + // invalid, or if the memory allocation fails, the string will be + // marked as invalid ("if (s)" will be false). + String & operator = (const String &rhs); + String & operator = (const char *cstr); + #ifdef __GXX_EXPERIMENTAL_CXX0X__ + String & operator = (String &&rval); + String & operator = (StringSumHelper &&rval); + #endif + + // concatenate (works w/ built-in types) + + // returns true on success, false on failure (in which case, the string + // is left unchanged). if the argument is null or invalid, the + // concatenation is considered unsucessful. + unsigned char concat(const String &str); + unsigned char concat(const char *cstr); + unsigned char concat(char c); + unsigned char concat(unsigned char c); + unsigned char concat(int num); + unsigned char concat(unsigned int num); + unsigned char concat(long num); + unsigned char concat(unsigned long num); + + // if there's not enough memory for the concatenated value, the string + // will be left unchanged (but this isn't signalled in any way) + String & operator += (const String &rhs) {concat(rhs); return (*this);} + String & operator += (const char *cstr) {concat(cstr); return (*this);} + String & operator += (char c) {concat(c); return (*this);} + String & operator += (unsigned char num) {concat(num); return (*this);} + String & operator += (int num) {concat(num); return (*this);} + String & operator += (unsigned int num) {concat(num); return (*this);} + String & operator += (long num) {concat(num); return (*this);} + String & operator += (unsigned long num) {concat(num); return (*this);} + + friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs); + friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr); + friend StringSumHelper & operator + (const StringSumHelper &lhs, char c); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, int num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, long num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num); + + // comparison (only works w/ Strings and "strings") + operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; } + int compareTo(const String &s) const; + unsigned char equals(const String &s) const; + unsigned char equals(const char *cstr) const; + unsigned char operator == (const String &rhs) const {return equals(rhs);} + unsigned char operator == (const char *cstr) const {return equals(cstr);} + unsigned char operator != (const String &rhs) const {return !equals(rhs);} + unsigned char operator != (const char *cstr) const {return !equals(cstr);} + unsigned char operator < (const String &rhs) const; + unsigned char operator > (const String &rhs) const; + unsigned char operator <= (const String &rhs) const; + unsigned char operator >= (const String &rhs) const; + unsigned char equalsIgnoreCase(const String &s) const; + unsigned char startsWith( const String &prefix) const; + unsigned char startsWith(const String &prefix, unsigned int offset) const; + unsigned char endsWith(const String &suffix) const; + + // character acccess + char charAt(unsigned int index) const; + void setCharAt(unsigned int index, char c); + char operator [] (unsigned int index) const; + char& operator [] (unsigned int index); + void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const; + void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const + {getBytes((unsigned char *)buf, bufsize, index);} + + // search + int indexOf( char ch ) const; + int indexOf( char ch, unsigned int fromIndex ) const; + int indexOf( const String &str ) const; + int indexOf( const String &str, unsigned int fromIndex ) const; + int lastIndexOf( char ch ) const; + int lastIndexOf( char ch, unsigned int fromIndex ) const; + int lastIndexOf( const String &str ) const; + int lastIndexOf( const String &str, unsigned int fromIndex ) const; + String substring( unsigned int beginIndex ) const; + String substring( unsigned int beginIndex, unsigned int endIndex ) const; + + // modification + void replace(char find, char replace); + void replace(const String& find, const String& replace); + void toLowerCase(void); + void toUpperCase(void); + void trim(void); + + // parsing/conversion + long toInt(void) const; + +protected: + char *buffer; // the actual char array + unsigned int capacity; // the array length minus one (for the '\0') + unsigned int len; // the String length (not counting the '\0') + unsigned char flags; // unused, for future features +protected: + void init(void); + void invalidate(void); + unsigned char changeBuffer(unsigned int maxStrLen); + unsigned char concat(const char *cstr, unsigned int length); + + // copy and move + String & copy(const char *cstr, unsigned int length); + #ifdef __GXX_EXPERIMENTAL_CXX0X__ + void move(String &rhs); + #endif +}; + +class StringSumHelper : public String +{ +public: + StringSumHelper(const String &s) : String(s) {} + StringSumHelper(const char *p) : String(p) {} + StringSumHelper(char c) : String(c) {} + StringSumHelper(unsigned char num) : String(num) {} + StringSumHelper(int num) : String(num) {} + StringSumHelper(unsigned int num) : String(num) {} + StringSumHelper(long num) : String(num) {} + StringSumHelper(unsigned long num) : String(num) {} +}; + +#endif // __cplusplus +#endif // String_class_h diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/binary.h b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/binary.h new file mode 100644 index 000000000..af1498033 --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/binary.h @@ -0,0 +1,515 @@ +#ifndef Binary_h +#define Binary_h + +#define B0 0 +#define B00 0 +#define B000 0 +#define B0000 0 +#define B00000 0 +#define B000000 0 +#define B0000000 0 +#define B00000000 0 +#define B1 1 +#define B01 1 +#define B001 1 +#define B0001 1 +#define B00001 1 +#define B000001 1 +#define B0000001 1 +#define B00000001 1 +#define B10 2 +#define B010 2 +#define B0010 2 +#define B00010 2 +#define B000010 2 +#define B0000010 2 +#define B00000010 2 +#define B11 3 +#define B011 3 +#define B0011 3 +#define B00011 3 +#define B000011 3 +#define B0000011 3 +#define B00000011 3 +#define B100 4 +#define B0100 4 +#define B00100 4 +#define B000100 4 +#define B0000100 4 +#define B00000100 4 +#define B101 5 +#define B0101 5 +#define B00101 5 +#define B000101 5 +#define B0000101 5 +#define B00000101 5 +#define B110 6 +#define B0110 6 +#define B00110 6 +#define B000110 6 +#define B0000110 6 +#define B00000110 6 +#define B111 7 +#define B0111 7 +#define B00111 7 +#define B000111 7 +#define B0000111 7 +#define B00000111 7 +#define B1000 8 +#define B01000 8 +#define B001000 8 +#define B0001000 8 +#define B00001000 8 +#define B1001 9 +#define B01001 9 +#define B001001 9 +#define B0001001 9 +#define B00001001 9 +#define B1010 10 +#define B01010 10 +#define B001010 10 +#define B0001010 10 +#define B00001010 10 +#define B1011 11 +#define B01011 11 +#define B001011 11 +#define B0001011 11 +#define B00001011 11 +#define B1100 12 +#define B01100 12 +#define B001100 12 +#define B0001100 12 +#define B00001100 12 +#define B1101 13 +#define B01101 13 +#define B001101 13 +#define B0001101 13 +#define B00001101 13 +#define B1110 14 +#define B01110 14 +#define B001110 14 +#define B0001110 14 +#define B00001110 14 +#define B1111 15 +#define B01111 15 +#define B001111 15 +#define B0001111 15 +#define B00001111 15 +#define B10000 16 +#define B010000 16 +#define B0010000 16 +#define B00010000 16 +#define B10001 17 +#define B010001 17 +#define B0010001 17 +#define B00010001 17 +#define B10010 18 +#define B010010 18 +#define B0010010 18 +#define B00010010 18 +#define B10011 19 +#define B010011 19 +#define B0010011 19 +#define B00010011 19 +#define B10100 20 +#define B010100 20 +#define B0010100 20 +#define B00010100 20 +#define B10101 21 +#define B010101 21 +#define B0010101 21 +#define B00010101 21 +#define B10110 22 +#define B010110 22 +#define B0010110 22 +#define B00010110 22 +#define B10111 23 +#define B010111 23 +#define B0010111 23 +#define B00010111 23 +#define B11000 24 +#define B011000 24 +#define B0011000 24 +#define B00011000 24 +#define B11001 25 +#define B011001 25 +#define B0011001 25 +#define B00011001 25 +#define B11010 26 +#define B011010 26 +#define B0011010 26 +#define B00011010 26 +#define B11011 27 +#define B011011 27 +#define B0011011 27 +#define B00011011 27 +#define B11100 28 +#define B011100 28 +#define B0011100 28 +#define B00011100 28 +#define B11101 29 +#define B011101 29 +#define B0011101 29 +#define B00011101 29 +#define B11110 30 +#define B011110 30 +#define B0011110 30 +#define B00011110 30 +#define B11111 31 +#define B011111 31 +#define B0011111 31 +#define B00011111 31 +#define B100000 32 +#define B0100000 32 +#define B00100000 32 +#define B100001 33 +#define B0100001 33 +#define B00100001 33 +#define B100010 34 +#define B0100010 34 +#define B00100010 34 +#define B100011 35 +#define B0100011 35 +#define B00100011 35 +#define B100100 36 +#define B0100100 36 +#define B00100100 36 +#define B100101 37 +#define B0100101 37 +#define B00100101 37 +#define B100110 38 +#define B0100110 38 +#define B00100110 38 +#define B100111 39 +#define B0100111 39 +#define B00100111 39 +#define B101000 40 +#define B0101000 40 +#define B00101000 40 +#define B101001 41 +#define B0101001 41 +#define B00101001 41 +#define B101010 42 +#define B0101010 42 +#define B00101010 42 +#define B101011 43 +#define B0101011 43 +#define B00101011 43 +#define B101100 44 +#define B0101100 44 +#define B00101100 44 +#define B101101 45 +#define B0101101 45 +#define B00101101 45 +#define B101110 46 +#define B0101110 46 +#define B00101110 46 +#define B101111 47 +#define B0101111 47 +#define B00101111 47 +#define B110000 48 +#define B0110000 48 +#define B00110000 48 +#define B110001 49 +#define B0110001 49 +#define B00110001 49 +#define B110010 50 +#define B0110010 50 +#define B00110010 50 +#define B110011 51 +#define B0110011 51 +#define B00110011 51 +#define B110100 52 +#define B0110100 52 +#define B00110100 52 +#define B110101 53 +#define B0110101 53 +#define B00110101 53 +#define B110110 54 +#define B0110110 54 +#define B00110110 54 +#define B110111 55 +#define B0110111 55 +#define B00110111 55 +#define B111000 56 +#define B0111000 56 +#define B00111000 56 +#define B111001 57 +#define B0111001 57 +#define B00111001 57 +#define B111010 58 +#define B0111010 58 +#define B00111010 58 +#define B111011 59 +#define B0111011 59 +#define B00111011 59 +#define B111100 60 +#define B0111100 60 +#define B00111100 60 +#define B111101 61 +#define B0111101 61 +#define B00111101 61 +#define B111110 62 +#define B0111110 62 +#define B00111110 62 +#define B111111 63 +#define B0111111 63 +#define B00111111 63 +#define B1000000 64 +#define B01000000 64 +#define B1000001 65 +#define B01000001 65 +#define B1000010 66 +#define B01000010 66 +#define B1000011 67 +#define B01000011 67 +#define B1000100 68 +#define B01000100 68 +#define B1000101 69 +#define B01000101 69 +#define B1000110 70 +#define B01000110 70 +#define B1000111 71 +#define B01000111 71 +#define B1001000 72 +#define B01001000 72 +#define B1001001 73 +#define B01001001 73 +#define B1001010 74 +#define B01001010 74 +#define B1001011 75 +#define B01001011 75 +#define B1001100 76 +#define B01001100 76 +#define B1001101 77 +#define B01001101 77 +#define B1001110 78 +#define B01001110 78 +#define B1001111 79 +#define B01001111 79 +#define B1010000 80 +#define B01010000 80 +#define B1010001 81 +#define B01010001 81 +#define B1010010 82 +#define B01010010 82 +#define B1010011 83 +#define B01010011 83 +#define B1010100 84 +#define B01010100 84 +#define B1010101 85 +#define B01010101 85 +#define B1010110 86 +#define B01010110 86 +#define B1010111 87 +#define B01010111 87 +#define B1011000 88 +#define B01011000 88 +#define B1011001 89 +#define B01011001 89 +#define B1011010 90 +#define B01011010 90 +#define B1011011 91 +#define B01011011 91 +#define B1011100 92 +#define B01011100 92 +#define B1011101 93 +#define B01011101 93 +#define B1011110 94 +#define B01011110 94 +#define B1011111 95 +#define B01011111 95 +#define B1100000 96 +#define B01100000 96 +#define B1100001 97 +#define B01100001 97 +#define B1100010 98 +#define B01100010 98 +#define B1100011 99 +#define B01100011 99 +#define B1100100 100 +#define B01100100 100 +#define B1100101 101 +#define B01100101 101 +#define B1100110 102 +#define B01100110 102 +#define B1100111 103 +#define B01100111 103 +#define B1101000 104 +#define B01101000 104 +#define B1101001 105 +#define B01101001 105 +#define B1101010 106 +#define B01101010 106 +#define B1101011 107 +#define B01101011 107 +#define B1101100 108 +#define B01101100 108 +#define B1101101 109 +#define B01101101 109 +#define B1101110 110 +#define B01101110 110 +#define B1101111 111 +#define B01101111 111 +#define B1110000 112 +#define B01110000 112 +#define B1110001 113 +#define B01110001 113 +#define B1110010 114 +#define B01110010 114 +#define B1110011 115 +#define B01110011 115 +#define B1110100 116 +#define B01110100 116 +#define B1110101 117 +#define B01110101 117 +#define B1110110 118 +#define B01110110 118 +#define B1110111 119 +#define B01110111 119 +#define B1111000 120 +#define B01111000 120 +#define B1111001 121 +#define B01111001 121 +#define B1111010 122 +#define B01111010 122 +#define B1111011 123 +#define B01111011 123 +#define B1111100 124 +#define B01111100 124 +#define B1111101 125 +#define B01111101 125 +#define B1111110 126 +#define B01111110 126 +#define B1111111 127 +#define B01111111 127 +#define B10000000 128 +#define B10000001 129 +#define B10000010 130 +#define B10000011 131 +#define B10000100 132 +#define B10000101 133 +#define B10000110 134 +#define B10000111 135 +#define B10001000 136 +#define B10001001 137 +#define B10001010 138 +#define B10001011 139 +#define B10001100 140 +#define B10001101 141 +#define B10001110 142 +#define B10001111 143 +#define B10010000 144 +#define B10010001 145 +#define B10010010 146 +#define B10010011 147 +#define B10010100 148 +#define B10010101 149 +#define B10010110 150 +#define B10010111 151 +#define B10011000 152 +#define B10011001 153 +#define B10011010 154 +#define B10011011 155 +#define B10011100 156 +#define B10011101 157 +#define B10011110 158 +#define B10011111 159 +#define B10100000 160 +#define B10100001 161 +#define B10100010 162 +#define B10100011 163 +#define B10100100 164 +#define B10100101 165 +#define B10100110 166 +#define B10100111 167 +#define B10101000 168 +#define B10101001 169 +#define B10101010 170 +#define B10101011 171 +#define B10101100 172 +#define B10101101 173 +#define B10101110 174 +#define B10101111 175 +#define B10110000 176 +#define B10110001 177 +#define B10110010 178 +#define B10110011 179 +#define B10110100 180 +#define B10110101 181 +#define B10110110 182 +#define B10110111 183 +#define B10111000 184 +#define B10111001 185 +#define B10111010 186 +#define B10111011 187 +#define B10111100 188 +#define B10111101 189 +#define B10111110 190 +#define B10111111 191 +#define B11000000 192 +#define B11000001 193 +#define B11000010 194 +#define B11000011 195 +#define B11000100 196 +#define B11000101 197 +#define B11000110 198 +#define B11000111 199 +#define B11001000 200 +#define B11001001 201 +#define B11001010 202 +#define B11001011 203 +#define B11001100 204 +#define B11001101 205 +#define B11001110 206 +#define B11001111 207 +#define B11010000 208 +#define B11010001 209 +#define B11010010 210 +#define B11010011 211 +#define B11010100 212 +#define B11010101 213 +#define B11010110 214 +#define B11010111 215 +#define B11011000 216 +#define B11011001 217 +#define B11011010 218 +#define B11011011 219 +#define B11011100 220 +#define B11011101 221 +#define B11011110 222 +#define B11011111 223 +#define B11100000 224 +#define B11100001 225 +#define B11100010 226 +#define B11100011 227 +#define B11100100 228 +#define B11100101 229 +#define B11100110 230 +#define B11100111 231 +#define B11101000 232 +#define B11101001 233 +#define B11101010 234 +#define B11101011 235 +#define B11101100 236 +#define B11101101 237 +#define B11101110 238 +#define B11101111 239 +#define B11110000 240 +#define B11110001 241 +#define B11110010 242 +#define B11110011 243 +#define B11110100 244 +#define B11110101 245 +#define B11110110 246 +#define B11110111 247 +#define B11111000 248 +#define B11111001 249 +#define B11111010 250 +#define B11111011 251 +#define B11111100 252 +#define B11111101 253 +#define B11111110 254 +#define B11111111 255 + +#endif diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/main.cpp b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/main.cpp new file mode 100644 index 000000000..3d4e079d2 --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/main.cpp @@ -0,0 +1,20 @@ +#include + +int main(void) +{ + init(); + +#if defined(USBCON) + USBDevice.attach(); +#endif + + setup(); + + for (;;) { + loop(); + if (serialEventRun) serialEventRun(); + } + + return 0; +} + diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/new.cpp b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/new.cpp new file mode 100644 index 000000000..0f6d4220e --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/new.cpp @@ -0,0 +1,18 @@ +#include + +void * operator new(size_t size) +{ + return malloc(size); +} + +void operator delete(void * ptr) +{ + free(ptr); +} + +int __cxa_guard_acquire(__guard *g) {return !*(char *)(g);}; +void __cxa_guard_release (__guard *g) {*(char *)g = 1;}; +void __cxa_guard_abort (__guard *) {}; + +void __cxa_pure_virtual(void) {}; + diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/new.h b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/new.h new file mode 100644 index 000000000..cd940ce8b --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/new.h @@ -0,0 +1,22 @@ +/* Header to define new/delete operators as they aren't provided by avr-gcc by default + Taken from http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=59453 + */ + +#ifndef NEW_H +#define NEW_H + +#include + +void * operator new(size_t size); +void operator delete(void * ptr); + +__extension__ typedef int __guard __attribute__((mode (__DI__))); + +extern "C" int __cxa_guard_acquire(__guard *); +extern "C" void __cxa_guard_release (__guard *); +extern "C" void __cxa_guard_abort (__guard *); + +extern "C" void __cxa_pure_virtual(void); + +#endif + diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/wiring.c b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/wiring.c new file mode 100644 index 000000000..ac8bb6f9b --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/wiring.c @@ -0,0 +1,324 @@ +/* + wiring.c - Partial implementation of the Wiring API for the ATmega8. + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2005-2006 David A. Mellis + + 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., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + $Id$ +*/ + +#include "wiring_private.h" + +// the prescaler is set so that timer0 ticks every 64 clock cycles, and the +// the overflow handler is called every 256 ticks. +#define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256)) + +// the whole number of milliseconds per timer0 overflow +#define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000) + +// the fractional number of milliseconds per timer0 overflow. we shift right +// by three to fit these numbers into a byte. (for the clock speeds we care +// about - 8 and 16 MHz - this doesn't lose precision.) +#define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3) +#define FRACT_MAX (1000 >> 3) + +volatile unsigned long timer0_overflow_count = 0; +volatile unsigned long timer0_millis = 0; +static unsigned char timer0_fract = 0; + +#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) +SIGNAL(TIM0_OVF_vect) +#else +SIGNAL(TIMER0_OVF_vect) +#endif +{ + // copy these to local variables so they can be stored in registers + // (volatile variables must be read from memory on every access) + unsigned long m = timer0_millis; + unsigned char f = timer0_fract; + + m += MILLIS_INC; + f += FRACT_INC; + if (f >= FRACT_MAX) { + f -= FRACT_MAX; + m += 1; + } + + timer0_fract = f; + timer0_millis = m; + timer0_overflow_count++; +} + +unsigned long millis() +{ + unsigned long m; + uint8_t oldSREG = SREG; + + // disable interrupts while we read timer0_millis or we might get an + // inconsistent value (e.g. in the middle of a write to timer0_millis) + cli(); + m = timer0_millis; + SREG = oldSREG; + + return m; +} + +unsigned long micros() { + unsigned long m; + uint8_t oldSREG = SREG, t; + + cli(); + m = timer0_overflow_count; +#if defined(TCNT0) + t = TCNT0; +#elif defined(TCNT0L) + t = TCNT0L; +#else + #error TIMER 0 not defined +#endif + + +#ifdef TIFR0 + if ((TIFR0 & _BV(TOV0)) && (t < 255)) + m++; +#else + if ((TIFR & _BV(TOV0)) && (t < 255)) + m++; +#endif + + SREG = oldSREG; + + return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond()); +} + +void delay(unsigned long ms) +{ + uint16_t start = (uint16_t)micros(); + + while (ms > 0) { + if (((uint16_t)micros() - start) >= 1000) { + ms--; + start += 1000; + } + } +} + +/* Delay for the given number of microseconds. Assumes a 8 or 16 MHz clock. */ +void delayMicroseconds(unsigned int us) +{ + // calling avrlib's delay_us() function with low values (e.g. 1 or + // 2 microseconds) gives delays longer than desired. + //delay_us(us); +#if F_CPU >= 20000000L + // for the 20 MHz clock on rare Arduino boards + + // for a one-microsecond delay, simply wait 2 cycle and return. The overhead + // of the function call yields a delay of exactly a one microsecond. + __asm__ __volatile__ ( + "nop" "\n\t" + "nop"); //just waiting 2 cycle + if (--us == 0) + return; + + // the following loop takes a 1/5 of a microsecond (4 cycles) + // per iteration, so execute it five times for each microsecond of + // delay requested. + us = (us<<2) + us; // x5 us + + // account for the time taken in the preceeding commands. + us -= 2; + +#elif F_CPU >= 16000000L + // for the 16 MHz clock on most Arduino boards + + // for a one-microsecond delay, simply return. the overhead + // of the function call yields a delay of approximately 1 1/8 us. + if (--us == 0) + return; + + // the following loop takes a quarter of a microsecond (4 cycles) + // per iteration, so execute it four times for each microsecond of + // delay requested. + us <<= 2; + + // account for the time taken in the preceeding commands. + us -= 2; +#else + // for the 8 MHz internal clock on the ATmega168 + + // for a one- or two-microsecond delay, simply return. the overhead of + // the function calls takes more than two microseconds. can't just + // subtract two, since us is unsigned; we'd overflow. + if (--us == 0) + return; + if (--us == 0) + return; + + // the following loop takes half of a microsecond (4 cycles) + // per iteration, so execute it twice for each microsecond of + // delay requested. + us <<= 1; + + // partially compensate for the time taken by the preceeding commands. + // we can't subtract any more than this or we'd overflow w/ small delays. + us--; +#endif + + // busy wait + __asm__ __volatile__ ( + "1: sbiw %0,1" "\n\t" // 2 cycles + "brne 1b" : "=w" (us) : "0" (us) // 2 cycles + ); +} + +void init() +{ + // this needs to be called before setup() or some functions won't + // work there + sei(); + + // on the ATmega168, timer 0 is also used for fast hardware pwm + // (using phase-correct PWM would mean that timer 0 overflowed half as often + // resulting in different millis() behavior on the ATmega8 and ATmega168) +#if defined(TCCR0A) && defined(WGM01) + sbi(TCCR0A, WGM01); + sbi(TCCR0A, WGM00); +#endif + + // set timer 0 prescale factor to 64 +#if defined(__AVR_ATmega128__) + // CPU specific: different values for the ATmega128 + sbi(TCCR0, CS02); +#elif defined(TCCR0) && defined(CS01) && defined(CS00) + // this combination is for the standard atmega8 + sbi(TCCR0, CS01); + sbi(TCCR0, CS00); +#elif defined(TCCR0B) && defined(CS01) && defined(CS00) + // this combination is for the standard 168/328/1280/2560 + sbi(TCCR0B, CS01); + sbi(TCCR0B, CS00); +#elif defined(TCCR0A) && defined(CS01) && defined(CS00) + // this combination is for the __AVR_ATmega645__ series + sbi(TCCR0A, CS01); + sbi(TCCR0A, CS00); +#else + #error Timer 0 prescale factor 64 not set correctly +#endif + + // enable timer 0 overflow interrupt +#if defined(TIMSK) && defined(TOIE0) + sbi(TIMSK, TOIE0); +#elif defined(TIMSK0) && defined(TOIE0) + sbi(TIMSK0, TOIE0); +#else + #error Timer 0 overflow interrupt not set correctly +#endif + + // timers 1 and 2 are used for phase-correct hardware pwm + // this is better for motors as it ensures an even waveform + // note, however, that fast pwm mode can achieve a frequency of up + // 8 MHz (with a 16 MHz clock) at 50% duty cycle + +#if defined(TCCR1B) && defined(CS11) && defined(CS10) + TCCR1B = 0; + + // set timer 1 prescale factor to 64 + sbi(TCCR1B, CS11); +#if F_CPU >= 8000000L + sbi(TCCR1B, CS10); +#endif +#elif defined(TCCR1) && defined(CS11) && defined(CS10) + sbi(TCCR1, CS11); +#if F_CPU >= 8000000L + sbi(TCCR1, CS10); +#endif +#endif + // put timer 1 in 8-bit phase correct pwm mode +#if defined(TCCR1A) && defined(WGM10) + sbi(TCCR1A, WGM10); +#elif defined(TCCR1) + #warning this needs to be finished +#endif + + // set timer 2 prescale factor to 64 +#if defined(TCCR2) && defined(CS22) + sbi(TCCR2, CS22); +#elif defined(TCCR2B) && defined(CS22) + sbi(TCCR2B, CS22); +#else + #warning Timer 2 not finished (may not be present on this CPU) +#endif + + // configure timer 2 for phase correct pwm (8-bit) +#if defined(TCCR2) && defined(WGM20) + sbi(TCCR2, WGM20); +#elif defined(TCCR2A) && defined(WGM20) + sbi(TCCR2A, WGM20); +#else + #warning Timer 2 not finished (may not be present on this CPU) +#endif + +#if defined(TCCR3B) && defined(CS31) && defined(WGM30) + sbi(TCCR3B, CS31); // set timer 3 prescale factor to 64 + sbi(TCCR3B, CS30); + sbi(TCCR3A, WGM30); // put timer 3 in 8-bit phase correct pwm mode +#endif + +#if defined(TCCR4A) && defined(TCCR4B) && defined(TCCR4D) /* beginning of timer4 block for 32U4 and similar */ + sbi(TCCR4B, CS42); // set timer4 prescale factor to 64 + sbi(TCCR4B, CS41); + sbi(TCCR4B, CS40); + sbi(TCCR4D, WGM40); // put timer 4 in phase- and frequency-correct PWM mode + sbi(TCCR4A, PWM4A); // enable PWM mode for comparator OCR4A + sbi(TCCR4C, PWM4D); // enable PWM mode for comparator OCR4D +#else /* beginning of timer4 block for ATMEGA1280 and ATMEGA2560 */ +#if defined(TCCR4B) && defined(CS41) && defined(WGM40) + sbi(TCCR4B, CS41); // set timer 4 prescale factor to 64 + sbi(TCCR4B, CS40); + sbi(TCCR4A, WGM40); // put timer 4 in 8-bit phase correct pwm mode +#endif +#endif /* end timer4 block for ATMEGA1280/2560 and similar */ + +#if defined(TCCR5B) && defined(CS51) && defined(WGM50) + sbi(TCCR5B, CS51); // set timer 5 prescale factor to 64 + sbi(TCCR5B, CS50); + sbi(TCCR5A, WGM50); // put timer 5 in 8-bit phase correct pwm mode +#endif + +#if defined(ADCSRA) + // set a2d prescale factor to 128 + // 16 MHz / 128 = 125 KHz, inside the desired 50-200 KHz range. + // XXX: this will not work properly for other clock speeds, and + // this code should use F_CPU to determine the prescale factor. + sbi(ADCSRA, ADPS2); + sbi(ADCSRA, ADPS1); + sbi(ADCSRA, ADPS0); + + // enable a2d conversions + sbi(ADCSRA, ADEN); +#endif + + // the bootloader connects pins 0 and 1 to the USART; disconnect them + // here so they can be used as normal digital i/o; they will be + // reconnected in Serial.begin() +#if defined(UCSRB) + UCSRB = 0; +#elif defined(UCSR0B) + UCSR0B = 0; +#endif +} diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/wiring_analog.c b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/wiring_analog.c new file mode 100644 index 000000000..23b01c65a --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/wiring_analog.c @@ -0,0 +1,282 @@ +/* + wiring_analog.c - analog input and output + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2005-2006 David A. Mellis + + 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., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + Modified 28 September 2010 by Mark Sproul + + $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $ +*/ + +#include "wiring_private.h" +#include "pins_arduino.h" + +uint8_t analog_reference = DEFAULT; + +void analogReference(uint8_t mode) +{ + // can't actually set the register here because the default setting + // will connect AVCC and the AREF pin, which would cause a short if + // there's something connected to AREF. + analog_reference = mode; +} + +int analogRead(uint8_t pin) +{ + uint8_t low, high; + +#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + if (pin >= 54) pin -= 54; // allow for channel or pin numbers +#elif defined(__AVR_ATmega32U4__) + if (pin >= 18) pin -= 18; // allow for channel or pin numbers +#elif defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644P__) + if (pin >= 24) pin -= 24; // allow for channel or pin numbers +#else + if (pin >= 14) pin -= 14; // allow for channel or pin numbers +#endif + +#if defined(__AVR_ATmega32U4__) + pin = analogPinToChannel(pin); + ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5); +#elif defined(ADCSRB) && defined(MUX5) + // the MUX5 bit of ADCSRB selects whether we're reading from channels + // 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high). + ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5); +#endif + + // set the analog reference (high two bits of ADMUX) and select the + // channel (low 4 bits). this also sets ADLAR (left-adjust result) + // to 0 (the default). +#if defined(ADMUX) + ADMUX = (analog_reference << 6) | (pin & 0x07); +#endif + + // without a delay, we seem to read from the wrong channel + //delay(1); + +#if defined(ADCSRA) && defined(ADCL) + // start the conversion + sbi(ADCSRA, ADSC); + + // ADSC is cleared when the conversion finishes + while (bit_is_set(ADCSRA, ADSC)); + + // we have to read ADCL first; doing so locks both ADCL + // and ADCH until ADCH is read. reading ADCL second would + // cause the results of each conversion to be discarded, + // as ADCL and ADCH would be locked when it completed. + low = ADCL; + high = ADCH; +#else + // we dont have an ADC, return 0 + low = 0; + high = 0; +#endif + + // combine the two bytes + return (high << 8) | low; +} + +// Right now, PWM output only works on the pins with +// hardware support. These are defined in the appropriate +// pins_*.c file. For the rest of the pins, we default +// to digital output. +void analogWrite(uint8_t pin, int val) +{ + // We need to make sure the PWM output is enabled for those pins + // that support it, as we turn it off when digitally reading or + // writing with them. Also, make sure the pin is in output mode + // for consistenty with Wiring, which doesn't require a pinMode + // call for the analog output pins. + pinMode(pin, OUTPUT); + if (val == 0) + { + digitalWrite(pin, LOW); + } + else if (val == 255) + { + digitalWrite(pin, HIGH); + } + else + { + switch(digitalPinToTimer(pin)) + { + // XXX fix needed for atmega8 + #if defined(TCCR0) && defined(COM00) && !defined(__AVR_ATmega8__) + case TIMER0A: + // connect pwm to pin on timer 0 + sbi(TCCR0, COM00); + OCR0 = val; // set pwm duty + break; + #endif + + #if defined(TCCR0A) && defined(COM0A1) + case TIMER0A: + // connect pwm to pin on timer 0, channel A + sbi(TCCR0A, COM0A1); + OCR0A = val; // set pwm duty + break; + #endif + + #if defined(TCCR0A) && defined(COM0B1) + case TIMER0B: + // connect pwm to pin on timer 0, channel B + sbi(TCCR0A, COM0B1); + OCR0B = val; // set pwm duty + break; + #endif + + #if defined(TCCR1A) && defined(COM1A1) + case TIMER1A: + // connect pwm to pin on timer 1, channel A + sbi(TCCR1A, COM1A1); + OCR1A = val; // set pwm duty + break; + #endif + + #if defined(TCCR1A) && defined(COM1B1) + case TIMER1B: + // connect pwm to pin on timer 1, channel B + sbi(TCCR1A, COM1B1); + OCR1B = val; // set pwm duty + break; + #endif + + #if defined(TCCR2) && defined(COM21) + case TIMER2: + // connect pwm to pin on timer 2 + sbi(TCCR2, COM21); + OCR2 = val; // set pwm duty + break; + #endif + + #if defined(TCCR2A) && defined(COM2A1) + case TIMER2A: + // connect pwm to pin on timer 2, channel A + sbi(TCCR2A, COM2A1); + OCR2A = val; // set pwm duty + break; + #endif + + #if defined(TCCR2A) && defined(COM2B1) + case TIMER2B: + // connect pwm to pin on timer 2, channel B + sbi(TCCR2A, COM2B1); + OCR2B = val; // set pwm duty + break; + #endif + + #if defined(TCCR3A) && defined(COM3A1) + case TIMER3A: + // connect pwm to pin on timer 3, channel A + sbi(TCCR3A, COM3A1); + OCR3A = val; // set pwm duty + break; + #endif + + #if defined(TCCR3A) && defined(COM3B1) + case TIMER3B: + // connect pwm to pin on timer 3, channel B + sbi(TCCR3A, COM3B1); + OCR3B = val; // set pwm duty + break; + #endif + + #if defined(TCCR3A) && defined(COM3C1) + case TIMER3C: + // connect pwm to pin on timer 3, channel C + sbi(TCCR3A, COM3C1); + OCR3C = val; // set pwm duty + break; + #endif + + #if defined(TCCR4A) + case TIMER4A: + //connect pwm to pin on timer 4, channel A + sbi(TCCR4A, COM4A1); + #if defined(COM4A0) // only used on 32U4 + cbi(TCCR4A, COM4A0); + #endif + OCR4A = val; // set pwm duty + break; + #endif + + #if defined(TCCR4A) && defined(COM4B1) + case TIMER4B: + // connect pwm to pin on timer 4, channel B + sbi(TCCR4A, COM4B1); + OCR4B = val; // set pwm duty + break; + #endif + + #if defined(TCCR4A) && defined(COM4C1) + case TIMER4C: + // connect pwm to pin on timer 4, channel C + sbi(TCCR4A, COM4C1); + OCR4C = val; // set pwm duty + break; + #endif + + #if defined(TCCR4C) && defined(COM4D1) + case TIMER4D: + // connect pwm to pin on timer 4, channel D + sbi(TCCR4C, COM4D1); + #if defined(COM4D0) // only used on 32U4 + cbi(TCCR4C, COM4D0); + #endif + OCR4D = val; // set pwm duty + break; + #endif + + + #if defined(TCCR5A) && defined(COM5A1) + case TIMER5A: + // connect pwm to pin on timer 5, channel A + sbi(TCCR5A, COM5A1); + OCR5A = val; // set pwm duty + break; + #endif + + #if defined(TCCR5A) && defined(COM5B1) + case TIMER5B: + // connect pwm to pin on timer 5, channel B + sbi(TCCR5A, COM5B1); + OCR5B = val; // set pwm duty + break; + #endif + + #if defined(TCCR5A) && defined(COM5C1) + case TIMER5C: + // connect pwm to pin on timer 5, channel C + sbi(TCCR5A, COM5C1); + OCR5C = val; // set pwm duty + break; + #endif + + case NOT_ON_TIMER: + default: + if (val < 128) { + digitalWrite(pin, LOW); + } else { + digitalWrite(pin, HIGH); + } + } + } +} + diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/wiring_digital.c b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/wiring_digital.c new file mode 100644 index 000000000..be323b1df --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/wiring_digital.c @@ -0,0 +1,178 @@ +/* + wiring_digital.c - digital input and output functions + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2005-2006 David A. Mellis + + 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., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + Modified 28 September 2010 by Mark Sproul + + $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $ +*/ + +#define ARDUINO_MAIN +#include "wiring_private.h" +#include "pins_arduino.h" + +void pinMode(uint8_t pin, uint8_t mode) +{ + uint8_t bit = digitalPinToBitMask(pin); + uint8_t port = digitalPinToPort(pin); + volatile uint8_t *reg, *out; + + if (port == NOT_A_PIN) return; + + // JWS: can I let the optimizer do this? + reg = portModeRegister(port); + out = portOutputRegister(port); + + if (mode == INPUT) { + uint8_t oldSREG = SREG; + cli(); + *reg &= ~bit; + *out &= ~bit; + SREG = oldSREG; + } else if (mode == INPUT_PULLUP) { + uint8_t oldSREG = SREG; + cli(); + *reg &= ~bit; + *out |= bit; + SREG = oldSREG; + } else { + uint8_t oldSREG = SREG; + cli(); + *reg |= bit; + SREG = oldSREG; + } +} + +// Forcing this inline keeps the callers from having to push their own stuff +// on the stack. It is a good performance win and only takes 1 more byte per +// user than calling. (It will take more bytes on the 168.) +// +// But shouldn't this be moved into pinMode? Seems silly to check and do on +// each digitalread or write. +// +// Mark Sproul: +// - Removed inline. Save 170 bytes on atmega1280 +// - changed to a switch statment; added 32 bytes but much easier to read and maintain. +// - Added more #ifdefs, now compiles for atmega645 +// +//static inline void turnOffPWM(uint8_t timer) __attribute__ ((always_inline)); +//static inline void turnOffPWM(uint8_t timer) +static void turnOffPWM(uint8_t timer) +{ + switch (timer) + { + #if defined(TCCR1A) && defined(COM1A1) + case TIMER1A: cbi(TCCR1A, COM1A1); break; + #endif + #if defined(TCCR1A) && defined(COM1B1) + case TIMER1B: cbi(TCCR1A, COM1B1); break; + #endif + + #if defined(TCCR2) && defined(COM21) + case TIMER2: cbi(TCCR2, COM21); break; + #endif + + #if defined(TCCR0A) && defined(COM0A1) + case TIMER0A: cbi(TCCR0A, COM0A1); break; + #endif + + #if defined(TIMER0B) && defined(COM0B1) + case TIMER0B: cbi(TCCR0A, COM0B1); break; + #endif + #if defined(TCCR2A) && defined(COM2A1) + case TIMER2A: cbi(TCCR2A, COM2A1); break; + #endif + #if defined(TCCR2A) && defined(COM2B1) + case TIMER2B: cbi(TCCR2A, COM2B1); break; + #endif + + #if defined(TCCR3A) && defined(COM3A1) + case TIMER3A: cbi(TCCR3A, COM3A1); break; + #endif + #if defined(TCCR3A) && defined(COM3B1) + case TIMER3B: cbi(TCCR3A, COM3B1); break; + #endif + #if defined(TCCR3A) && defined(COM3C1) + case TIMER3C: cbi(TCCR3A, COM3C1); break; + #endif + + #if defined(TCCR4A) && defined(COM4A1) + case TIMER4A: cbi(TCCR4A, COM4A1); break; + #endif + #if defined(TCCR4A) && defined(COM4B1) + case TIMER4B: cbi(TCCR4A, COM4B1); break; + #endif + #if defined(TCCR4A) && defined(COM4C1) + case TIMER4C: cbi(TCCR4A, COM4C1); break; + #endif + #if defined(TCCR4C) && defined(COM4D1) + case TIMER4D: cbi(TCCR4C, COM4D1); break; + #endif + + #if defined(TCCR5A) + case TIMER5A: cbi(TCCR5A, COM5A1); break; + case TIMER5B: cbi(TCCR5A, COM5B1); break; + case TIMER5C: cbi(TCCR5A, COM5C1); break; + #endif + } +} + +void digitalWrite(uint8_t pin, uint8_t val) +{ + uint8_t timer = digitalPinToTimer(pin); + uint8_t bit = digitalPinToBitMask(pin); + uint8_t port = digitalPinToPort(pin); + volatile uint8_t *out; + + if (port == NOT_A_PIN) return; + + // If the pin that support PWM output, we need to turn it off + // before doing a digital write. + if (timer != NOT_ON_TIMER) turnOffPWM(timer); + + out = portOutputRegister(port); + + uint8_t oldSREG = SREG; + cli(); + + if (val == LOW) { + *out &= ~bit; + } else { + *out |= bit; + } + + SREG = oldSREG; +} + +int digitalRead(uint8_t pin) +{ + uint8_t timer = digitalPinToTimer(pin); + uint8_t bit = digitalPinToBitMask(pin); + uint8_t port = digitalPinToPort(pin); + + if (port == NOT_A_PIN) return LOW; + + // If the pin that support PWM output, we need to turn it off + // before getting a digital reading. + if (timer != NOT_ON_TIMER) turnOffPWM(timer); + + if (*portInputRegister(port) & bit) return HIGH; + return LOW; +} diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/wiring_private.h b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/wiring_private.h new file mode 100644 index 000000000..f67826567 --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/wiring_private.h @@ -0,0 +1,71 @@ +/* + wiring_private.h - Internal header file. + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2005-2006 David A. Mellis + + 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., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + $Id: wiring.h 239 2007-01-12 17:58:39Z mellis $ +*/ + +#ifndef WiringPrivate_h +#define WiringPrivate_h + +#include +#include +#include +#include + +#include "Arduino.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +#ifndef cbi +#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) +#endif +#ifndef sbi +#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) +#endif + +#define EXTERNAL_INT_0 0 +#define EXTERNAL_INT_1 1 +#define EXTERNAL_INT_2 2 +#define EXTERNAL_INT_3 3 +#define EXTERNAL_INT_4 4 +#define EXTERNAL_INT_5 5 +#define EXTERNAL_INT_6 6 +#define EXTERNAL_INT_7 7 + +#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +#define EXTERNAL_NUM_INTERRUPTS 8 +#elif defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644P__) +#define EXTERNAL_NUM_INTERRUPTS 3 +#elif defined(__AVR_ATmega32U4__) +#define EXTERNAL_NUM_INTERRUPTS 4 +#else +#define EXTERNAL_NUM_INTERRUPTS 2 +#endif + +typedef void (*voidFuncPtr)(void); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/wiring_pulse.c b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/wiring_pulse.c new file mode 100644 index 000000000..0d968865d --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/wiring_pulse.c @@ -0,0 +1,69 @@ +/* + wiring_pulse.c - pulseIn() function + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2005-2006 David A. Mellis + + 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., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $ +*/ + +#include "wiring_private.h" +#include "pins_arduino.h" + +/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH + * or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds + * to 3 minutes in length, but must be called at least a few dozen microseconds + * before the start of the pulse. */ +unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout) +{ + // cache the port and bit of the pin in order to speed up the + // pulse width measuring loop and achieve finer resolution. calling + // digitalRead() instead yields much coarser resolution. + uint8_t bit = digitalPinToBitMask(pin); + uint8_t port = digitalPinToPort(pin); + uint8_t stateMask = (state ? bit : 0); + unsigned long width = 0; // keep initialization out of time critical area + + // convert the timeout from microseconds to a number of times through + // the initial loop; it takes 16 clock cycles per iteration. + unsigned long numloops = 0; + unsigned long maxloops = microsecondsToClockCycles(timeout) / 16; + + // wait for any previous pulse to end + while ((*portInputRegister(port) & bit) == stateMask) + if (numloops++ == maxloops) + return 0; + + // wait for the pulse to start + while ((*portInputRegister(port) & bit) != stateMask) + if (numloops++ == maxloops) + return 0; + + // wait for the pulse to stop + while ((*portInputRegister(port) & bit) == stateMask) { + if (numloops++ == maxloops) + return 0; + width++; + } + + // convert the reading to microseconds. The loop has been determined + // to be 20 clock cycles long and have about 16 clocks between the edge + // and the start of the loop. There will be some error introduced by + // the interrupt handlers. + return clockCyclesToMicroseconds(width * 21 + 16); +} diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/wiring_shift.c b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/wiring_shift.c new file mode 100644 index 000000000..cfe786758 --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/cores/arduino/wiring_shift.c @@ -0,0 +1,55 @@ +/* + wiring_shift.c - shiftOut() function + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2005-2006 David A. Mellis + + 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., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $ +*/ + +#include "wiring_private.h" + +uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) { + uint8_t value = 0; + uint8_t i; + + for (i = 0; i < 8; ++i) { + digitalWrite(clockPin, HIGH); + if (bitOrder == LSBFIRST) + value |= digitalRead(dataPin) << i; + else + value |= digitalRead(dataPin) << (7 - i); + digitalWrite(clockPin, LOW); + } + return value; +} + +void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val) +{ + uint8_t i; + + for (i = 0; i < 8; i++) { + if (bitOrder == LSBFIRST) + digitalWrite(dataPin, !!(val & (1 << i))); + else + digitalWrite(dataPin, !!(val & (1 << (7 - i)))); + + digitalWrite(clockPin, HIGH); + digitalWrite(clockPin, LOW); + } +} diff --git a/ArduinoAddons/Arduino_1.x.x/hardware/rambo/variants/standard/pins_arduino.h b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/variants/standard/pins_arduino.h new file mode 100644 index 000000000..f49a23fc0 --- /dev/null +++ b/ArduinoAddons/Arduino_1.x.x/hardware/rambo/variants/standard/pins_arduino.h @@ -0,0 +1,411 @@ +/* + pins_arduino.h - Pin definition functions for Arduino + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2007 David A. Mellis + + 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., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + $Id: wiring.h 249 2007-02-03 16:52:51Z mellis $ +*/ + +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include + +#define NUM_DIGITAL_PINS 82 +#define NUM_ANALOG_INPUTS 16 +#define analogInputToDigitalPin(p) ((p < 16) ? (p) + 54 : -1) +#define digitalPinHasPWM(p) (((p) >= 2 && (p) <= 13) || ((p) >= 44 && (p)<= 46)) + +static const uint8_t SS = 53; +static const uint8_t MOSI = 51; +static const uint8_t MISO = 50; +static const uint8_t SCK = 52; + +static const uint8_t SDA = 20; +static const uint8_t SCL = 21; +static const uint8_t LED_BUILTIN = 13; + +static const uint8_t A0 = 54; +static const uint8_t A1 = 55; +static const uint8_t A2 = 56; +static const uint8_t A3 = 57; +static const uint8_t A4 = 58; +static const uint8_t A5 = 59; +static const uint8_t A6 = 60; +static const uint8_t A7 = 61; +static const uint8_t A8 = 62; +static const uint8_t A9 = 63; +static const uint8_t A10 = 64; +static const uint8_t A11 = 65; +static const uint8_t A12 = 66; +static const uint8_t A13 = 67; +static const uint8_t A14 = 68; +static const uint8_t A15 = 69; + +// A majority of the pins are NOT PCINTs, SO BE WARNED (i.e. you cannot use them as receive pins) +// Only pins available for RECEIVE (TRANSMIT can be on any pin): +// (I've deliberately left out pin mapping to the Hardware USARTs - seems senseless to me) +// Pins: 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69 + +#define digitalPinToPCICR(p) ( (((p) >= 10) && ((p) <= 13)) || \ + (((p) >= 50) && ((p) <= 53)) || \ + (((p) >= 62) && ((p) <= 69)) ? (&PCICR) : ((uint8_t *)0) ) + +#define digitalPinToPCICRbit(p) ( (((p) >= 10) && ((p) <= 13)) || (((p) >= 50) && ((p) <= 53)) ? 0 : \ + ( (((p) >= 62) && ((p) <= 69)) ? 2 : \ + 0 ) ) + +#define digitalPinToPCMSK(p) ( (((p) >= 10) && ((p) <= 13)) || (((p) >= 50) && ((p) <= 53)) ? (&PCMSK0) : \ + ( (((p) >= 62) && ((p) <= 69)) ? (&PCMSK2) : \ + ((uint8_t *)0) ) ) + +#define digitalPinToPCMSKbit(p) ( (((p) >= 10) && ((p) <= 13)) ? ((p) - 6) : \ + ( ((p) == 50) ? 3 : \ + ( ((p) == 51) ? 2 : \ + ( ((p) == 52) ? 1 : \ + ( ((p) == 53) ? 0 : \ + ( (((p) >= 62) && ((p) <= 69)) ? ((p) - 62) : \ + 0 ) ) ) ) ) ) + +#ifdef ARDUINO_MAIN + +const uint16_t PROGMEM port_to_mode_PGM[] = { + NOT_A_PORT, + (uint16_t) &DDRA, + (uint16_t) &DDRB, + (uint16_t) &DDRC, + (uint16_t) &DDRD, + (uint16_t) &DDRE, + (uint16_t) &DDRF, + (uint16_t) &DDRG, + (uint16_t) &DDRH, + NOT_A_PORT, + (uint16_t) &DDRJ, + (uint16_t) &DDRK, + (uint16_t) &DDRL, +}; + +const uint16_t PROGMEM port_to_output_PGM[] = { + NOT_A_PORT, + (uint16_t) &PORTA, + (uint16_t) &PORTB, + (uint16_t) &PORTC, + (uint16_t) &PORTD, + (uint16_t) &PORTE, + (uint16_t) &PORTF, + (uint16_t) &PORTG, + (uint16_t) &PORTH, + NOT_A_PORT, + (uint16_t) &PORTJ, + (uint16_t) &PORTK, + (uint16_t) &PORTL, +}; + +const uint16_t PROGMEM port_to_input_PGM[] = { + NOT_A_PIN, + (uint16_t) &PINA, + (uint16_t) &PINB, + (uint16_t) &PINC, + (uint16_t) &PIND, + (uint16_t) &PINE, + (uint16_t) &PINF, + (uint16_t) &PING, + (uint16_t) &PINH, + NOT_A_PIN, + (uint16_t) &PINJ, + (uint16_t) &PINK, + (uint16_t) &PINL, +}; + +const uint8_t PROGMEM digital_pin_to_port_PGM[] = { + // PORTLIST + // ------------------------------------------- + PE , // PE 0 ** 0 ** USART0_RX + PE , // PE 1 ** 1 ** USART0_TX + PE , // PE 4 ** 2 ** PWM2 + PE , // PE 5 ** 3 ** PWM3 + PG , // PG 5 ** 4 ** PWM4 + PE , // PE 3 ** 5 ** PWM5 + PH , // PH 3 ** 6 ** PWM6 + PH , // PH 4 ** 7 ** PWM7 + PH , // PH 5 ** 8 ** PWM8 + PH , // PH 6 ** 9 ** PWM9 + PB , // PB 4 ** 10 ** PWM10 + PB , // PB 5 ** 11 ** PWM11 + PB , // PB 6 ** 12 ** PWM12 + PB , // PB 7 ** 13 ** PWM13 + PJ , // PJ 1 ** 14 ** USART3_TX + PJ , // PJ 0 ** 15 ** USART3_RX + PH , // PH 1 ** 16 ** USART2_TX + PH , // PH 0 ** 17 ** USART2_RX + PD , // PD 3 ** 18 ** USART1_TX + PD , // PD 2 ** 19 ** USART1_RX + PD , // PD 1 ** 20 ** I2C_SDA + PD , // PD 0 ** 21 ** I2C_SCL + PA , // PA 0 ** 22 ** D22 + PA , // PA 1 ** 23 ** D23 + PA , // PA 2 ** 24 ** D24 + PA , // PA 3 ** 25 ** D25 + PA , // PA 4 ** 26 ** D26 + PA , // PA 5 ** 27 ** D27 + PA , // PA 6 ** 28 ** D28 + PA , // PA 7 ** 29 ** D29 + PC , // PC 7 ** 30 ** D30 + PC , // PC 6 ** 31 ** D31 + PC , // PC 5 ** 32 ** D32 + PC , // PC 4 ** 33 ** D33 + PC , // PC 3 ** 34 ** D34 + PC , // PC 2 ** 35 ** D35 + PC , // PC 1 ** 36 ** D36 + PC , // PC 0 ** 37 ** D37 + PD , // PD 7 ** 38 ** D38 + PG , // PG 2 ** 39 ** D39 + PG , // PG 1 ** 40 ** D40 + PG , // PG 0 ** 41 ** D41 + PL , // PL 7 ** 42 ** D42 + PL , // PL 6 ** 43 ** D43 + PL , // PL 5 ** 44 ** D44 + PL , // PL 4 ** 45 ** D45 + PL , // PL 3 ** 46 ** D46 + PL , // PL 2 ** 47 ** D47 + PL , // PL 1 ** 48 ** D48 + PL , // PL 0 ** 49 ** D49 + PB , // PB 3 ** 50 ** SPI_MISO + PB , // PB 2 ** 51 ** SPI_MOSI + PB , // PB 1 ** 52 ** SPI_SCK + PB , // PB 0 ** 53 ** SPI_SS + PF , // PF 0 ** 54 ** A0 + PF , // PF 1 ** 55 ** A1 + PF , // PF 2 ** 56 ** A2 + PF , // PF 3 ** 57 ** A3 + PF , // PF 4 ** 58 ** A4 + PF , // PF 5 ** 59 ** A5 + PF , // PF 6 ** 60 ** A6 + PF , // PF 7 ** 61 ** A7 + PK , // PK 0 ** 62 ** A8 + PK , // PK 1 ** 63 ** A9 + PK , // PK 2 ** 64 ** A10 + PK , // PK 3 ** 65 ** A11 + PK , // PK 4 ** 66 ** A12 + PK , // PK 5 ** 67 ** A13 + PK , // PK 6 ** 68 ** A14 + PK , // PK 7 ** 69 ** A15 + PG , // PG 4 ** 70 ** D70 + PG , // PG 3 ** 71 ** D71 + PJ , // PJ 2 ** 72 ** D72 + PJ , // PJ 3 ** 73 ** D73 + PJ , // PJ 7 ** 74 ** D74 + PJ , // PJ 4 ** 75 ** D75 + PJ , // PJ 5 ** 76 ** D76 + PJ , // PJ 6 ** 77 ** D77 + PE , // PE 2 ** 78 ** D78 + PE , // PE 6 ** 79 ** D79 + PE , // PE 7 ** 80 ** D80 + PD , // PD 4 ** 81 ** D81 + PD , // PD 5 ** 82 ** D82 + PD , // PD 6 ** 83 ** D83 + PH , // PH 2 ** 84 ** D84 + PH , // PH 7 ** 85 ** D85 +}; + +const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = { + // PIN IN PORT + // ------------------------------------------- + _BV( 0 ) , // PE 0 ** 0 ** USART0_RX + _BV( 1 ) , // PE 1 ** 1 ** USART0_TX + _BV( 4 ) , // PE 4 ** 2 ** PWM2 + _BV( 5 ) , // PE 5 ** 3 ** PWM3 + _BV( 5 ) , // PG 5 ** 4 ** PWM4 + _BV( 3 ) , // PE 3 ** 5 ** PWM5 + _BV( 3 ) , // PH 3 ** 6 ** PWM6 + _BV( 4 ) , // PH 4 ** 7 ** PWM7 + _BV( 5 ) , // PH 5 ** 8 ** PWM8 + _BV( 6 ) , // PH 6 ** 9 ** PWM9 + _BV( 4 ) , // PB 4 ** 10 ** PWM10 + _BV( 5 ) , // PB 5 ** 11 ** PWM11 + _BV( 6 ) , // PB 6 ** 12 ** PWM12 + _BV( 7 ) , // PB 7 ** 13 ** PWM13 + _BV( 1 ) , // PJ 1 ** 14 ** USART3_TX + _BV( 0 ) , // PJ 0 ** 15 ** USART3_RX + _BV( 1 ) , // PH 1 ** 16 ** USART2_TX + _BV( 0 ) , // PH 0 ** 17 ** USART2_RX + _BV( 3 ) , // PD 3 ** 18 ** USART1_TX + _BV( 2 ) , // PD 2 ** 19 ** USART1_RX + _BV( 1 ) , // PD 1 ** 20 ** I2C_SDA + _BV( 0 ) , // PD 0 ** 21 ** I2C_SCL + _BV( 0 ) , // PA 0 ** 22 ** D22 + _BV( 1 ) , // PA 1 ** 23 ** D23 + _BV( 2 ) , // PA 2 ** 24 ** D24 + _BV( 3 ) , // PA 3 ** 25 ** D25 + _BV( 4 ) , // PA 4 ** 26 ** D26 + _BV( 5 ) , // PA 5 ** 27 ** D27 + _BV( 6 ) , // PA 6 ** 28 ** D28 + _BV( 7 ) , // PA 7 ** 29 ** D29 + _BV( 7 ) , // PC 7 ** 30 ** D30 + _BV( 6 ) , // PC 6 ** 31 ** D31 + _BV( 5 ) , // PC 5 ** 32 ** D32 + _BV( 4 ) , // PC 4 ** 33 ** D33 + _BV( 3 ) , // PC 3 ** 34 ** D34 + _BV( 2 ) , // PC 2 ** 35 ** D35 + _BV( 1 ) , // PC 1 ** 36 ** D36 + _BV( 0 ) , // PC 0 ** 37 ** D37 + _BV( 7 ) , // PD 7 ** 38 ** D38 + _BV( 2 ) , // PG 2 ** 39 ** D39 + _BV( 1 ) , // PG 1 ** 40 ** D40 + _BV( 0 ) , // PG 0 ** 41 ** D41 + _BV( 7 ) , // PL 7 ** 42 ** D42 + _BV( 6 ) , // PL 6 ** 43 ** D43 + _BV( 5 ) , // PL 5 ** 44 ** D44 + _BV( 4 ) , // PL 4 ** 45 ** D45 + _BV( 3 ) , // PL 3 ** 46 ** D46 + _BV( 2 ) , // PL 2 ** 47 ** D47 + _BV( 1 ) , // PL 1 ** 48 ** D48 + _BV( 0 ) , // PL 0 ** 49 ** D49 + _BV( 3 ) , // PB 3 ** 50 ** SPI_MISO + _BV( 2 ) , // PB 2 ** 51 ** SPI_MOSI + _BV( 1 ) , // PB 1 ** 52 ** SPI_SCK + _BV( 0 ) , // PB 0 ** 53 ** SPI_SS + _BV( 0 ) , // PF 0 ** 54 ** A0 + _BV( 1 ) , // PF 1 ** 55 ** A1 + _BV( 2 ) , // PF 2 ** 56 ** A2 + _BV( 3 ) , // PF 3 ** 57 ** A3 + _BV( 4 ) , // PF 4 ** 58 ** A4 + _BV( 5 ) , // PF 5 ** 59 ** A5 + _BV( 6 ) , // PF 6 ** 60 ** A6 + _BV( 7 ) , // PF 7 ** 61 ** A7 + _BV( 0 ) , // PK 0 ** 62 ** A8 + _BV( 1 ) , // PK 1 ** 63 ** A9 + _BV( 2 ) , // PK 2 ** 64 ** A10 + _BV( 3 ) , // PK 3 ** 65 ** A11 + _BV( 4 ) , // PK 4 ** 66 ** A12 + _BV( 5 ) , // PK 5 ** 67 ** A13 + _BV( 6 ) , // PK 6 ** 68 ** A14 + _BV( 7 ) , // PK 7 ** 69 ** A15 + _BV( 4 ) , // PG 4 ** 70 ** D70 + _BV( 3 ) , // PG 3 ** 71 ** D71 + _BV( 2 ) , // PJ 2 ** 72 ** D72 + _BV( 3 ) , // PJ 3 ** 73 ** D73 + _BV( 7 ) , // PJ 7 ** 74 ** D74 + _BV( 4 ) , // PJ 4 ** 75 ** D75 + _BV( 5 ) , // PJ 5 ** 76 ** D76 + _BV( 6 ) , // PJ 6 ** 77 ** D77 + _BV( 2 ) , // PE 2 ** 78 ** D78 + _BV( 6 ) , // PE 6 ** 79 ** D79 + _BV( 7 ) , // PE 7 ** 80 ** D80 + _BV( 4 ) , // PD 4 ** 81 ** D81 + _BV( 5 ) , // PD 5 ** 82 ** D82 + _BV( 6 ) , // PD 6 ** 83 ** D83 + _BV( 2 ) , // PH 2 ** 84 ** D84 + _BV( 7 ) , // PH 7 ** 85 ** D85 +}; + +const uint8_t PROGMEM digital_pin_to_timer_PGM[] = { + // TIMERS + // ------------------------------------------- + NOT_ON_TIMER , // PE 0 ** 0 ** USART0_RX + NOT_ON_TIMER , // PE 1 ** 1 ** USART0_TX + TIMER3B , // PE 4 ** 2 ** PWM2 + TIMER3C , // PE 5 ** 3 ** PWM3 + TIMER0B , // PG 5 ** 4 ** PWM4 + TIMER3A , // PE 3 ** 5 ** PWM5 + TIMER4A , // PH 3 ** 6 ** PWM6 + TIMER4B , // PH 4 ** 7 ** PWM7 + TIMER4C , // PH 5 ** 8 ** PWM8 + TIMER2B , // PH 6 ** 9 ** PWM9 + TIMER2A , // PB 4 ** 10 ** PWM10 + TIMER1A , // PB 5 ** 11 ** PWM11 + TIMER1B , // PB 6 ** 12 ** PWM12 + TIMER0A , // PB 7 ** 13 ** PWM13 + NOT_ON_TIMER , // PJ 1 ** 14 ** USART3_TX + NOT_ON_TIMER , // PJ 0 ** 15 ** USART3_RX + NOT_ON_TIMER , // PH 1 ** 16 ** USART2_TX + NOT_ON_TIMER , // PH 0 ** 17 ** USART2_RX + NOT_ON_TIMER , // PD 3 ** 18 ** USART1_TX + NOT_ON_TIMER , // PD 2 ** 19 ** USART1_RX + NOT_ON_TIMER , // PD 1 ** 20 ** I2C_SDA + NOT_ON_TIMER , // PD 0 ** 21 ** I2C_SCL + NOT_ON_TIMER , // PA 0 ** 22 ** D22 + NOT_ON_TIMER , // PA 1 ** 23 ** D23 + NOT_ON_TIMER , // PA 2 ** 24 ** D24 + NOT_ON_TIMER , // PA 3 ** 25 ** D25 + NOT_ON_TIMER , // PA 4 ** 26 ** D26 + NOT_ON_TIMER , // PA 5 ** 27 ** D27 + NOT_ON_TIMER , // PA 6 ** 28 ** D28 + NOT_ON_TIMER , // PA 7 ** 29 ** D29 + NOT_ON_TIMER , // PC 7 ** 30 ** D30 + NOT_ON_TIMER , // PC 6 ** 31 ** D31 + NOT_ON_TIMER , // PC 5 ** 32 ** D32 + NOT_ON_TIMER , // PC 4 ** 33 ** D33 + NOT_ON_TIMER , // PC 3 ** 34 ** D34 + NOT_ON_TIMER , // PC 2 ** 35 ** D35 + NOT_ON_TIMER , // PC 1 ** 36 ** D36 + NOT_ON_TIMER , // PC 0 ** 37 ** D37 + NOT_ON_TIMER , // PD 7 ** 38 ** D38 + NOT_ON_TIMER , // PG 2 ** 39 ** D39 + NOT_ON_TIMER , // PG 1 ** 40 ** D40 + NOT_ON_TIMER , // PG 0 ** 41 ** D41 + NOT_ON_TIMER , // PL 7 ** 42 ** D42 + NOT_ON_TIMER , // PL 6 ** 43 ** D43 + TIMER5C , // PL 5 ** 44 ** D44 + TIMER5B , // PL 4 ** 45 ** D45 + TIMER5A , // PL 3 ** 46 ** D46 + NOT_ON_TIMER , // PL 2 ** 47 ** D47 + NOT_ON_TIMER , // PL 1 ** 48 ** D48 + NOT_ON_TIMER , // PL 0 ** 49 ** D49 + NOT_ON_TIMER , // PB 3 ** 50 ** SPI_MISO + NOT_ON_TIMER , // PB 2 ** 51 ** SPI_MOSI + NOT_ON_TIMER , // PB 1 ** 52 ** SPI_SCK + NOT_ON_TIMER , // PB 0 ** 53 ** SPI_SS + NOT_ON_TIMER , // PF 0 ** 54 ** A0 + NOT_ON_TIMER , // PF 1 ** 55 ** A1 + NOT_ON_TIMER , // PF 2 ** 56 ** A2 + NOT_ON_TIMER , // PF 3 ** 57 ** A3 + NOT_ON_TIMER , // PF 4 ** 58 ** A4 + NOT_ON_TIMER , // PF 5 ** 59 ** A5 + NOT_ON_TIMER , // PF 6 ** 60 ** A6 + NOT_ON_TIMER , // PF 7 ** 61 ** A7 + NOT_ON_TIMER , // PK 0 ** 62 ** A8 + NOT_ON_TIMER , // PK 1 ** 63 ** A9 + NOT_ON_TIMER , // PK 2 ** 64 ** A10 + NOT_ON_TIMER , // PK 3 ** 65 ** A11 + NOT_ON_TIMER , // PK 4 ** 66 ** A12 + NOT_ON_TIMER , // PK 5 ** 67 ** A13 + NOT_ON_TIMER , // PK 6 ** 68 ** A14 + NOT_ON_TIMER , // PK 7 ** 69 ** A15 + NOT_ON_TIMER , // PG 4 ** 70 ** D70 + NOT_ON_TIMER , // PG 3 ** 71 ** D71 + NOT_ON_TIMER , // PJ 2 ** 72 ** D72 + NOT_ON_TIMER , // PJ 3 ** 73 ** D73 + NOT_ON_TIMER , // PJ 7 ** 74 ** D74 + NOT_ON_TIMER , // PJ 4 ** 75 ** D75 + NOT_ON_TIMER , // PJ 5 ** 76 ** D76 + NOT_ON_TIMER , // PJ 6 ** 77 ** D77 + NOT_ON_TIMER , // PE 2 ** 78 ** D78 + NOT_ON_TIMER , // PE 6 ** 79 ** D79 + NOT_ON_TIMER , // PE 7 ** 80 ** D80 + NOT_ON_TIMER , // PD 4 ** 81 ** D81 + NOT_ON_TIMER , // PD 5 ** 82 ** D82 + NOT_ON_TIMER , // PD 6 ** 83 ** D83 + NOT_ON_TIMER , // PH 2 ** 84 ** D84 + NOT_ON_TIMER , // PH 7 ** 85 ** D85 +}; + +#endif + +#endif diff --git a/Marlin/BlinkM.cpp b/Marlin/BlinkM.cpp new file mode 100644 index 000000000..de604ecd3 --- /dev/null +++ b/Marlin/BlinkM.cpp @@ -0,0 +1,29 @@ +/* + BlinkM.cpp - Library for controlling a BlinkM over i2c + Created by Tim Koster, August 21 2013. +*/ +#include "Marlin.h" +#ifdef BLINKM + +#if (ARDUINO >= 100) + # include "Arduino.h" +#else + # include "WProgram.h" +#endif + +#include "BlinkM.h" + +void SendColors(byte red, byte grn, byte blu) +{ + Wire.begin(); + Wire.beginTransmission(0x09); + Wire.write('o'); //to disable ongoing script, only needs to be used once + Wire.write('n'); + Wire.write(red); + Wire.write(grn); + Wire.write(blu); + Wire.endTransmission(); +} + +#endif //BLINKM + diff --git a/Marlin/BlinkM.h b/Marlin/BlinkM.h new file mode 100644 index 000000000..513682878 --- /dev/null +++ b/Marlin/BlinkM.h @@ -0,0 +1,14 @@ +/* + BlinkM.h + Library header file for BlinkM library + */ +#if (ARDUINO >= 100) + # include "Arduino.h" +#else + # include "WProgram.h" +#endif + +#include "Wire.h" + +void SendColors(byte red, byte grn, byte blu); + diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index db02b1d5f..46d6b96dd 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -5,6 +5,13 @@ // Advanced settings can be found in Configuration_adv.h // BASIC SETTINGS: select your board type, temperature sensor type, axis scaling, and endstop configuration +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer replace the configuration files with the files in the +// example_configurations/delta directory. +// + // User-specified version info of this build to display in [Pronterface, etc] terminal window during // startup. Implementation of an idea by Prof Braino to inform user that any changes made to this // build by the user have been successfully uploaded into firmware. @@ -16,15 +23,21 @@ // Serial port 0 is still used by the Arduino bootloader regardless of this setting. #define SERIAL_PORT 0 +// This determines the communication speed of the printer // This determines the communication speed of the printer #define BAUDRATE 250000 -//#define BAUDRATE 115200 + +// This enables the serial port associated to the Bluetooth interface +//#define BTENABLED // Enable BT interface on AT90USB devices + //// The following define selects which electronics board you have. Please choose the one that matches your setup // 10 = Gen7 custom (Alfons3 Version) "https://github.com/Alfons3/Generation_7_Electronics" // 11 = Gen7 v1.1, v1.2 = 11 // 12 = Gen7 v1.3 // 13 = Gen7 v1.4 +// 2 = Cheaptronic v1.0 +// 20 = Sethi 3D_1 // 3 = MEGA/RAMPS up to 1.2 = 3 // 33 = RAMPS 1.3 / 1.4 (Power outputs: Extruder, Fan, Bed) // 34 = RAMPS 1.3 / 1.4 (Power outputs: Extruder0, Extruder1, Bed) @@ -38,21 +51,27 @@ // 64 = STB V1.1 // 65 = Azteeg X1 // 66 = Melzi with ATmega1284 (MaKr3d version) +// 67 = Azteeg X3 +// 68 = Azteeg X3 Pro // 7 = Ultimaker // 71 = Ultimaker (Older electronics. Pre 1.5.4. This is rare) +// 72 = Ultimainboard 2.x (Uses TEMP_SENSOR 20) // 77 = 3Drag Controller // 8 = Teensylu // 80 = Rumba // 81 = Printrboard (AT90USB1286) // 82 = Brainwave (AT90USB646) +// 83 = SAV Mk-I (AT90USB1286) +// 84 = Teensy++2.0 (AT90USB1286) // CLI compile: DEFINES=AT90USBxx_TEENSYPP_ASSIGNMENTS HARDWARE_MOTHERBOARD=84 make // 9 = Gen3+ // 70 = Megatronics // 701= Megatronics v2.0 // 702= Minitronics v1.0 // 90 = Alpha OMCA board // 91 = Final OMCA board -// 301 = Rambo +// 301= Rambo // 21 = Elefu Ra Board (v3) +// 88 = 5DPrint D8 Driver Board #ifndef MOTHERBOARD #define MOTHERBOARD 7 @@ -61,6 +80,10 @@ // Define this to set a custom name for your generic Mendel, // #define CUSTOM_MENDEL_NAME "This Mendel" +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4) +// #define MACHINE_UUID "00000000-0000-0000-0000-000000000000" + // This defines the number of extruders #define EXTRUDERS 1 @@ -70,42 +93,8 @@ #define POWER_SUPPLY 1 - -//=========================================================================== -//============================== Delta Settings ============================= -//=========================================================================== -// Enable DELTA kinematics -//#define DELTA - -// Make delta curves from many straight lines (linear interpolation). -// This is a trade-off between visible corners (not enough segments) -// and processor overload (too many expensive sqrt calls). -#define DELTA_SEGMENTS_PER_SECOND 200 - -// Center-to-center distance of the holes in the diagonal push rods. -#define DELTA_DIAGONAL_ROD 250.0 // mm - -// Horizontal offset from middle of printer to smooth rod center. -#define DELTA_SMOOTH_ROD_OFFSET 175.0 // mm - -// Horizontal offset of the universal joints on the end effector. -#define DELTA_EFFECTOR_OFFSET 33.0 // mm - -// Horizontal offset of the universal joints on the carriages. -#define DELTA_CARRIAGE_OFFSET 18.0 // mm - -// Effective horizontal distance bridged by diagonal push rods. -#define DELTA_RADIUS (DELTA_SMOOTH_ROD_OFFSET-DELTA_EFFECTOR_OFFSET-DELTA_CARRIAGE_OFFSET) - -// Effective X/Y positions of the three vertical towers. -#define SIN_60 0.8660254037844386 -#define COS_60 0.5 -#define DELTA_TOWER1_X -SIN_60*DELTA_RADIUS // front left tower -#define DELTA_TOWER1_Y -COS_60*DELTA_RADIUS -#define DELTA_TOWER2_X SIN_60*DELTA_RADIUS // front right tower -#define DELTA_TOWER2_Y -COS_60*DELTA_RADIUS -#define DELTA_TOWER3_X 0.0 // back middle tower -#define DELTA_TOWER3_Y DELTA_RADIUS +// Define this to have the electronics keep the power supply off on startup. If you don't know what this is leave it. +// #define PS_DEFAULT_OFF //=========================================================================== //=============================Thermal Settings ============================ @@ -119,21 +108,31 @@ // 0 is not used // 1 is 100k thermistor - best choice for EPCOS 100k (4.7k pullup) // 2 is 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) -// 3 is mendel-parts thermistor (4.7k pullup) +// 3 is Mendel-parts thermistor (4.7k pullup) // 4 is 10k thermistor !! do not use it for a hotend. It gives bad resolution at high temp. !! -// 5 is 100K thermistor - ATC Semitec 104GT-2 (Used in ParCan) (4.7k pullup) +// 5 is 100K thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (4.7k pullup) // 6 is 100k EPCOS - Not as accurate as table 1 (created using a fluke thermocouple) (4.7k pullup) // 7 is 100k Honeywell thermistor 135-104LAG-J01 (4.7k pullup) +// 71 is 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) // 8 is 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) // 9 is 100k GE Sensing AL03006-58.2K-97-G1 (4.7k pullup) // 10 is 100k RS thermistor 198-961 (4.7k pullup) -// 60 is 100k Maker's Tool Works Kapton Bed Thermister +// 11 is 100k beta 3950 1% thermistor (4.7k pullup) +// 12 is 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) (calibrated for Makibox hot bed) +// 20 is the PT100 circuit found in the Ultimainboard V2.x +// 60 is 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 // // 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) -// 55 is 100k thermistor - ATC Semitec 104GT-2 (Used in ParCan) (1k pullup) +// 55 is 100k thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (1k pullup) +// +// 1047 is Pt1000 with 4k7 pullup +// 1010 is Pt1000 with 1k pullup (non standard) +// 147 is Pt100 with 4k7 pullup +// 110 is Pt100 with 1k pullup (non standard) +// 70 is 500C thermistor for Pico hot end #define TEMP_SENSOR_0 -1 #define TEMP_SENSOR_1 -1 @@ -141,7 +140,7 @@ #define TEMP_SENSOR_BED 0 // This makes temp sensor 1 a redundant sensor for sensor 0. If the temperatures difference between these sensors is to high the print will be aborted. -//#define TEMP_SENSOR_1_AS_REDUNDANT +//#define TEMP_SENSOR_1_AS_REDUNDANT #define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 // Actual temperature must be close to target for this long before M109 returns success @@ -170,6 +169,10 @@ // HEATER_BED_DUTY_CYCLE_DIVIDER intervals. //#define HEATER_BED_DUTY_CYCLE_DIVIDER 4 +// If you want the M105 heater power reported in watts, define the BED_WATTS, and (shared for all extruders) EXTRUDER_WATTS +//#define EXTRUDER_WATTS (12.0*12.0/6.7) // P=I^2/R +//#define BED_WATTS (12.0*12.0/1.1) // P=I^2/R + // PID settings: // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP @@ -182,15 +185,15 @@ // is more then PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max. #define PID_INTEGRAL_DRIVE_MAX 255 //limit for the integral term #define K1 0.95 //smoothing factor within the PID - #define PID_dT ((16.0 * 8.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the temperature routine + #define PID_dT ((OVERSAMPLENR * 8.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the temperature routine -// If you are using a preconfigured hotend then you can use one of the value sets by uncommenting it +// If you are using a pre-configured 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 -// Makergear +// MakerGear // #define DEFAULT_Kp 7.0 // #define DEFAULT_Ki 0.1 // #define DEFAULT_Kd 12 @@ -248,6 +251,44 @@ #define EXTRUDE_MINTEMP 170 #define EXTRUDE_MAXLENGTH (X_MAX_LENGTH+Y_MAX_LENGTH) //prevent extrusion of very large distances. +/*================== Thermal Runaway Protection ============================== +This is a feature to protect your printer from burn up in flames if it has +a thermistor coming off place (this happened to a friend of mine recently and +motivated me writing this feature). + +The issue: If a thermistor come off, it will read a lower temperature than actual. +The system will turn the heater on forever, burning up the filament and anything +else around. + +After the temperature reaches the target for the first time, this feature will +start measuring for how long the current temperature stays below the target +minus _HYSTERESIS (set_temperature - THERMAL_RUNAWAY_PROTECTION_HYSTERESIS). + +If it stays longer than _PERIOD, it means the thermistor temperature +cannot catch up with the target, so something *may be* wrong. Then, to be on the +safe side, the system will he halt. + +Bear in mind the count down will just start AFTER the first time the +thermistor temperature is over the target, so you will have no problem if +your extruder heater takes 2 minutes to hit the target on heating. + +*/ +// If you want to enable this feature for all your extruder heaters, +// uncomment the 2 defines below: + +// Parameters for all extruder heaters +//#define THERMAL_RUNAWAY_PROTECTION_PERIOD 40 //in seconds +//#define THERMAL_RUNAWAY_PROTECTION_HYSTERESIS 4 // in degree Celsius + +// If you want to enable this feature for your bed heater, +// uncomment the 2 defines below: + +// Parameters for the bed heater +//#define THERMAL_RUNAWAY_PROTECTION_BED_PERIOD 20 //in seconds +//#define THERMAL_RUNAWAY_PROTECTION_BED_HYSTERESIS 2 // in degree Celsius +//=========================================================================== + + //=========================================================================== //=============================Mechanical Settings=========================== //=========================================================================== @@ -259,7 +300,7 @@ #define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors #ifndef ENDSTOPPULLUPS - // fine Enstop settings: Individual Pullups. will be ignored if ENDSTOPPULLUPS is defined + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined // #define ENDSTOPPULLUP_XMAX // #define ENDSTOPPULLUP_YMAX // #define ENDSTOPPULLUP_ZMAX @@ -278,9 +319,12 @@ #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_MIN_ENDSTOP_INVERTING = true; // set to true to invert the logic of the endstop. +const bool Y_MIN_ENDSTOP_INVERTING = true; // set to true to invert the logic of the endstop. +const bool Z_MIN_ENDSTOP_INVERTING = true; // set to true to invert the logic of the endstop. +const bool X_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of the endstop. +const bool Y_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of the endstop. +const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of the endstop. //#define DISABLE_MAX_ENDSTOPS //#define DISABLE_MIN_ENDSTOPS @@ -300,6 +344,7 @@ const bool Z_ENDSTOPS_INVERTING = true; // set to true to invert the logic of th #define DISABLE_Y false #define DISABLE_Z false #define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true //disable only inactive extruders and keep active extruder enabled #define INVERT_X_DIR true // for Mendel set to false, for Orca set to true #define INVERT_Y_DIR false // for Mendel set to true, for Orca set to false @@ -316,6 +361,7 @@ const bool Z_ENDSTOPS_INVERTING = true; // set to true to invert the logic of th #define min_software_endstops true // If true, axis won't move to coordinates less than HOME_POS. #define max_software_endstops true // If true, axis won't move to coordinates greater than the defined lengths below. + // Travel limits after homing #define X_MAX_POS 205 #define X_MIN_POS 0 @@ -327,13 +373,103 @@ const bool Z_ENDSTOPS_INVERTING = true; // set to true to invert the logic of th #define X_MAX_LENGTH (X_MAX_POS - X_MIN_POS) #define Y_MAX_LENGTH (Y_MAX_POS - Y_MIN_POS) #define Z_MAX_LENGTH (Z_MAX_POS - Z_MIN_POS) +//============================= Bed Auto Leveling =========================== + +//#define ENABLE_AUTO_BED_LEVELING // Delete the comment to enable (remove // at the start of the line) + +#ifdef ENABLE_AUTO_BED_LEVELING + +// There are 2 different ways to pick the X and Y locations to probe: + +// - "grid" mode +// Probe every point in a rectangular grid +// You must specify the rectangle, and the density of sample points +// This mode is preferred because there are more measurements. +// It used to be called ACCURATE_BED_LEVELING but "grid" is more descriptive + +// - "3-point" mode +// Probe 3 arbitrary points on the bed (that aren't colinear) +// You must specify the X & Y coordinates of all 3 points + + #define AUTO_BED_LEVELING_GRID + // with AUTO_BED_LEVELING_GRID, the bed is sampled in a + // AUTO_BED_LEVELING_GRID_POINTSxAUTO_BED_LEVELING_GRID_POINTS grid + // and least squares solution is calculated + // Note: this feature occupies 10'206 byte + #ifdef AUTO_BED_LEVELING_GRID + + // set the rectangle in which to probe + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define BACK_PROBE_BED_POSITION 180 + #define FRONT_PROBE_BED_POSITION 20 + + // set the number of grid points per dimension + // I wouldn't see a reason to go above 3 (=9 probing points on the bed) + #define AUTO_BED_LEVELING_GRID_POINTS 2 + + + #else // not AUTO_BED_LEVELING_GRID + // with no grid, just probe 3 arbitrary points. A simple cross-product + // is used to esimate the plane of the print bed + + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + + #endif // AUTO_BED_LEVELING_GRID + + + // these are the offsets to the probe relative to the extruder tip (Hotend - Probe) + #define X_PROBE_OFFSET_FROM_EXTRUDER -25 + #define Y_PROBE_OFFSET_FROM_EXTRUDER -29 + #define Z_PROBE_OFFSET_FROM_EXTRUDER -12.35 + + #define Z_RAISE_BEFORE_HOMING 4 // (in mm) Raise Z before homing (G28) for Probe Clearance. + // Be sure you have this distance over your Z_MAX_POS in case + + #define XY_TRAVEL_SPEED 8000 // X and Y axis travel speed between probes, in mm/min + + #define Z_RAISE_BEFORE_PROBING 15 //How much the extruder will be raised before traveling to the first probing point. + #define Z_RAISE_BETWEEN_PROBINGS 5 //How much the extruder will be raised when traveling from between next probing points + + + //If defined, the Probe servo will be turned on only during movement and then turned off to avoid jerk + //The value is the delay to turn the servo off after powered on - depends on the servo speed; 300ms is good value, but you can try lower it. + // You MUST HAVE the SERVO_ENDSTOPS defined to use here a value higher than zero otherwise your code will not compile. + +// #define PROBE_SERVO_DEACTIVATION_DELAY 300 + + +//If you have enabled the Bed Auto Leveling and are using the same Z Probe for Z Homing, +//it is highly recommended you let this Z_SAFE_HOMING enabled!!! + + #define Z_SAFE_HOMING // This feature is meant to avoid Z homing with probe outside the bed area. + // When defined, it will: + // - Allow Z homing only after X and Y homing AND stepper drivers still enabled + // - If stepper drivers timeout, it will need X and Y homing again before Z homing + // - Position the probe in a defined XY point before Z Homing when homing all axis (G28) + // - Block Z homing only when the probe is outside bed area. + + #ifdef Z_SAFE_HOMING + + #define Z_SAFE_HOMING_X_POINT (X_MAX_LENGTH/2) // X point for Z homing when homing all axis (G28) + #define Z_SAFE_HOMING_Y_POINT (Y_MAX_LENGTH/2) // Y point for Z homing when homing all axis (G28) + + #endif + +#endif // ENABLE_AUTO_BED_LEVELING + // The position of the homing switches //#define MANUAL_HOME_POSITIONS // If defined, MANUAL_*_HOME_POS below will be used //#define BED_CENTER_AT_0_0 // If defined, the center of the bed is at (X=0, Y=0) //Manual homing switch locations: -// For deltabots this means top and center of the cartesian print volume. +// For deltabots this means top and center of the Cartesian print volume. #define MANUAL_X_HOME_POS 0 #define MANUAL_Y_HOME_POS 0 #define MANUAL_Z_HOME_POS 0 @@ -347,7 +483,7 @@ const bool Z_ENDSTOPS_INVERTING = true; // set to true to invert the logic of th #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_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_RETRACT_ACCELERATION 3000 // X, Y, Z and E max acceleration in mm/s^2 for retracts @@ -367,19 +503,28 @@ const bool Z_ENDSTOPS_INVERTING = true; // set to true to invert the logic of th //=============================Additional Features=========================== //=========================================================================== +// Custom M code points +#define CUSTOM_M_CODES +#ifdef CUSTOM_M_CODES + #define CUSTOM_M_CODE_SET_Z_PROBE_OFFSET 851 + #define Z_PROBE_OFFSET_RANGE_MIN -15 + #define Z_PROBE_OFFSET_RANGE_MAX -5 +#endif + + // EEPROM -// the microcontroller can store settings in the EEPROM, e.g. max velocity... -// M500 - stores paramters in EEPROM +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM // 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 this to enable EEPROM support //#define EEPROM_SETTINGS //to disable EEPROM Serial responses and decrease program space by ~1700 byte: comment this out: // please keep turned on if you can. //#define EEPROM_CHITCHAT // Preheat Constants -#define PLA_PREHEAT_HOTEND_TEMP 180 +#define PLA_PREHEAT_HOTEND_TEMP 180 #define PLA_PREHEAT_HPB_TEMP 70 #define PLA_PREHEAT_FAN_SPEED 255 // Insert Value between 0 and 255 @@ -388,13 +533,17 @@ const bool Z_ENDSTOPS_INVERTING = true; // set to true to invert the logic of th #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 ULTRA_LCD //general LCD support, also 16x2 //#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) - -//#define ULTIMAKERCONTROLLER //as available from the ultimaker online store. -//#define ULTIPANEL //the ultipanel as on thingiverse +//#define SD_CHECK_AND_RETRY // Use CRC checks and retries on the SD communication +//#define ENCODER_PULSES_PER_STEP 1 // Increase if you have a high resolution encoder +//#define ENCODER_STEPS_PER_MENU_ITEM 5 // Set according to ENCODER_PULSES_PER_STEP or your liking +//#define ULTIMAKERCONTROLLER //as available from the Ultimaker online store. +//#define ULTIPANEL //the UltiPanel as on Thingiverse +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 // this is the tone frequency the buzzer plays when on UI feedback. ie Screen Click +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 // the duration the buzzer plays the UI feedback sound. ie Screen Click // The MaKr3d Makr-Panel with graphic controller and SD support // http://reprap.org/wiki/MaKr3d_MaKrPanel @@ -464,7 +613,7 @@ const bool Z_ENDSTOPS_INVERTING = true; // set to true to invert the logic of th #define LCD_I2C_TYPE_PCF8575 #define LCD_I2C_ADDRESS 0x27 // I2C Address of the port expander #define NEWPANEL - #define ULTIPANEL + #define ULTIPANEL #endif // PANELOLU2 LCD with status LEDs, separate encoder and click inputs @@ -473,13 +622,28 @@ const bool Z_ENDSTOPS_INVERTING = true; // set to true to invert the logic of th // 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). + // 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 + #define ULTIPANEL + + #ifndef ENCODER_PULSES_PER_STEP + #define ENCODER_PULSES_PER_STEP 4 + #endif + + #ifndef ENCODER_STEPS_PER_MENU_ITEM + #define ENCODER_STEPS_PER_MENU_ITEM 1 + #endif + + + #ifdef LCD_USE_I2C_BUZZER + #define LCD_FEEDBACK_FREQUENCY_HZ 1000 + #define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 + #endif + #endif // Panucatt VIKI LCD with status LEDs, integrated click & L/R/U/P buttons, separate encoder inputs @@ -489,13 +653,24 @@ const bool Z_ENDSTOPS_INVERTING = true; // set to true to invert the logic of th // 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_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 + #define ULTIPANEL +#endif + +// Shift register panels +// --------------------- +// 2 wire Non-latching LCD SR from: +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/schematics#!shiftregister-connection +//#define SR_LCD +#ifdef SR_LCD + #define SR_LCD_2W_NL // Non latching 2 wire shift register + //#define NEWPANEL #endif + #ifdef ULTIPANEL // #define NEWPANEL //enable this if you have a click-encoder panel #define SDSUPPORT @@ -507,7 +682,7 @@ const bool Z_ENDSTOPS_INVERTING = true; // set to true to invert the logic of th #define LCD_WIDTH 20 #define LCD_HEIGHT 4 #endif -#else //no panel but just lcd +#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 @@ -529,6 +704,11 @@ const bool Z_ENDSTOPS_INVERTING = true; // set to true to invert the logic of th // Increase the FAN pwm frequency. Removes the PWM noise but increases heating in the FET/Arduino //#define FAST_PWM_FAN +// Temperature status LEDs that display the hotend and bet temperature. +// If all hotends and bed temperature and temperature setpoint are < 54C then the BLUE led is on. +// Otherwise the RED led is on. There is 1C hysteresis. +//#define TEMP_STAT_LEDS + // Use software PWM to drive the fan, as for the heaters. This uses a very low frequency // which is not ass annoying as with the hardware PWM. On the other hand, if this frequency // is too low, you should also increment SOFT_PWM_SCALE. @@ -550,6 +730,9 @@ const bool Z_ENDSTOPS_INVERTING = true; // set to true to invert the logic of th // Support for the BariCUDA Paste Extruder. //#define BARICUDA +//define BlinkM/CyzRgb Support +//#define BLINKM + /*********************************************************************\ * R/C SERVO support * Sponsored by TrinityLabs, Reworked by codexmas @@ -565,10 +748,10 @@ const bool Z_ENDSTOPS_INVERTING = true; // set to true to invert the logic of th //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Servo Endstops -// +// // This allows for servo actuated endstops, primary usage is for the Z Axis to eliminate calibration or bed height changes. // Use M206 command to correct for switch height offset to actual nozzle height. Store that setting with M500. -// +// //#define SERVO_ENDSTOPS {-1, -1, 0} // Servo index for X, Y, Z. Disable with -1 //#define SERVO_ENDSTOP_ANGLES {0,0, 0,0, 70,0} // X,Y,Z Axis Extend and Retract angles diff --git a/Marlin/ConfigurationStore.cpp b/Marlin/ConfigurationStore.cpp index 65d030279..074ef6ae3 100644 --- a/Marlin/ConfigurationStore.cpp +++ b/Marlin/ConfigurationStore.cpp @@ -37,7 +37,11 @@ void _EEPROM_readData(int &pos, uint8_t* value, uint8_t size) // the default values are used whenever there is a change to the data, to prevent // wrong data being written to the variables. // ALSO: always make sure the variables in the Store and retrieve sections are in the same order. -#define EEPROM_VERSION "V08" +#ifdef DELTA +#define EEPROM_VERSION "V11" +#else +#define EEPROM_VERSION "V10" +#endif #ifdef EEPROM_SETTINGS void Config_StoreSettings() @@ -57,6 +61,12 @@ void Config_StoreSettings() EEPROM_WRITE_VAR(i,max_z_jerk); EEPROM_WRITE_VAR(i,max_e_jerk); EEPROM_WRITE_VAR(i,add_homeing); + #ifdef DELTA + EEPROM_WRITE_VAR(i,endstop_adj); + EEPROM_WRITE_VAR(i,delta_radius); + EEPROM_WRITE_VAR(i,delta_diagonal_rod); + EEPROM_WRITE_VAR(i,delta_segments_per_second); + #endif #ifndef ULTIPANEL int plaPreheatHotendTemp = PLA_PREHEAT_HOTEND_TEMP, plaPreheatHPBTemp = PLA_PREHEAT_HPB_TEMP, plaPreheatFanSpeed = PLA_PREHEAT_FAN_SPEED; int absPreheatHotendTemp = ABS_PREHEAT_HOTEND_TEMP, absPreheatHPBTemp = ABS_PREHEAT_HPB_TEMP, absPreheatFanSpeed = ABS_PREHEAT_FAN_SPEED; @@ -67,6 +77,7 @@ void Config_StoreSettings() EEPROM_WRITE_VAR(i,absPreheatHotendTemp); EEPROM_WRITE_VAR(i,absPreheatHPBTemp); EEPROM_WRITE_VAR(i,absPreheatFanSpeed); + EEPROM_WRITE_VAR(i,zprobe_zoffset); #ifdef PIDTEMP EEPROM_WRITE_VAR(i,Kp); EEPROM_WRITE_VAR(i,Ki); @@ -91,7 +102,7 @@ void Config_StoreSettings() #endif //EEPROM_SETTINGS -#ifdef EEPROM_CHITCHAT +#ifndef DISABLE_M503 void Config_PrintSettings() { // Always have this function, even with EEPROM_SETTINGS disabled, the current values will be shown SERIAL_ECHO_START; @@ -145,6 +156,22 @@ void Config_PrintSettings() SERIAL_ECHOPAIR(" Y" ,add_homeing[1] ); SERIAL_ECHOPAIR(" Z" ,add_homeing[2] ); SERIAL_ECHOLN(""); +#ifdef DELTA + SERIAL_ECHO_START; + SERIAL_ECHOLNPGM("Endstop adjustement (mm):"); + SERIAL_ECHO_START; + SERIAL_ECHOPAIR(" M666 X",endstop_adj[0] ); + SERIAL_ECHOPAIR(" Y" ,endstop_adj[1] ); + SERIAL_ECHOPAIR(" Z" ,endstop_adj[2] ); + SERIAL_ECHOLN(""); + SERIAL_ECHO_START; + SERIAL_ECHOLNPGM("Delta settings: L=delta_diagonal_rod, R=delta_radius, S=delta_segments_per_second"); + SERIAL_ECHO_START; + SERIAL_ECHOPAIR(" M665 L",delta_diagonal_rod ); + SERIAL_ECHOPAIR(" R" ,delta_radius ); + SERIAL_ECHOPAIR(" S" ,delta_segments_per_second ); + SERIAL_ECHOLN(""); +#endif #ifdef PIDTEMP SERIAL_ECHO_START; SERIAL_ECHOLNPGM("PID settings:"); @@ -185,6 +212,12 @@ void Config_RetrieveSettings() EEPROM_READ_VAR(i,max_z_jerk); EEPROM_READ_VAR(i,max_e_jerk); EEPROM_READ_VAR(i,add_homeing); + #ifdef DELTA + EEPROM_READ_VAR(i,endstop_adj); + EEPROM_READ_VAR(i,delta_radius); + EEPROM_READ_VAR(i,delta_diagonal_rod); + EEPROM_READ_VAR(i,delta_segments_per_second); + #endif #ifndef ULTIPANEL int plaPreheatHotendTemp, plaPreheatHPBTemp, plaPreheatFanSpeed; int absPreheatHotendTemp, absPreheatHPBTemp, absPreheatFanSpeed; @@ -195,6 +228,7 @@ void Config_RetrieveSettings() EEPROM_READ_VAR(i,absPreheatHotendTemp); EEPROM_READ_VAR(i,absPreheatHPBTemp); EEPROM_READ_VAR(i,absPreheatFanSpeed); + EEPROM_READ_VAR(i,zprobe_zoffset); #ifndef PIDTEMP float Kp,Ki,Kd; #endif @@ -216,7 +250,9 @@ void Config_RetrieveSettings() { Config_ResetDefault(); } - Config_PrintSettings(); + #ifdef EEPROM_CHITCHAT + Config_PrintSettings(); + #endif } #endif @@ -244,6 +280,13 @@ void Config_ResetDefault() max_z_jerk=DEFAULT_ZJERK; max_e_jerk=DEFAULT_EJERK; add_homeing[0] = add_homeing[1] = add_homeing[2] = 0; +#ifdef DELTA + endstop_adj[0] = endstop_adj[1] = endstop_adj[2] = 0; + delta_radius= DELTA_RADIUS; + delta_diagonal_rod= DELTA_DIAGONAL_ROD; + delta_segments_per_second= DELTA_SEGMENTS_PER_SECOND; + recalc_delta_settings(delta_radius, delta_diagonal_rod); +#endif #ifdef ULTIPANEL plaPreheatHotendTemp = PLA_PREHEAT_HOTEND_TEMP; plaPreheatHPBTemp = PLA_PREHEAT_HPB_TEMP; @@ -252,6 +295,9 @@ void Config_ResetDefault() absPreheatHPBTemp = ABS_PREHEAT_HPB_TEMP; absPreheatFanSpeed = ABS_PREHEAT_FAN_SPEED; #endif +#ifdef ENABLE_AUTO_BED_LEVELING + zprobe_zoffset = -Z_PROBE_OFFSET_FROM_EXTRUDER; +#endif #ifdef DOGLCD lcd_contrast = DEFAULT_LCD_CONTRAST; #endif diff --git a/Marlin/ConfigurationStore.h b/Marlin/ConfigurationStore.h index 2bbf4808c..4f68b13a6 100644 --- a/Marlin/ConfigurationStore.h +++ b/Marlin/ConfigurationStore.h @@ -5,7 +5,7 @@ void Config_ResetDefault(); -#ifdef EEPROM_CHITCHAT +#ifndef DISABLE_M503 void Config_PrintSettings(); #else FORCE_INLINE void Config_PrintSettings() {} diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index f555d6069..245f65c9e 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -11,39 +11,43 @@ #define BED_CHECK_INTERVAL 5000 //ms between checks in bang-bang control //// Heating sanity check: -// This waits for the watchperiod in milliseconds whenever an M104 or M109 increases the target temperature -// If the temperature has not increased at the end of that period, the target temperature is set to zero. +// This waits for the watch period in milliseconds whenever an M104 or M109 increases the target temperature +// If the temperature has not increased at the end of that period, the target temperature is set to zero. // It can be reset with another M104/M109. This check is also only triggered if the target temperature and the current temperature // differ by at least 2x WATCH_TEMP_INCREASE //#define WATCH_TEMP_PERIOD 40000 //40 seconds //#define WATCH_TEMP_INCREASE 10 //Heat up at least 10 degree in 20 seconds #ifdef PIDTEMP - // this adds an experimental additional term to the heatingpower, proportional to the extrusion speed. - // if Kc is choosen well, the additional required power due to increased melting should be compensated. - #define PID_ADD_EXTRUSION_RATE + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + #define PID_ADD_EXTRUSION_RATE #ifdef PID_ADD_EXTRUSION_RATE - #define DEFAULT_Kc (1) //heatingpower=Kc*(e_speed) + #define DEFAULT_Kc (1) //heating power=Kc*(e_speed) #endif #endif //automatic temperature: The hot end target temperature is calculated by all the buffered lines of gcode. //The maximum buffered steps/sec of the extruder motor are called "se". -//You enter the autotemp mode by a M109 S T F +//You enter the autotemp mode by a M109 S B F // the target temperature is set to mintemp+factor*se[steps/sec] and limited by mintemp and maxtemp // you exit the value by any M109 without F* // Also, if the temperature is set to a value +// Mode 0: Full control. The slicer has full control over both x-carriages and can achieve optimal travel results +// as long as it supports dual x-carriages. (M605 S0) +// Mode 1: Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so +// that additional slicer support is not required. (M605 S1) +// Mode 2: Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all +// actions of the first x-carriage. This allows the printer to print 2 arbitrary items at +// once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + +// This is the default power-up mode which can be later using M605. +#define DEFAULT_DUAL_X_CARRIAGE_MODE 0 + +// As the x-carriages are independent we can now account for any relative Z offset +#define EXTRUDER1_Z_OFFSET 0.0 // z offset relative to extruder 0 + +// Default settings in "Auto-park Mode" +#define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder +#define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + +// Default x offset in duplication mode (typically set to half print bed width) +#define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif //DUAL_X_CARRIAGE + //homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: -#define X_HOME_RETRACT_MM 5 -#define Y_HOME_RETRACT_MM 5 -#define Z_HOME_RETRACT_MM 1 +#define X_HOME_RETRACT_MM 5 +#define Y_HOME_RETRACT_MM 5 +#define Z_HOME_RETRACT_MM 2 //#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. #define AXIS_RELATIVE_MODES {false, false, false, false} @@ -193,6 +234,16 @@ #define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate #define DEFAULT_MINTRAVELFEEDRATE 0.0 +// Feedrates for manual moves along X, Y, Z, E from panel +#ifdef ULTIPANEL +#define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // set the speeds for manual moves (mm/min) +#endif + +//Comment to disable setting feedrate multiplier via encoder +#ifdef ULTIPANEL + #define ULTIPANEL_FEEDMULTIPLY +#endif + // minimum time in microseconds that a movement needs to take if the buffer is emptied. #define DEFAULT_MINSEGMENTTIME 20000 @@ -222,15 +273,29 @@ // Motor Current setting (Only functional when motor driver current ref pins are connected to a digital trimpot on supported boards) #define DIGIPOT_MOTOR_CURRENT {135,135,135,135,135} // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A) +// uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +// Number of channels available for I2C digipot, For Azteeg X3 Pro we have 8 +#define DIGIPOT_I2C_NUM_CHANNELS 8 +// actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#define DIGIPOT_I2C_MOTOR_CURRENTS {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0} //=========================================================================== //=============================Additional Features=========================== //=========================================================================== +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. -// The hardware watchdog should reset the Microcontroller disabling all outputs, in case the firmware gets stuck and doesn't do temperature regulation. +#define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. +// if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. +// using: +//#define MENU_ADDAUTOSTART + +// The hardware watchdog should reset the microcontroller disabling all outputs, in case the firmware gets stuck and doesn't do temperature regulation. //#define USE_WATCHDOG #ifdef USE_WATCHDOG @@ -243,12 +308,32 @@ // 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 +// Babystepping enables the user to control the axis in tiny amounts, independently from the normal printing process +// it can e.g. be used to change z-positions in the print startup phase in real-time +// does not respect endstops! +//#define BABYSTEPPING +#ifdef BABYSTEPPING + #define BABYSTEP_XY //not only z, but also XY in the menu. more clutter, more functions + #define BABYSTEP_INVERT_Z false //true for inverse movements in Z + #define BABYSTEP_Z_MULTIPLICATOR 2 //faster z movements + + #ifdef COREXY + #error BABYSTEPPING not implemented for COREXY yet. + #endif + + #ifdef DELTA + #ifdef BABYSTEP_XY + #error BABYSTEPPING only implemented for Z axis on deltabots. + #endif + #endif +#endif + // extruder advance constant (s2/mm3) // // advance (steps) = STEPS_PER_CUBIC_MM_E * EXTUDER_ADVANCE_K * cubic mm per second ^ 2 // -// hooke's law says: force = k * distance -// bernoulli's priniciple says: v ^ 2 / 2 + g . h + pressure / density = constant +// Hooke's law says: force = k * distance +// Bernoulli's principle says: v ^ 2 / 2 + g . h + pressure / density = constant // so: v ^ 2 is proportional to number of steps we advance the extruder //#define ADVANCE @@ -269,10 +354,10 @@ const unsigned int dropsegments=5; //everything with less than this number of steps will be ignored as move and joined with the next movement // If you are using a RAMPS board or cheap E-bay purchased boards that do not detect when an SD card is inserted -// You can get round this by connecting a push button or single throw switch to the pin defined as SDCARDCARDDETECT +// You can get round this by connecting a push button or single throw switch to the pin defined as SDCARDCARDDETECT // in the pins.h file. When using a push button pulling the pin to ground this will need inverted. This setting should // be commented out otherwise -#define SDCARDDETECTINVERTED +#define SDCARDDETECTINVERTED #ifdef ULTIPANEL #undef SDCARDDETECTINVERTED @@ -284,22 +369,25 @@ const unsigned int dropsegments=5; //everything with less than this number of st #define POWER_SUPPLY 1 #endif // 1 = ATX -#if (POWER_SUPPLY == 1) +#if (POWER_SUPPLY == 1) #define PS_ON_AWAKE LOW #define PS_ON_ASLEEP HIGH #endif // 2 = X-Box 360 203W -#if (POWER_SUPPLY == 2) +#if (POWER_SUPPLY == 2) #define PS_ON_AWAKE HIGH #define PS_ON_ASLEEP LOW #endif +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + //=========================================================================== //=============================Buffers ============================ //=========================================================================== -// The number of linear motions that can be in the plan at any give time. -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ringbuffering. +// The number of linear motions that can be in the plan at any give time. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. #if defined SDSUPPORT #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #else @@ -307,24 +395,30 @@ const unsigned int dropsegments=5; //everything with less than this number of st #endif -//The ASCII buffer for recieving from the serial: +//The ASCII buffer for receiving from the serial: #define MAX_CMD_SIZE 96 #define BUFSIZE 4 -// Firmware based and LCD controled retract -// M207 and M208 can be used to define parameters for the retraction. +// Firmware based and LCD controlled retract +// M207 and M208 can be used to define parameters for the retraction. // The retraction can be called by the slicer using G10 and G11 -// until then, intended retractions can be detected by moves that only extrude and the direction. +// until then, intended retractions can be detected by moves that only extrude and the direction. // the moves are than replaced by the firmware controlled ones. // #define FWRETRACT //ONLY PARTIALLY TESTED -#define MIN_RETRACT 0.1 //minimum extruded mm to accept a automatic gcode retraction attempt - +#ifdef FWRETRACT + #define MIN_RETRACT 0.1 //minimum extruded mm to accept a automatic gcode retraction attempt + #define RETRACT_LENGTH 3 //default retract length (positive mm) + #define RETRACT_FEEDRATE 45 //default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 //default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 //default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_FEEDRATE 8 //default feedrate for recovering from retraction (mm/s) +#endif //adds support for experimental filament exchange support M600; requires display #ifdef ULTIPANEL - //#define FILAMENTCHANGEENABLE + #define FILAMENTCHANGEENABLE #ifdef FILAMENTCHANGEENABLE #define FILAMENTCHANGE_XPOS 3 #define FILAMENTCHANGE_YPOS 3 @@ -333,7 +427,13 @@ const unsigned int dropsegments=5; //everything with less than this number of st #define FILAMENTCHANGE_FINALRETRACT -100 #endif #endif - + +#ifdef FILAMENTCHANGEENABLE + #ifdef EXTRUDER_RUNOUT_PREVENT + #error EXTRUDER_RUNOUT_PREVENT currently incompatible with FILAMENTCHANGE + #endif +#endif + //=========================================================================== //============================= Define Defines ============================ //=========================================================================== @@ -341,6 +441,10 @@ const unsigned int dropsegments=5; //everything with less than this number of st #error "You cannot use TEMP_SENSOR_1_AS_REDUNDANT if EXTRUDERS > 1" #endif +#if EXTRUDERS > 1 && defined HEATERS_PARALLEL + #error "You cannot use HEATERS_PARALLEL if EXTRUDERS > 1" +#endif + #if TEMP_SENSOR_0 > 0 #define THERMISTORHEATER_0 TEMP_SENSOR_0 #define HEATER_0_USES_THERMISTOR diff --git a/Marlin/LCD Menu Tree.pdf b/Marlin/LCD Menu Tree.pdf index 5e29d0495..72b5911dd 100644 Binary files a/Marlin/LCD Menu Tree.pdf and b/Marlin/LCD Menu Tree.pdf differ diff --git a/Marlin/LiquidCrystalRus.cpp b/Marlin/LiquidCrystalRus.cpp index c193e449d..6ee2c112e 100644 --- a/Marlin/LiquidCrystalRus.cpp +++ b/Marlin/LiquidCrystalRus.cpp @@ -11,7 +11,7 @@ #include "WProgram.h" #endif -// it is a russian alphabet translation +// it is a Russian alphabet translation // except 0401 --> 0xa2 = ╗, 0451 --> 0xb5 const PROGMEM uint8_t utf_recode[] = { 0x41,0xa0,0x42,0xa1,0xe0,0x45,0xa3,0xa4,0xa5,0xa6,0x4b,0xa7,0x4d,0x48,0x4f, @@ -115,7 +115,7 @@ void LiquidCrystalRus::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) { // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION! // according to datasheet, we need at least 40ms after power rises above 2.7V - // before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50 + // before sending commands. Arduino can turn on way before 4.5V so we'll wait 50 delayMicroseconds(50000); // Now we pull both RS and R/W low to begin commands digitalWrite(_rs_pin, LOW); @@ -126,7 +126,7 @@ void LiquidCrystalRus::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) { //put the LCD into 4 bit or 8 bit mode if (! (_displayfunction & LCD_8BITMODE)) { - // this is according to the hitachi HD44780 datasheet + // this is according to the Hitachi HD44780 datasheet // figure 24, pg 46 // we start in 8bit mode, try to set 4 bit mode @@ -144,7 +144,7 @@ void LiquidCrystalRus::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) { // finally, set to 8-bit interface writeNbits(0x02,4); } else { - // this is according to the hitachi HD44780 datasheet + // this is according to the Hitachi HD44780 datasheet // page 45 figure 23 // Send function set command sequence @@ -308,7 +308,7 @@ inline void LiquidCrystalRus::command(uint8_t value) { } } else send(out_char, HIGH); #if defined(ARDUINO) && ARDUINO >= 100 - return 1; // assume sucess + return 1; // assume success #endif } diff --git a/Marlin/Makefile b/Marlin/Makefile index a56bc1eab..3bd0ae3bf 100644 --- a/Marlin/Makefile +++ b/Marlin/Makefile @@ -14,7 +14,7 @@ # # 1. Modify the line containg "ARDUINO_INSTALL_DIR" to point to the directory that # contains the Arduino installation (for example, under Mac OS X, this -# might be /Applications/arduino-0012). +# might be /Applications/Arduino.app/Contents/Resources/Java). # # 2. Modify the line containing "UPLOAD_PORT" to refer to the filename # representing the USB or serial connection to your Arduino board @@ -40,8 +40,8 @@ HARDWARE_MOTHERBOARD ?= 11 # Arduino source install directory, and version number -ARDUINO_INSTALL_DIR ?= ../../arduino-0022 -ARDUINO_VERSION ?= 22 +ARDUINO_INSTALL_DIR ?= /Applications/Arduino.app/Contents/Resources/Java +ARDUINO_VERSION ?= 105 # You can optionally set a path to the avr-gcc tools. Requires a trailing slash. (ex: /usr/local/avr-gcc/bin) AVR_TOOLS_PATH ?= @@ -54,6 +54,12 @@ UPLOAD_PORT ?= /dev/arduino #Directory used to build files in, contains all the build files, from object files to the final hex file. BUILD_DIR ?= applet +# This defines whether Liquid_TWI2 support will be built +LIQUID_TWI2 ?= 0 + +# this defines if Wire is needed +WIRE ?= 0 + ############################################################################ # Below here nothing should be changed... @@ -139,6 +145,12 @@ MCU ?= at90usb1286 else ifeq ($(HARDWARE_MOTHERBOARD),82) HARDWARE_VARIANT ?= Teensy MCU ?= at90usb646 +else ifeq ($(HARDWARE_MOTHERBOARD),83) +HARDWARE_VARIANT ?= Teensy +MCU ?= at90usb1286 +else ifeq ($(HARDWARE_MOTHERBOARD),84) +HARDWARE_VARIANT ?= Teensy +MCU ?= at90usb1286 #Gen3+ else ifeq ($(HARDWARE_MOTHERBOARD),9) @@ -165,6 +177,14 @@ else ifeq ($(HARDWARE_MOTHERBOARD),301) HARDWARE_VARIANT ?= arduino MCU ?= atmega2560 +# Azteeg +else ifeq ($(HARDWARE_MOTHERBOARD),67) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 +else ifeq ($(HARDWARE_MOTHERBOARD),68) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 + endif # Be sure to regenerate speed_lookuptable.h with create_speed_lookuptable.py @@ -199,9 +219,27 @@ VPATH += $(HARDWARE_SRC) ifeq ($(HARDWARE_VARIANT), arduino) VPATH += $(ARDUINO_INSTALL_DIR)/libraries/LiquidCrystal VPATH += $(ARDUINO_INSTALL_DIR)/libraries/SPI +ifeq ($(LIQUID_TWI2), 1) +VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire +VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire/utility +VPATH += $(ARDUINO_INSTALL_DIR)/libraries/LiquidTWI2 +endif +ifeq ($(WIRE), 1) +VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire +VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire/utility +endif else VPATH += $(HARDWARE_DIR)/libraries/LiquidCrystal VPATH += $(HARDWARE_DIR)/libraries/SPI +ifeq ($(LIQUID_TWI2), 1) +VPATH += $(HARDWARE_DIR)/libraries/Wire +VPATH += $(HARDWARE_DIR)/libraries/Wire/utility +VPATH += $(HARDWARE_DIR)/libraries/LiquidTWI2 +endif +ifeq ($(WIRE), 1) +VPATH += $(HARDWARE_DIR)/libraries/Wire +VPATH += $(HARDWARE_DIR)/libraries/Wire/utility +endif endif ifeq ($(HARDWARE_VARIANT), arduino) HARDWARE_SUB_VARIANT ?= mega @@ -214,12 +252,27 @@ SRC = wiring.c \ wiring_analog.c wiring_digital.c \ wiring_pulse.c \ wiring_shift.c WInterrupts.c +ifeq ($(HARDWARE_VARIANT), Teensy) +SRC = wiring.c +VPATH += $(ARDUINO_INSTALL_DIR)/hardware/teensy/cores/teensy +endif CXXSRC = WMath.cpp WString.cpp Print.cpp Marlin_main.cpp \ MarlinSerial.cpp Sd2Card.cpp SdBaseFile.cpp SdFatUtil.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 Servo.cpp Tone.cpp + watchdog.cpp SPI.cpp Servo.cpp Tone.cpp ultralcd.cpp digipot_mcp4451.cpp \ + vector_3.cpp qr_solve.cpp +ifeq ($(LIQUID_TWI2), 0) +CXXSRC += LiquidCrystal.cpp +else +SRC += twi.c +CXXSRC += Wire.cpp LiquidTWI2.cpp +endif + +ifeq ($(WIRE), 1) +SRC += twi.c +CXXSRC += Wire.cpp +endif #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) @@ -294,7 +347,12 @@ LDFLAGS = -lm # Programming support using avrdude. Settings and variables. AVRDUDE_PORT = $(UPLOAD_PORT) AVRDUDE_WRITE_FLASH = -U flash:w:$(BUILD_DIR)/$(TARGET).hex:i -AVRDUDE_FLAGS = -D -C $(ARDUINO_INSTALL_DIR)/hardware/tools/avr/etc/avrdude.conf \ +ifeq ($(shell uname -s), Linux) +AVRDUDE_CONF = $(ARDUINO_INSTALL_DIR)/hardware/tools/avrdude.conf +else +AVRDUDE_CONF = $(ARDUINO_INSTALL_DIR)/hardware/tools/avr/etc/avrdude.conf +endif +AVRDUDE_FLAGS = -D -C $(AVRDUDE_CONF) \ -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \ -b $(UPLOAD_RATE) diff --git a/Marlin/Marlin.h b/Marlin/Marlin.h index 1ae9494e3..e7282092e 100644 --- a/Marlin/Marlin.h +++ b/Marlin/Marlin.h @@ -1,5 +1,5 @@ // Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware. -// Licence: GPL +// License: GPL #ifndef MARLIN_H #define MARLIN_H @@ -30,10 +30,14 @@ # include "Arduino.h" #else # include "WProgram.h" - //Arduino < 1.0.0 does not define this, so we need to do it ourselfs + //Arduino < 1.0.0 does not define this, so we need to do it ourselves # define analogInputToDigitalPin(p) ((p) + A0) #endif +#ifdef AT90USB +#include "HardwareSerial.h" +#endif + #include "MarlinSerial.h" #ifndef cbi @@ -46,27 +50,31 @@ #include "WString.h" #ifdef AT90USB - #define MYSERIAL Serial + #ifdef BTENABLED + #define MYSERIAL bt + #else + #define MYSERIAL Serial + #endif // BTENABLED #else #define MYSERIAL MSerial #endif -#define SERIAL_PROTOCOL(x) MYSERIAL.print(x); -#define SERIAL_PROTOCOL_F(x,y) MYSERIAL.print(x,y); -#define SERIAL_PROTOCOLPGM(x) serialprintPGM(PSTR(x)); -#define SERIAL_PROTOCOLLN(x) {MYSERIAL.print(x);MYSERIAL.write('\n');} -#define SERIAL_PROTOCOLLNPGM(x) {serialprintPGM(PSTR(x));MYSERIAL.write('\n');} +#define SERIAL_PROTOCOL(x) (MYSERIAL.print(x)) +#define SERIAL_PROTOCOL_F(x,y) (MYSERIAL.print(x,y)) +#define SERIAL_PROTOCOLPGM(x) (serialprintPGM(PSTR(x))) +#define SERIAL_PROTOCOLLN(x) (MYSERIAL.print(x),MYSERIAL.write('\n')) +#define SERIAL_PROTOCOLLNPGM(x) (serialprintPGM(PSTR(x)),MYSERIAL.write('\n')) const char errormagic[] PROGMEM ="Error:"; const char echomagic[] PROGMEM ="echo:"; -#define SERIAL_ERROR_START serialprintPGM(errormagic); +#define SERIAL_ERROR_START (serialprintPGM(errormagic)) #define SERIAL_ERROR(x) SERIAL_PROTOCOL(x) #define SERIAL_ERRORPGM(x) SERIAL_PROTOCOLPGM(x) #define SERIAL_ERRORLN(x) SERIAL_PROTOCOLLN(x) #define SERIAL_ERRORLNPGM(x) SERIAL_PROTOCOLLNPGM(x) -#define SERIAL_ECHO_START serialprintPGM(echomagic); +#define SERIAL_ECHO_START (serialprintPGM(echomagic)) #define SERIAL_ECHO(x) SERIAL_PROTOCOL(x) #define SERIAL_ECHOPGM(x) SERIAL_PROTOCOLPGM(x) #define SERIAL_ECHOLN(x) SERIAL_PROTOCOLLN(x) @@ -79,7 +87,7 @@ void serial_echopair_P(const char *s_P, double v); void serial_echopair_P(const char *s_P, unsigned long v); -//things to write to serial from Programmemory. saves 400 to 2k of RAM. +//Things to write to serial from Program memory. Saves 400 to 2k of RAM. FORCE_INLINE void serialprintPGM(const char *str) { char ch=pgm_read_byte(str); @@ -99,18 +107,23 @@ void manage_inactivity(); #if defined(DUAL_X_CARRIAGE) && defined(X_ENABLE_PIN) && X_ENABLE_PIN > -1 \ && defined(X2_ENABLE_PIN) && X2_ENABLE_PIN > -1 #define enable_x() do { WRITE(X_ENABLE_PIN, X_ENABLE_ON); WRITE(X2_ENABLE_PIN, X_ENABLE_ON); } while (0) - #define disable_x() do { WRITE(X_ENABLE_PIN,!X_ENABLE_ON); WRITE(X2_ENABLE_PIN,!X_ENABLE_ON); } while (0) + #define disable_x() do { WRITE(X_ENABLE_PIN,!X_ENABLE_ON); WRITE(X2_ENABLE_PIN,!X_ENABLE_ON); axis_known_position[X_AXIS] = false; } while (0) #elif defined(X_ENABLE_PIN) && X_ENABLE_PIN > -1 #define enable_x() WRITE(X_ENABLE_PIN, X_ENABLE_ON) - #define disable_x() WRITE(X_ENABLE_PIN,!X_ENABLE_ON) + #define disable_x() { WRITE(X_ENABLE_PIN,!X_ENABLE_ON); axis_known_position[X_AXIS] = false; } #else #define enable_x() ; #define disable_x() ; #endif #if defined(Y_ENABLE_PIN) && Y_ENABLE_PIN > -1 - #define enable_y() WRITE(Y_ENABLE_PIN, Y_ENABLE_ON) - #define disable_y() WRITE(Y_ENABLE_PIN,!Y_ENABLE_ON) + #ifdef Y_DUAL_STEPPER_DRIVERS + #define enable_y() { WRITE(Y_ENABLE_PIN, Y_ENABLE_ON); WRITE(Y2_ENABLE_PIN, Y_ENABLE_ON); } + #define disable_y() { WRITE(Y_ENABLE_PIN,!Y_ENABLE_ON); WRITE(Y2_ENABLE_PIN, !Y_ENABLE_ON); axis_known_position[Y_AXIS] = false; } + #else + #define enable_y() WRITE(Y_ENABLE_PIN, Y_ENABLE_ON) + #define disable_y() { WRITE(Y_ENABLE_PIN,!Y_ENABLE_ON); axis_known_position[Y_AXIS] = false; } + #endif #else #define enable_y() ; #define disable_y() ; @@ -119,10 +132,10 @@ void manage_inactivity(); #if defined(Z_ENABLE_PIN) && Z_ENABLE_PIN > -1 #ifdef Z_DUAL_STEPPER_DRIVERS #define enable_z() { WRITE(Z_ENABLE_PIN, Z_ENABLE_ON); WRITE(Z2_ENABLE_PIN, Z_ENABLE_ON); } - #define disable_z() { WRITE(Z_ENABLE_PIN,!Z_ENABLE_ON); WRITE(Z2_ENABLE_PIN,!Z_ENABLE_ON); } + #define disable_z() { WRITE(Z_ENABLE_PIN,!Z_ENABLE_ON); WRITE(Z2_ENABLE_PIN,!Z_ENABLE_ON); axis_known_position[Z_AXIS] = false; } #else #define enable_z() WRITE(Z_ENABLE_PIN, Z_ENABLE_ON) - #define disable_z() WRITE(Z_ENABLE_PIN,!Z_ENABLE_ON) + #define disable_z() { WRITE(Z_ENABLE_PIN,!Z_ENABLE_ON); axis_known_position[Z_AXIS] = false; } #endif #else #define enable_z() ; @@ -163,6 +176,7 @@ void ClearToSend(); void get_coordinates(); #ifdef DELTA void calculate_delta(float cartesian[3]); +extern float delta[3]; #endif void prepare_move(); void kill(); @@ -170,11 +184,13 @@ void Stop(); bool IsStopped(); -void enquecommand(const char *cmd); //put an ascii command at the end of the current buffer. -void enquecommand_P(const char *cmd); //put an ascii command at the end of the current buffer, read from flash +void enquecommand(const char *cmd); //put an ASCII command at the end of the current buffer. +void enquecommand_P(const char *cmd); //put an ASCII command at the end of the current buffer, read from flash void prepare_arc_move(char isclockwise); void clamp_to_software_endstops(float target[3]); +void refresh_cmd_timeout(void); + #ifdef FAST_PWM_FAN void setPwmFrequency(uint8_t pin, int val); #endif @@ -187,11 +203,22 @@ void setPwmFrequency(uint8_t pin, int val); extern float homing_feedrate[]; extern bool axis_relative_modes[]; extern int feedmultiply; -extern int extrudemultiply; // Sets extrude multiply factor (in percent) +extern int extrudemultiply; // Sets extrude multiply factor (in percent) for all extruders +extern int extruder_multiply[EXTRUDERS]; // sets extrude multiply factor (in percent) for each extruder individually +extern float volumetric_multiplier[EXTRUDERS]; // reciprocal of cross-sectional area of filament (in square millimeters), stored this way to reduce computational burden in planner extern float current_position[NUM_AXIS] ; extern float add_homeing[3]; +#ifdef DELTA +extern float endstop_adj[3]; +extern float delta_radius; +extern float delta_diagonal_rod; +extern float delta_segments_per_second; +void recalc_delta_settings(float radius, float diagonal_rod); +#endif extern float min_pos[3]; extern float max_pos[3]; +extern bool axis_known_position[3]; +extern float zprobe_zoffset; extern int fanSpeed; #ifdef BARICUDA extern int ValvePressure; @@ -215,4 +242,9 @@ extern unsigned long stoptime; // Handling multiple extruders pins extern uint8_t active_extruder; +#ifdef DIGIPOT_I2C +extern void digipot_i2c_set_current( int channel, float current ); +extern void digipot_i2c_init(); +#endif + #endif diff --git a/Marlin/Marlin.ino b/Marlin/Marlin.ino new file mode 100644 index 000000000..79c934bf0 --- /dev/null +++ b/Marlin/Marlin.ino @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ + +/* + Reprap firmware based on Sprinter and grbl. + Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +/* + This firmware is a mashup between Sprinter and grbl. + (https://github.com/kliment/Sprinter) + (https://github.com/simen/grbl/tree) + + It has preliminary support for Matthew Roberts advance algorithm + http://reprap.org/pipermail/reprap-dev/2011-May/003323.html + */ + +/* All the implementation is done in *.cpp files to get better compatibility with avr-gcc without the Arduino IDE */ +/* Use this file to help the Arduino IDE find which Arduino libraries are needed and to keep documentation on GCode */ + +#include "Configuration.h" +#include "pins.h" + +#ifdef ULTRA_LCD + #if defined(LCD_I2C_TYPE_PCF8575) + #include + #include + #elif defined(LCD_I2C_TYPE_MCP23017) || defined(LCD_I2C_TYPE_MCP23008) + #include + #include + #elif defined(DOGLCD) + #include // library for graphics LCD by Oli Kraus (https://code.google.com/p/u8glib/) + #else + #include // library for character LCD + #endif +#endif + +#if defined(DIGIPOTSS_PIN) && DIGIPOTSS_PIN > -1 +#include +#endif + +#if defined(DIGIPOT_I2C) + #include +#endif diff --git a/Marlin/Marlin.pde b/Marlin/Marlin.pde index 2d6211c97..79c934bf0 100644 --- a/Marlin/Marlin.pde +++ b/Marlin/Marlin.pde @@ -3,17 +3,17 @@ /* Reprap firmware based on Sprinter and grbl. Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm - + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + This program 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 General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -22,8 +22,8 @@ This firmware is a mashup between Sprinter and grbl. (https://github.com/kliment/Sprinter) (https://github.com/simen/grbl/tree) - - It has preliminary support for Matthew Roberts advance algorithm + + It has preliminary support for Matthew Roberts advance algorithm http://reprap.org/pipermail/reprap-dev/2011-May/003323.html */ @@ -50,3 +50,7 @@ #if defined(DIGIPOTSS_PIN) && DIGIPOTSS_PIN > -1 #include #endif + +#if defined(DIGIPOT_I2C) + #include +#endif diff --git a/Marlin/MarlinSerial.cpp b/Marlin/MarlinSerial.cpp index 1358f3859..a7251dd6a 100644 --- a/Marlin/MarlinSerial.cpp +++ b/Marlin/MarlinSerial.cpp @@ -25,7 +25,7 @@ #ifndef AT90USB // this next line disables the entire HardwareSerial.cpp, -// this is so I can support Attiny series and any other chip without a uart +// this is so I can support Attiny series and any other chip without a UART #if defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H) #if UART_PRESENT(SERIAL_PORT) @@ -73,7 +73,7 @@ void MarlinSerial::begin(long baud) bool useU2X = true; #if F_CPU == 16000000UL && SERIAL_PORT == 0 - // hardcoded exception for compatibility with the bootloader shipped + // hard coded exception for compatibility with the bootloader shipped // with the Duemilanove and previous boards and the firmware on the 8U2 // on the Uno and Mega 2560. if (baud == 57600) { @@ -320,3 +320,9 @@ MarlinSerial MSerial; #endif // whole file #endif // !AT90USB + +// For AT90USB targets use the UART for BT interfacing +#if defined(AT90USB) && defined (BTENABLED) + HardwareSerial bt; +#endif + diff --git a/Marlin/MarlinSerial.h b/Marlin/MarlinSerial.h index 9514730fa..7ccdfd6a0 100644 --- a/Marlin/MarlinSerial.h +++ b/Marlin/MarlinSerial.h @@ -181,4 +181,9 @@ class MarlinSerial //: public Stream extern MarlinSerial MSerial; #endif // !AT90USB +// Use the UART for BT in AT90USB configurations +#if defined(AT90USB) && defined (BTENABLED) + extern HardwareSerial bt; +#endif + #endif diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index 886edca49..0367eb46c 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -29,6 +29,13 @@ #include "Marlin.h" +#ifdef ENABLE_AUTO_BED_LEVELING +#include "vector_3.h" + #ifdef AUTO_BED_LEVELING_GRID + #include "qr_solve.h" + #endif +#endif // ENABLE_AUTO_BED_LEVELING + #include "ultralcd.h" #include "planner.h" #include "stepper.h" @@ -39,6 +46,12 @@ #include "ConfigurationStore.h" #include "language.h" #include "pins_arduino.h" +#include "math.h" + +#ifdef BLINKM +#include "BlinkM.h" +#include "Wire.h" +#endif #if NUM_SERVOS > 0 #include "Servo.h" @@ -50,7 +63,7 @@ #define VERSION_STRING "1.0.0" -// look here for descriptions of gcodes: http://linuxcnc.org/handbook/gcode/g-code.html +// look here for descriptions of G-codes: http://linuxcnc.org/handbook/gcode/g-code.html // http://objects.reprap.org/wiki/Mendel_User_Manual:_RepRapGCodes //Implemented Codes @@ -63,9 +76,11 @@ // G10 - retract filament according to settings of M207 // G11 - retract recover filament according to settings of M208 // G28 - Home all Axis +// G29 - Detailed Z-Probe, probes the bed at 3 or more points. Will fail if you haven't homed yet. +// G30 - Single Z Probe, probes bed at current XY location. // G90 - Use Absolute Coordinates // G91 - Use Relative Coordinates -// G92 - Set current position to cordinates given +// G92 - Set current position to coordinates given // M Codes // M0 - Unconditional stop - Wait for user to press a button on the LCD (Only if ULTRA_LCD is enabled) @@ -84,7 +99,10 @@ // M29 - Stop SD write // M30 - Delete file from SD (M30 filename.g) // M31 - Output time since last M109 or SD card start to serial -// M32 - Select file and start SD print (Can be used when printing from SD card) +// M32 - Select file and start SD print (Can be used _while_ printing from SD card files): +// syntax "M32 /path/filename#", or "M32 S !filename#" +// Call gcode file : "M32 P !filename#" and return to caller file after finishing (similar to #include). +// The '#' is necessary when calling from within sd files, as it stops buffer prereading // M42 - Change pin status via gcode Use M42 Px Sy to set pin x to value y, when omitting Px the onboard led will be used. // M80 - Turn on Power Supply // M81 - Turn off Power Supply @@ -100,6 +118,8 @@ // M107 - Fan off // M109 - Sxxx Wait for extruder current temp to reach target temp. Waits only when heating // Rxxx Wait for extruder current temp to reach target temp. Waits when heating and cooling +// IF AUTOTEMP is enabled, S B F. Exit autotemp by any M109 without F +// M112 - Emergency stop // M114 - Output current position to serial port // M115 - Capabilities string // M117 - display message @@ -109,36 +129,43 @@ // M128 - EtoP Open (BariCUDA EtoP = electricity to air pressure transducer by jmil) // M129 - EtoP Closed (BariCUDA EtoP = electricity to air pressure transducer by jmil) // M140 - Set bed target temp +// M150 - Set BlinkM Color Output R: Red<0-255> U(!): Green<0-255> B: Blue<0-255> over i2c, G for green does not work. // M190 - Sxxx Wait for bed current temp to reach target temp. Waits only when heating // Rxxx Wait for bed current temp to reach target temp. Waits when heating and cooling -// M200 - Set filament diameter +// M200 D- set filament diameter and set E axis units to cubic millimeters (use S0 to set back to millimeters). // M201 - Set max acceleration in units/s^2 for print moves (M201 X1000 Y1000) // 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 +// M204 - Set default acceleration: S normal moves T filament only moves (M204 S3000 T7000) in mm/sec^2 also sets minimum segment time in ms (B20000) to prevent buffer under-runs and M20 minimum feedrate // M205 - advanced settings: minimum travel speed S=while printing T=travel only, B=minimum segment time X= maximum xy jerk, Z=maximum Z jerk, E=maximum E jerk -// M206 - set additional homeing offset -// M207 - set retract length S[positive mm] F[feedrate mm/sec] Z[additional zlift/hop] +// M206 - set additional homing offset +// M207 - set retract length S[positive mm] F[feedrate mm/min] Z[additional zlift/hop], stays in mm regardless of M200 setting // M208 - set recover=unretract length S[positive mm surplus to the M207 S*] F[feedrate mm/sec] // M209 - S<1=true/0=false> enable automatic retract detect if the slicer did not support G10/11: every normal extrude-only move will be classified as retract depending on the direction. // M218 - set hotend offset (in mm): T X Y // M220 S- set speed factor override percentage // M221 S- set extrude factor override percentage +// M226 P S- Wait until the specified pin reaches the state required // M240 - Trigger a camera to take a photograph // M250 - Set LCD contrast C (value 0..63) // M280 - set servo position absolute. P: servo index, S: angle or microseconds -// M300 - Play beepsound S P +// M300 - Play beep sound S P // M301 - Set PID parameters P I and D // M302 - Allow cold extrudes, or set the minimum extrude S. // M303 - PID relay autotune S sets the target temperature. (default target temperature = 150C) // M304 - Set bed PID parameters P I and D // M400 - Finish all moves -// M500 - stores paramters in EEPROM +// M401 - Lower z-probe if present +// M402 - Raise z-probe if present +// M500 - stores parameters in EEPROM // 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) +// M503 - print the current settings (from memory not from EEPROM) // M540 - Use S[0|1] to enable or disable the stop SD card print on endstop hit (requires ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) // M600 - Pause for filament change X[pos] Y[pos] Z[relative lift] E[initial retract] L[later retract distance for removal] +// M665 - set delta configurations +// M666 - set delta endstop adjustment +// M605 - Set dual x-carriage movement mode: S [ X R ] // M907 - Set digital trimpot motor current using axis codes. // M908 - Control digital trimpot directly. // M350 - Set microstepping mode. @@ -164,13 +191,40 @@ bool axis_relative_modes[] = AXIS_RELATIVE_MODES; int feedmultiply=100; //100->1 200->2 int saved_feedmultiply; int extrudemultiply=100; //100->1 200->2 +int extruder_multiply[EXTRUDERS] = {100 + #if EXTRUDERS > 1 + , 100 + #if EXTRUDERS > 2 + , 100 + #endif + #endif +}; +float volumetric_multiplier[EXTRUDERS] = {1.0 + #if EXTRUDERS > 1 + , 1.0 + #if EXTRUDERS > 2 + , 1.0 + #endif + #endif +}; float current_position[NUM_AXIS] = { 0.0, 0.0, 0.0, 0.0 }; float add_homeing[3]={0,0,0}; +#ifdef DELTA +float endstop_adj[3]={0,0,0}; +#endif float min_pos[3] = { X_MIN_POS, Y_MIN_POS, Z_MIN_POS }; float max_pos[3] = { X_MAX_POS, Y_MAX_POS, Z_MAX_POS }; -// Extruder offset, only in XY plane +bool axis_known_position[3] = {false, false, false}; +float zprobe_zoffset; + +// Extruder offset #if EXTRUDERS > 1 -float extruder_offset[2][EXTRUDERS] = { +#ifndef DUAL_X_CARRIAGE + #define NUM_EXTRUDER_OFFSETS 2 // only in XY plane +#else + #define NUM_EXTRUDER_OFFSETS 3 // supports offsets in XYZ plane +#endif +float extruder_offset[NUM_EXTRUDER_OFFSETS][EXTRUDERS] = { #if defined(EXTRUDER_OFFSET_X) && defined(EXTRUDER_OFFSET_Y) EXTRUDER_OFFSET_X, EXTRUDER_OFFSET_Y #endif @@ -188,24 +242,47 @@ int EtoPPressure=0; #endif #ifdef FWRETRACT - bool autoretract_enabled=true; + bool autoretract_enabled=false; bool retracted=false; - float retract_length=3, retract_feedrate=17*60, retract_zlift=0.8; - float retract_recover_length=0, retract_recover_feedrate=8*60; + float retract_length = RETRACT_LENGTH; + float retract_feedrate = RETRACT_FEEDRATE; + float retract_zlift = RETRACT_ZLIFT; + float retract_recover_length = RETRACT_RECOVER_LENGTH; + float retract_recover_feedrate = RETRACT_RECOVER_FEEDRATE; #endif #ifdef ULTIPANEL - bool powersupply = true; + #ifdef PS_DEFAULT_OFF + bool powersupply = false; + #else + bool powersupply = true; + #endif #endif +#ifdef DELTA + float delta[3] = {0.0, 0.0, 0.0}; + #define SIN_60 0.8660254037844386 + #define COS_60 0.5 + // these are the default values, can be overriden with M665 + float delta_radius= DELTA_RADIUS; + float delta_tower1_x= -SIN_60*delta_radius; // front left tower + float delta_tower1_y= -COS_60*delta_radius; + float delta_tower2_x= SIN_60*delta_radius; // front right tower + float delta_tower2_y= -COS_60*delta_radius; + float delta_tower3_x= 0.0; // back middle tower + float delta_tower3_y= delta_radius; + float delta_diagonal_rod= DELTA_DIAGONAL_ROD; + float delta_diagonal_rod_2= sq(delta_diagonal_rod); + float delta_segments_per_second= DELTA_SEGMENTS_PER_SECOND; +#endif + +bool cancel_heatup = false ; + //=========================================================================== -//=============================private variables============================= +//=============================Private Variables============================= //=========================================================================== const char axis_codes[NUM_AXIS] = {'X', 'Y', 'Z', 'E'}; static float destination[NUM_AXIS] = { 0.0, 0.0, 0.0, 0.0}; -#ifdef DELTA -static float delta[3] = {0.0, 0.0, 0.0}; -#endif static float offset[3] = {0.0, 0.0, 0.0}; static bool home_all_axis = true; static float feedrate = 1500.0, next_feedrate, saved_feedrate; @@ -222,7 +299,7 @@ static int buflen = 0; static char serial_char; static int serial_count = 0; static boolean comment_mode = false; -static char *strchr_pointer; // just a pointer to find chars in the cmd string like X, Y, Z, E, etc +static char *strchr_pointer; // just a pointer to find chars in the command string like X, Y, Z, E, etc const int sensitive_pins[] = SENSITIVE_PINS; // Sensitive pin list for M42 @@ -249,8 +326,14 @@ bool Stopped=false; bool CooldownNoWait = true; bool target_direction; +//Insert variables if CHDK is defined +#ifdef CHDK +unsigned long chdkHigh = 0; +boolean chdkActive = false; +#endif + //=========================================================================== -//=============================ROUTINES============================= +//=============================Routines====================================== //=========================================================================== void get_arc_coordinates(); @@ -287,7 +370,7 @@ void enquecommand(const char *cmd) { if(buflen < BUFSIZE) { - //this is dangerous if a mixing of serial and this happsens + //this is dangerous if a mixing of serial and this happens strcpy(&(cmdbuffer[bufindw][0]),cmd); SERIAL_ECHO_START; SERIAL_ECHOPGM("enqueing \""); @@ -302,7 +385,7 @@ void enquecommand_P(const char *cmd) { if(buflen < BUFSIZE) { - //this is dangerous if a mixing of serial and this happsens + //this is dangerous if a mixing of serial and this happens strcpy_P(&(cmdbuffer[bufindw][0]),cmd); SERIAL_ECHO_START; SERIAL_ECHOPGM("enqueing \""); @@ -337,7 +420,11 @@ void setup_powerhold() #endif #if defined(PS_ON_PIN) && PS_ON_PIN > -1 SET_OUTPUT(PS_ON_PIN); - WRITE(PS_ON_PIN, PS_ON_AWAKE); + #if defined(PS_DEFAULT_OFF) + WRITE(PS_ON_PIN, PS_ON_ASLEEP); + #else + WRITE(PS_ON_PIN, PS_ON_AWAKE); + #endif #endif } @@ -376,6 +463,11 @@ void servo_init() } } #endif + + #if defined (ENABLE_AUTO_BED_LEVELING) && (PROBE_SERVO_DEACTIVATION_DELAY > 0) + delay(PROBE_SERVO_DEACTIVATION_DELAY); + servos[servo_endstops[Z_AXIS]].detach(); + #endif } void setup() @@ -430,10 +522,14 @@ void setup() lcd_init(); _delay_ms(1000); // wait 1sec to display the splash screen - + #if defined(CONTROLLERFAN_PIN) && CONTROLLERFAN_PIN > -1 SET_OUTPUT(CONTROLLERFAN_PIN); //Set pin used for driver cooling fan - #endif + #endif + + #ifdef DIGIPOT_I2C + digipot_i2c_init(); + #endif } @@ -580,6 +676,11 @@ void get_command() } } + + //If command was e-stop process now + if(strcmp(cmdbuffer[bufindw], "M112") == 0) + kill(); + bufindw = (bufindw + 1)%BUFSIZE; buflen += 1; } @@ -595,11 +696,20 @@ void get_command() if(!card.sdprinting || serial_count!=0){ return; } - while( !card.eof() && buflen < BUFSIZE) { + + //'#' stops reading from SD to the buffer prematurely, so procedural macro calls are possible + // if it occurs, stop_buffering is triggered and the buffer is ran dry. + // this character _can_ occur in serial com, due to checksums. however, no checksums are used in SD printing + + static bool stop_buffering=false; + if(buflen==0) stop_buffering=false; + + while( !card.eof() && buflen < BUFSIZE && !stop_buffering) { int16_t n=card.get(); serial_char = (char)n; if(serial_char == '\n' || serial_char == '\r' || + (serial_char == '#' && comment_mode == false) || (serial_char == ':' && comment_mode == false) || serial_count >= (MAX_CMD_SIZE - 1)||n==-1) { @@ -619,6 +729,9 @@ void get_command() card.checkautostart(true); } + if(serial_char=='#') + stop_buffering=true; + if(!serial_count) { comment_mode = false; //for new command @@ -690,15 +803,20 @@ XYZ_CONSTS_FROM_CONFIG(signed char, home_dir, HOME_DIR); #endif #if X_HOME_DIR != -1 || X2_HOME_DIR != 1 #error "Please use canonical x-carriage assignment" // the x-carriages are defined by their homing directions - #endif - + #endif + +#define DXC_FULL_CONTROL_MODE 0 +#define DXC_AUTO_PARK_MODE 1 +#define DXC_DUPLICATION_MODE 2 +static int dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE; + static float x_home_pos(int extruder) { if (extruder == 0) return base_home_pos(X_AXIS) + add_homeing[X_AXIS]; else // In dual carriage mode the extruder offset provides an override of the // second X-carriage offset when homed - otherwise X2_HOME_POS is used. - // This allow soft recalibration of the second extruder offset position without firmware reflash + // This allow soft recalibration of the second extruder offset position without firmware reflash // (through the M218 command). return (extruder_offset[X_AXIS][1] > 0) ? extruder_offset[X_AXIS][1] : X2_HOME_POS; } @@ -707,23 +825,216 @@ static int x_home_dir(int extruder) { return (extruder == 0) ? X_HOME_DIR : X2_HOME_DIR; } -static float inactive_x_carriage_pos = X2_MAX_POS; -#endif +static float inactive_extruder_x_pos = X2_MAX_POS; // used in mode 0 & 1 +static bool active_extruder_parked = false; // used in mode 1 & 2 +static float raised_parked_position[NUM_AXIS]; // used in mode 1 +static unsigned long delayed_move_time = 0; // used in mode 1 +static float duplicate_extruder_x_offset = DEFAULT_DUPLICATION_X_OFFSET; // used in mode 2 +static float duplicate_extruder_temp_offset = 0; // used in mode 2 +bool extruder_duplication_enabled = false; // used in mode 2 +#endif //DUAL_X_CARRIAGE static void axis_is_at_home(int axis) { #ifdef DUAL_X_CARRIAGE - if (axis == X_AXIS && active_extruder != 0) { - current_position[X_AXIS] = x_home_pos(active_extruder); - min_pos[X_AXIS] = X2_MIN_POS; - max_pos[X_AXIS] = max(extruder_offset[X_AXIS][1], X2_MAX_POS); - return; + if (axis == X_AXIS) { + if (active_extruder != 0) { + current_position[X_AXIS] = x_home_pos(active_extruder); + min_pos[X_AXIS] = X2_MIN_POS; + max_pos[X_AXIS] = max(extruder_offset[X_AXIS][1], X2_MAX_POS); + return; + } + else if (dual_x_carriage_mode == DXC_DUPLICATION_MODE && active_extruder == 0) { + current_position[X_AXIS] = base_home_pos(X_AXIS) + add_homeing[X_AXIS]; + min_pos[X_AXIS] = base_min_pos(X_AXIS) + add_homeing[X_AXIS]; + max_pos[X_AXIS] = min(base_max_pos(X_AXIS) + add_homeing[X_AXIS], + max(extruder_offset[X_AXIS][1], X2_MAX_POS) - duplicate_extruder_x_offset); + return; + } } -#endif +#endif current_position[axis] = base_home_pos(axis) + add_homeing[axis]; min_pos[axis] = base_min_pos(axis) + add_homeing[axis]; max_pos[axis] = base_max_pos(axis) + add_homeing[axis]; } +#ifdef ENABLE_AUTO_BED_LEVELING +#ifdef AUTO_BED_LEVELING_GRID +static void set_bed_level_equation_lsq(double *plane_equation_coefficients) +{ + vector_3 planeNormal = vector_3(-plane_equation_coefficients[0], -plane_equation_coefficients[1], 1); + planeNormal.debug("planeNormal"); + plan_bed_level_matrix = matrix_3x3::create_look_at(planeNormal); + //bedLevel.debug("bedLevel"); + + //plan_bed_level_matrix.debug("bed level before"); + //vector_3 uncorrected_position = plan_get_position_mm(); + //uncorrected_position.debug("position before"); + + vector_3 corrected_position = plan_get_position(); +// corrected_position.debug("position after"); + current_position[X_AXIS] = corrected_position.x; + current_position[Y_AXIS] = corrected_position.y; + current_position[Z_AXIS] = corrected_position.z; + + // but the bed at 0 so we don't go below it. + current_position[Z_AXIS] = zprobe_zoffset; // in the lsq we reach here after raising the extruder due to the loop structure + + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); +} + +#else // not AUTO_BED_LEVELING_GRID + +static void set_bed_level_equation_3pts(float z_at_pt_1, float z_at_pt_2, float z_at_pt_3) { + + plan_bed_level_matrix.set_to_identity(); + + vector_3 pt1 = vector_3(ABL_PROBE_PT_1_X, ABL_PROBE_PT_1_Y, z_at_pt_1); + vector_3 pt2 = vector_3(ABL_PROBE_PT_2_X, ABL_PROBE_PT_2_Y, z_at_pt_2); + vector_3 pt3 = vector_3(ABL_PROBE_PT_3_X, ABL_PROBE_PT_3_Y, z_at_pt_3); + + vector_3 from_2_to_1 = (pt1 - pt2).get_normal(); + vector_3 from_2_to_3 = (pt3 - pt2).get_normal(); + vector_3 planeNormal = vector_3::cross(from_2_to_1, from_2_to_3).get_normal(); + planeNormal = vector_3(planeNormal.x, planeNormal.y, abs(planeNormal.z)); + + plan_bed_level_matrix = matrix_3x3::create_look_at(planeNormal); + + vector_3 corrected_position = plan_get_position(); + current_position[X_AXIS] = corrected_position.x; + current_position[Y_AXIS] = corrected_position.y; + current_position[Z_AXIS] = corrected_position.z; + + // put the bed at 0 so we don't go below it. + current_position[Z_AXIS] = zprobe_zoffset; + + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + +} + +#endif // AUTO_BED_LEVELING_GRID + +static void run_z_probe() { + plan_bed_level_matrix.set_to_identity(); + feedrate = homing_feedrate[Z_AXIS]; + + // move down until you find the bed + float zPosition = -10; + plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS], feedrate/60, active_extruder); + st_synchronize(); + + // we have to let the planner know where we are right now as it is not where we said to go. + zPosition = st_get_position_mm(Z_AXIS); + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS]); + + // move up the retract distance + zPosition += home_retract_mm(Z_AXIS); + plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS], feedrate/60, active_extruder); + st_synchronize(); + + // move back down slowly to find bed + feedrate = homing_feedrate[Z_AXIS]/4; + zPosition -= home_retract_mm(Z_AXIS) * 2; + plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS], feedrate/60, active_extruder); + st_synchronize(); + + current_position[Z_AXIS] = st_get_position_mm(Z_AXIS); + // make sure the planner knows where we are as it may be a bit different than we last said to move to + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); +} + +static void do_blocking_move_to(float x, float y, float z) { + float oldFeedRate = feedrate; + + feedrate = XY_TRAVEL_SPEED; + + current_position[X_AXIS] = x; + current_position[Y_AXIS] = y; + current_position[Z_AXIS] = z; + plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], feedrate/60, active_extruder); + st_synchronize(); + + feedrate = oldFeedRate; +} + +static void do_blocking_move_relative(float offset_x, float offset_y, float offset_z) { + do_blocking_move_to(current_position[X_AXIS] + offset_x, current_position[Y_AXIS] + offset_y, current_position[Z_AXIS] + offset_z); +} + +static void setup_for_endstop_move() { + saved_feedrate = feedrate; + saved_feedmultiply = feedmultiply; + feedmultiply = 100; + previous_millis_cmd = millis(); + + enable_endstops(true); +} + +static void clean_up_after_endstop_move() { +#ifdef ENDSTOPS_ONLY_FOR_HOMING + enable_endstops(false); +#endif + + feedrate = saved_feedrate; + feedmultiply = saved_feedmultiply; + previous_millis_cmd = millis(); +} + +static void engage_z_probe() { + // Engage Z Servo endstop if enabled + #ifdef SERVO_ENDSTOPS + if (servo_endstops[Z_AXIS] > -1) { +#if defined (ENABLE_AUTO_BED_LEVELING) && (PROBE_SERVO_DEACTIVATION_DELAY > 0) + servos[servo_endstops[Z_AXIS]].attach(0); +#endif + servos[servo_endstops[Z_AXIS]].write(servo_endstop_angles[Z_AXIS * 2]); +#if defined (ENABLE_AUTO_BED_LEVELING) && (PROBE_SERVO_DEACTIVATION_DELAY > 0) + delay(PROBE_SERVO_DEACTIVATION_DELAY); + servos[servo_endstops[Z_AXIS]].detach(); +#endif + } + #endif +} + +static void retract_z_probe() { + // Retract Z Servo endstop if enabled + #ifdef SERVO_ENDSTOPS + if (servo_endstops[Z_AXIS] > -1) { +#if defined (ENABLE_AUTO_BED_LEVELING) && (PROBE_SERVO_DEACTIVATION_DELAY > 0) + servos[servo_endstops[Z_AXIS]].attach(0); +#endif + servos[servo_endstops[Z_AXIS]].write(servo_endstop_angles[Z_AXIS * 2 + 1]); +#if defined (ENABLE_AUTO_BED_LEVELING) && (PROBE_SERVO_DEACTIVATION_DELAY > 0) + delay(PROBE_SERVO_DEACTIVATION_DELAY); + servos[servo_endstops[Z_AXIS]].detach(); +#endif + } + #endif +} + +/// Probe bed height at position (x,y), returns the measured z value +static float probe_pt(float x, float y, float z_before) { + // move to right place + do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], z_before); + do_blocking_move_to(x - X_PROBE_OFFSET_FROM_EXTRUDER, y - Y_PROBE_OFFSET_FROM_EXTRUDER, current_position[Z_AXIS]); + + engage_z_probe(); // Engage Z Servo endstop if available + run_z_probe(); + float measured_z = current_position[Z_AXIS]; + retract_z_probe(); + + SERIAL_PROTOCOLPGM(MSG_BED); + SERIAL_PROTOCOLPGM(" x: "); + SERIAL_PROTOCOL(x); + SERIAL_PROTOCOLPGM(" y: "); + SERIAL_PROTOCOL(y); + SERIAL_PROTOCOLPGM(" z: "); + SERIAL_PROTOCOL(measured_z); + SERIAL_PROTOCOLPGM("\n"); + return measured_z; +} + +#endif // #ifdef ENABLE_AUTO_BED_LEVELING + static void homeaxis(int axis) { #define HOMEAXIS_DO(LETTER) \ ((LETTER##_MIN_PIN > -1 && LETTER##_HOME_DIR==-1) || (LETTER##_MAX_PIN > -1 && LETTER##_HOME_DIR==1)) @@ -738,15 +1049,23 @@ static void homeaxis(int axis) { axis_home_dir = x_home_dir(active_extruder); #endif + current_position[axis] = 0; + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + + // Engage Servo endstop if enabled #ifdef SERVO_ENDSTOPS - if (SERVO_ENDSTOPS[axis] > -1) { + #if defined (ENABLE_AUTO_BED_LEVELING) && (PROBE_SERVO_DEACTIVATION_DELAY > 0) + if (axis==Z_AXIS) { + engage_z_probe(); + } + else + #endif + if (servo_endstops[axis] > -1) { servos[servo_endstops[axis]].write(servo_endstop_angles[axis * 2]); } #endif - - current_position[axis] = 0; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + destination[axis] = 1.5 * max_length(axis) * axis_home_dir; feedrate = homing_feedrate[axis]; plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder); @@ -766,27 +1085,82 @@ static void homeaxis(int axis) { #endif plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder); st_synchronize(); - +#ifdef DELTA + // retrace by the amount specified in endstop_adj + if (endstop_adj[axis] * axis_home_dir < 0) { + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + destination[axis] = endstop_adj[axis]; + plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder); + st_synchronize(); + } +#endif axis_is_at_home(axis); destination[axis] = current_position[axis]; feedrate = 0.0; endstops_hit_on_purpose(); + axis_known_position[axis] = true; // Retract Servo endstop if enabled #ifdef SERVO_ENDSTOPS - if (SERVO_ENDSTOPS[axis] > -1) { + if (servo_endstops[axis] > -1) { servos[servo_endstops[axis]].write(servo_endstop_angles[axis * 2 + 1]); } #endif +#if defined (ENABLE_AUTO_BED_LEVELING) && (PROBE_SERVO_DEACTIVATION_DELAY > 0) + if (axis==Z_AXIS) retract_z_probe(); +#endif + } } #define HOMEAXIS(LETTER) homeaxis(LETTER##_AXIS) +void refresh_cmd_timeout(void) +{ + previous_millis_cmd = millis(); +} + +#ifdef FWRETRACT + void retract(bool retracting) { + if(retracting && !retracted) { + destination[X_AXIS]=current_position[X_AXIS]; + destination[Y_AXIS]=current_position[Y_AXIS]; + destination[Z_AXIS]=current_position[Z_AXIS]; + destination[E_AXIS]=current_position[E_AXIS]; + current_position[E_AXIS]+=retract_length/volumetric_multiplier[active_extruder]; + plan_set_e_position(current_position[E_AXIS]); + float oldFeedrate = feedrate; + feedrate=retract_feedrate*60; + retracted=true; + prepare_move(); + current_position[Z_AXIS]-=retract_zlift; + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + prepare_move(); + feedrate = oldFeedrate; + } else if(!retracting && retracted) { + destination[X_AXIS]=current_position[X_AXIS]; + destination[Y_AXIS]=current_position[Y_AXIS]; + destination[Z_AXIS]=current_position[Z_AXIS]; + destination[E_AXIS]=current_position[E_AXIS]; + current_position[Z_AXIS]+=retract_zlift; + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + //prepare_move(); + current_position[E_AXIS]-=(retract_length+retract_recover_length)/volumetric_multiplier[active_extruder]; + plan_set_e_position(current_position[E_AXIS]); + float oldFeedrate = feedrate; + feedrate=retract_recover_feedrate*60; + retracted=false; + prepare_move(); + feedrate = oldFeedrate; + } + } //retract +#endif //FWRETRACT void process_commands() { unsigned long codenum; //throw away variable char *starpos = NULL; - +#ifdef ENABLE_AUTO_BED_LEVELING + float x_tmp, y_tmp, z_tmp, real_z; +#endif if(code_seen('G')) { switch((int)code_value()) @@ -795,23 +1169,37 @@ void process_commands() case 1: // G1 if(Stopped == false) { get_coordinates(); // For X Y Z E F + #ifdef FWRETRACT + if(autoretract_enabled) + if( !(code_seen('X') || code_seen('Y') || code_seen('Z')) && code_seen('E')) { + float echange=destination[E_AXIS]-current_position[E_AXIS]; + if((echange<-MIN_RETRACT && !retracted) || (echange>MIN_RETRACT && retracted)) { //move appears to be an attempt to retract or recover + current_position[E_AXIS] = destination[E_AXIS]; //hide the slicer-generated retract/recover from calculations + plan_set_e_position(current_position[E_AXIS]); //AND from the planner + retract(!retracted); + return; + } + } + #endif //FWRETRACT prepare_move(); //ClearToSend(); return; } - //break; + break; case 2: // G2 - CW ARC if(Stopped == false) { get_arc_coordinates(); prepare_arc_move(true); return; } + break; case 3: // G3 - CCW ARC if(Stopped == false) { get_arc_coordinates(); prepare_arc_move(false); return; } + break; case 4: // G4 dwell LCD_MESSAGEPGM(MSG_DWELL); codenum = 0; @@ -829,35 +1217,18 @@ void process_commands() break; #ifdef FWRETRACT case 10: // G10 retract - if(!retracted) - { - destination[X_AXIS]=current_position[X_AXIS]; - destination[Y_AXIS]=current_position[Y_AXIS]; - destination[Z_AXIS]=current_position[Z_AXIS]; - current_position[Z_AXIS]+=-retract_zlift; - destination[E_AXIS]=current_position[E_AXIS]-retract_length; - feedrate=retract_feedrate; - retracted=true; - prepare_move(); - } - + retract(true); break; - case 11: // G10 retract_recover - if(!retracted) - { - destination[X_AXIS]=current_position[X_AXIS]; - destination[Y_AXIS]=current_position[Y_AXIS]; - destination[Z_AXIS]=current_position[Z_AXIS]; - - current_position[Z_AXIS]+=retract_zlift; - current_position[E_AXIS]+=-retract_recover_length; - feedrate=retract_recover_feedrate; - retracted=false; - prepare_move(); - } + case 11: // G11 retract_recover + retract(false); break; #endif //FWRETRACT case 28: //G28 Home all Axis one at a time +#ifdef ENABLE_AUTO_BED_LEVELING + plan_bed_level_matrix.set_to_identity(); //Reset the plane ("erase" all leveling data) +#endif //ENABLE_AUTO_BED_LEVELING + + saved_feedrate = feedrate; saved_feedmultiply = feedmultiply; feedmultiply = 100; @@ -868,7 +1239,7 @@ void process_commands() for(int8_t i=0; i < NUM_AXIS; i++) { destination[i] = current_position[i]; } - feedrate = 0.0; + feedrate = 0.0; #ifdef DELTA // A delta can only safely home all axis at the same time @@ -878,7 +1249,7 @@ void process_commands() current_position[X_AXIS] = 0; current_position[Y_AXIS] = 0; current_position[Z_AXIS] = 0; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); destination[X_AXIS] = 3 * Z_MAX_LENGTH; destination[Y_AXIS] = 3 * Z_MAX_LENGTH; @@ -891,7 +1262,7 @@ void process_commands() current_position[X_AXIS] = destination[X_AXIS]; current_position[Y_AXIS] = destination[Y_AXIS]; current_position[Z_AXIS] = destination[Z_AXIS]; - + // take care of back off and rehome now we are all at the top HOMEAXIS(X); HOMEAXIS(Y); @@ -902,7 +1273,7 @@ void process_commands() #else // NOT DELTA - home_all_axis = !((code_seen(axis_codes[0])) || (code_seen(axis_codes[1])) || (code_seen(axis_codes[2]))); + home_all_axis = !((code_seen(axis_codes[X_AXIS])) || (code_seen(axis_codes[Y_AXIS])) || (code_seen(axis_codes[Z_AXIS]))); #if Z_HOME_DIR > 0 // If homing away from BED do Z first if((home_all_axis) || (code_seen(axis_codes[Z_AXIS]))) { @@ -919,13 +1290,19 @@ void process_commands() int x_axis_home_dir = home_dir(X_AXIS); #else int x_axis_home_dir = x_home_dir(active_extruder); + extruder_duplication_enabled = false; #endif - + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); destination[X_AXIS] = 1.5 * max_length(X_AXIS) * x_axis_home_dir;destination[Y_AXIS] = 1.5 * max_length(Y_AXIS) * home_dir(Y_AXIS); feedrate = homing_feedrate[X_AXIS]; if(homing_feedrate[Y_AXIS] max_length(Y_AXIS)) { + feedrate *= sqrt(pow(max_length(Y_AXIS) / max_length(X_AXIS), 2) + 1); + } else { + feedrate *= sqrt(pow(max_length(X_AXIS) / max_length(Y_AXIS), 2) + 1); + } plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder); st_synchronize(); @@ -949,24 +1326,25 @@ void process_commands() { #ifdef DUAL_X_CARRIAGE int tmp_extruder = active_extruder; + extruder_duplication_enabled = false; active_extruder = !active_extruder; HOMEAXIS(X); - inactive_x_carriage_pos = current_position[X_AXIS]; + inactive_extruder_x_pos = current_position[X_AXIS]; active_extruder = tmp_extruder; - #endif HOMEAXIS(X); + // reset state used by the different modes + memcpy(raised_parked_position, current_position, sizeof(raised_parked_position)); + delayed_move_time = 0; + active_extruder_parked = true; + #else + HOMEAXIS(X); + #endif } if((home_all_axis) || (code_seen(axis_codes[Y_AXIS]))) { HOMEAXIS(Y); } - #if Z_HOME_DIR < 0 // If homing towards BED do Z last - if((home_all_axis) || (code_seen(axis_codes[Z_AXIS]))) { - HOMEAXIS(Z); - } - #endif - if(code_seen(axis_codes[X_AXIS])) { if(code_value_long() != 0) { @@ -980,14 +1358,77 @@ void process_commands() } } + #if Z_HOME_DIR < 0 // If homing towards BED do Z last + #ifndef Z_SAFE_HOMING + if((home_all_axis) || (code_seen(axis_codes[Z_AXIS]))) { + #if defined (Z_RAISE_BEFORE_HOMING) && (Z_RAISE_BEFORE_HOMING > 0) + destination[Z_AXIS] = Z_RAISE_BEFORE_HOMING * home_dir(Z_AXIS) * (-1); // Set destination away from bed + feedrate = max_feedrate[Z_AXIS]; + plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate, active_extruder); + st_synchronize(); + #endif + HOMEAXIS(Z); + } + #else // Z Safe mode activated. + if(home_all_axis) { + destination[X_AXIS] = round(Z_SAFE_HOMING_X_POINT - X_PROBE_OFFSET_FROM_EXTRUDER); + destination[Y_AXIS] = round(Z_SAFE_HOMING_Y_POINT - Y_PROBE_OFFSET_FROM_EXTRUDER); + destination[Z_AXIS] = Z_RAISE_BEFORE_HOMING * home_dir(Z_AXIS) * (-1); // Set destination away from bed + feedrate = XY_TRAVEL_SPEED; + current_position[Z_AXIS] = 0; + + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate, active_extruder); + st_synchronize(); + current_position[X_AXIS] = destination[X_AXIS]; + current_position[Y_AXIS] = destination[Y_AXIS]; + + HOMEAXIS(Z); + } + // Let's see if X and Y are homed and probe is inside bed area. + if(code_seen(axis_codes[Z_AXIS])) { + if ( (axis_known_position[X_AXIS]) && (axis_known_position[Y_AXIS]) \ + && (current_position[X_AXIS]+X_PROBE_OFFSET_FROM_EXTRUDER >= X_MIN_POS) \ + && (current_position[X_AXIS]+X_PROBE_OFFSET_FROM_EXTRUDER <= X_MAX_POS) \ + && (current_position[Y_AXIS]+Y_PROBE_OFFSET_FROM_EXTRUDER >= Y_MIN_POS) \ + && (current_position[Y_AXIS]+Y_PROBE_OFFSET_FROM_EXTRUDER <= Y_MAX_POS)) { + + current_position[Z_AXIS] = 0; + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + destination[Z_AXIS] = Z_RAISE_BEFORE_HOMING * home_dir(Z_AXIS) * (-1); // Set destination away from bed + feedrate = max_feedrate[Z_AXIS]; + plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate, active_extruder); + st_synchronize(); + + HOMEAXIS(Z); + } else if (!((axis_known_position[X_AXIS]) && (axis_known_position[Y_AXIS]))) { + LCD_MESSAGEPGM(MSG_POSITION_UNKNOWN); + SERIAL_ECHO_START; + SERIAL_ECHOLNPGM(MSG_POSITION_UNKNOWN); + } else { + LCD_MESSAGEPGM(MSG_ZPROBE_OUT); + SERIAL_ECHO_START; + SERIAL_ECHOLNPGM(MSG_ZPROBE_OUT); + } + } + #endif + #endif + + + if(code_seen(axis_codes[Z_AXIS])) { if(code_value_long() != 0) { current_position[Z_AXIS]=code_value()+add_homeing[2]; } } + #ifdef ENABLE_AUTO_BED_LEVELING + if((home_all_axis) || (code_seen(axis_codes[Z_AXIS]))) { + current_position[Z_AXIS] += zprobe_zoffset; //Add Z_Probe offset (the distance is negative) + } + #endif plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); #endif // else DELTA - + #ifdef ENDSTOPS_ONLY_FOR_HOMING enable_endstops(false); #endif @@ -997,6 +1438,177 @@ void process_commands() previous_millis_cmd = millis(); endstops_hit_on_purpose(); break; + +#ifdef ENABLE_AUTO_BED_LEVELING + case 29: // G29 Detailed Z-Probe, probes the bed at 3 or more points. + { + #if Z_MIN_PIN == -1 + #error "You must have a Z_MIN endstop in order to enable Auto Bed Leveling feature!!! Z_MIN_PIN must point to a valid hardware pin." + #endif + + // Prevent user from running a G29 without first homing in X and Y + if (! (axis_known_position[X_AXIS] && axis_known_position[Y_AXIS]) ) + { + LCD_MESSAGEPGM(MSG_POSITION_UNKNOWN); + SERIAL_ECHO_START; + SERIAL_ECHOLNPGM(MSG_POSITION_UNKNOWN); + break; // abort G29, since we don't know where we are + } + + st_synchronize(); + // make sure the bed_level_rotation_matrix is identity or the planner will get it incorectly + //vector_3 corrected_position = plan_get_position_mm(); + //corrected_position.debug("position before G29"); + plan_bed_level_matrix.set_to_identity(); + vector_3 uncorrected_position = plan_get_position(); + //uncorrected_position.debug("position durring G29"); + current_position[X_AXIS] = uncorrected_position.x; + current_position[Y_AXIS] = uncorrected_position.y; + current_position[Z_AXIS] = uncorrected_position.z; + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + setup_for_endstop_move(); + + feedrate = homing_feedrate[Z_AXIS]; +#ifdef AUTO_BED_LEVELING_GRID + // probe at the points of a lattice grid + + int xGridSpacing = (RIGHT_PROBE_BED_POSITION - LEFT_PROBE_BED_POSITION) / (AUTO_BED_LEVELING_GRID_POINTS-1); + int yGridSpacing = (BACK_PROBE_BED_POSITION - FRONT_PROBE_BED_POSITION) / (AUTO_BED_LEVELING_GRID_POINTS-1); + + + // solve the plane equation ax + by + d = z + // A is the matrix with rows [x y 1] for all the probed points + // B is the vector of the Z positions + // the normal vector to the plane is formed by the coefficients of the plane equation in the standard form, which is Vx*x+Vy*y+Vz*z+d = 0 + // so Vx = -a Vy = -b Vz = 1 (we want the vector facing towards positive Z + + // "A" matrix of the linear system of equations + double eqnAMatrix[AUTO_BED_LEVELING_GRID_POINTS*AUTO_BED_LEVELING_GRID_POINTS*3]; + // "B" vector of Z points + double eqnBVector[AUTO_BED_LEVELING_GRID_POINTS*AUTO_BED_LEVELING_GRID_POINTS]; + + + int probePointCounter = 0; + bool zig = true; + + for (int yProbe=FRONT_PROBE_BED_POSITION; yProbe <= BACK_PROBE_BED_POSITION; yProbe += yGridSpacing) + { + int xProbe, xInc; + if (zig) + { + xProbe = LEFT_PROBE_BED_POSITION; + //xEnd = RIGHT_PROBE_BED_POSITION; + xInc = xGridSpacing; + zig = false; + } else // zag + { + xProbe = RIGHT_PROBE_BED_POSITION; + //xEnd = LEFT_PROBE_BED_POSITION; + xInc = -xGridSpacing; + zig = true; + } + + for (int xCount=0; xCount < AUTO_BED_LEVELING_GRID_POINTS; xCount++) + { + float z_before; + if (probePointCounter == 0) + { + // raise before probing + z_before = Z_RAISE_BEFORE_PROBING; + } else + { + // raise extruder + z_before = current_position[Z_AXIS] + Z_RAISE_BETWEEN_PROBINGS; + } + + float measured_z = probe_pt(xProbe, yProbe, z_before); + + eqnBVector[probePointCounter] = measured_z; + + eqnAMatrix[probePointCounter + 0*AUTO_BED_LEVELING_GRID_POINTS*AUTO_BED_LEVELING_GRID_POINTS] = xProbe; + eqnAMatrix[probePointCounter + 1*AUTO_BED_LEVELING_GRID_POINTS*AUTO_BED_LEVELING_GRID_POINTS] = yProbe; + eqnAMatrix[probePointCounter + 2*AUTO_BED_LEVELING_GRID_POINTS*AUTO_BED_LEVELING_GRID_POINTS] = 1; + probePointCounter++; + xProbe += xInc; + } + } + clean_up_after_endstop_move(); + + // solve lsq problem + double *plane_equation_coefficients = qr_solve(AUTO_BED_LEVELING_GRID_POINTS*AUTO_BED_LEVELING_GRID_POINTS, 3, eqnAMatrix, eqnBVector); + + SERIAL_PROTOCOLPGM("Eqn coefficients: a: "); + SERIAL_PROTOCOL(plane_equation_coefficients[0]); + SERIAL_PROTOCOLPGM(" b: "); + SERIAL_PROTOCOL(plane_equation_coefficients[1]); + SERIAL_PROTOCOLPGM(" d: "); + SERIAL_PROTOCOLLN(plane_equation_coefficients[2]); + + + set_bed_level_equation_lsq(plane_equation_coefficients); + + free(plane_equation_coefficients); + +#else // AUTO_BED_LEVELING_GRID not defined + + // Probe at 3 arbitrary points + // probe 1 + float z_at_pt_1 = probe_pt(ABL_PROBE_PT_1_X, ABL_PROBE_PT_1_Y, Z_RAISE_BEFORE_PROBING); + + // probe 2 + float z_at_pt_2 = probe_pt(ABL_PROBE_PT_2_X, ABL_PROBE_PT_2_Y, current_position[Z_AXIS] + Z_RAISE_BETWEEN_PROBINGS); + + // probe 3 + float z_at_pt_3 = probe_pt(ABL_PROBE_PT_3_X, ABL_PROBE_PT_3_Y, current_position[Z_AXIS] + Z_RAISE_BETWEEN_PROBINGS); + + clean_up_after_endstop_move(); + + set_bed_level_equation_3pts(z_at_pt_1, z_at_pt_2, z_at_pt_3); + + +#endif // AUTO_BED_LEVELING_GRID + st_synchronize(); + + // The following code correct the Z height difference from z-probe position and hotend tip position. + // The Z height on homing is measured by Z-Probe, but the probe is quite far from the hotend. + // When the bed is uneven, this height must be corrected. + real_z = float(st_get_position(Z_AXIS))/axis_steps_per_unit[Z_AXIS]; //get the real Z (since the auto bed leveling is already correcting the plane) + x_tmp = current_position[X_AXIS] + X_PROBE_OFFSET_FROM_EXTRUDER; + y_tmp = current_position[Y_AXIS] + Y_PROBE_OFFSET_FROM_EXTRUDER; + z_tmp = current_position[Z_AXIS]; + + apply_rotation_xyz(plan_bed_level_matrix, x_tmp, y_tmp, z_tmp); //Apply the correction sending the probe offset + current_position[Z_AXIS] = z_tmp - real_z + current_position[Z_AXIS]; //The difference is added to current position and sent to planner. + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + } + break; + + case 30: // G30 Single Z Probe + { + engage_z_probe(); // Engage Z Servo endstop if available + + st_synchronize(); + // TODO: make sure the bed_level_rotation_matrix is identity or the planner will get set incorectly + setup_for_endstop_move(); + + feedrate = homing_feedrate[Z_AXIS]; + + run_z_probe(); + SERIAL_PROTOCOLPGM(MSG_BED); + SERIAL_PROTOCOLPGM(" X: "); + SERIAL_PROTOCOL(current_position[X_AXIS]); + SERIAL_PROTOCOLPGM(" Y: "); + SERIAL_PROTOCOL(current_position[Y_AXIS]); + SERIAL_PROTOCOLPGM(" Z: "); + SERIAL_PROTOCOL(current_position[Z_AXIS]); + SERIAL_PROTOCOLPGM("\n"); + + clean_up_after_endstop_move(); + + retract_z_probe(); // Retract Z Servo endstop if available + } + break; +#endif // ENABLE_AUTO_BED_LEVELING case 90: // G90 relative_mode = false; break; @@ -1127,18 +1739,40 @@ void process_commands() } break; case 32: //M32 - Select file and start SD print + { if(card.sdprinting) { st_synchronize(); - card.closefile(); - card.sdprinting = false; + } starpos = (strchr(strchr_pointer + 4,'*')); + + char* namestartpos = (strchr(strchr_pointer + 4,'!')); //find ! to indicate filename string start. + if(namestartpos==NULL) + { + namestartpos=strchr_pointer + 4; //default name position, 4 letters after the M + } + else + namestartpos++; //to skip the '!' + if(starpos!=NULL) *(starpos-1)='\0'; - card.openFile(strchr_pointer + 4,true); - card.startFileprint(); - starttime=millis(); - break; + + bool call_procedure=(code_seen('P')); + + if(strchr_pointer>namestartpos) + call_procedure=false; //false alert, 'P' found within filename + + if( card.cardOK ) + { + card.openFile(namestartpos,true,!call_procedure); + if(code_seen('S')) + if(strchr_pointer= 0 && pin_status <= 255) pin_number = code_value(); - for(int8_t i = 0; i < (int8_t)sizeof(sensitive_pins); i++) + for(int8_t i = 0; i < (int8_t)(sizeof(sensitive_pins)/sizeof(int)); i++) { if (sensitive_pins[i] == pin_number) { @@ -1198,8 +1832,15 @@ void process_commands() break; } if (code_seen('S')) setTargetHotend(code_value(), tmp_extruder); +#ifdef DUAL_X_CARRIAGE + if (dual_x_carriage_mode == DXC_DUPLICATION_MODE && tmp_extruder == 0) + setTargetHotend1(code_value() == 0.0 ? 0.0 : code_value() + duplicate_extruder_temp_offset); +#endif setWatch(); break; + case 112: // M112 -Emergency Stop + kill(); + break; case 140: // M140 set bed temp if (code_seen('S')) setTargetBed(code_value()); break; @@ -1218,16 +1859,51 @@ void process_commands() SERIAL_PROTOCOLPGM(" /"); SERIAL_PROTOCOL_F(degTargetBed(),1); #endif //TEMP_BED_PIN + for (int8_t cur_extruder = 0; cur_extruder < EXTRUDERS; ++cur_extruder) { + SERIAL_PROTOCOLPGM(" T"); + SERIAL_PROTOCOL(cur_extruder); + SERIAL_PROTOCOLPGM(":"); + SERIAL_PROTOCOL_F(degHotend(cur_extruder),1); + SERIAL_PROTOCOLPGM(" /"); + SERIAL_PROTOCOL_F(degTargetHotend(cur_extruder),1); + } #else SERIAL_ERROR_START; SERIAL_ERRORLNPGM(MSG_ERR_NO_THERMISTORS); #endif SERIAL_PROTOCOLPGM(" @:"); + #ifdef EXTRUDER_WATTS + SERIAL_PROTOCOL((EXTRUDER_WATTS * getHeaterPower(tmp_extruder))/127); + SERIAL_PROTOCOLPGM("W"); + #else SERIAL_PROTOCOL(getHeaterPower(tmp_extruder)); + #endif SERIAL_PROTOCOLPGM(" B@:"); + #ifdef BED_WATTS + SERIAL_PROTOCOL((BED_WATTS * getHeaterPower(-1))/127); + SERIAL_PROTOCOLPGM("W"); + #else SERIAL_PROTOCOL(getHeaterPower(-1)); + #endif + + #ifdef SHOW_TEMP_ADC_VALUES + #if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1 + SERIAL_PROTOCOLPGM(" ADC B:"); + SERIAL_PROTOCOL_F(degBed(),1); + SERIAL_PROTOCOLPGM("C->"); + SERIAL_PROTOCOL_F(rawBedTemp()/OVERSAMPLENR,0); + #endif + for (int8_t cur_extruder = 0; cur_extruder < EXTRUDERS; ++cur_extruder) { + SERIAL_PROTOCOLPGM(" T"); + SERIAL_PROTOCOL(cur_extruder); + SERIAL_PROTOCOLPGM(":"); + SERIAL_PROTOCOL_F(degHotend(cur_extruder),1); + SERIAL_PROTOCOLPGM("C->"); + SERIAL_PROTOCOL_F(rawHotendTemp(cur_extruder)/OVERSAMPLENR,0); + } + #endif SERIAL_PROTOCOLLN(""); return; @@ -1241,11 +1917,19 @@ void process_commands() #ifdef AUTOTEMP autotemp_enabled=false; #endif - if (code_seen('S')) { + if (code_seen('S')) { setTargetHotend(code_value(), tmp_extruder); +#ifdef DUAL_X_CARRIAGE + if (dual_x_carriage_mode == DXC_DUPLICATION_MODE && tmp_extruder == 0) + setTargetHotend1(code_value() == 0.0 ? 0.0 : code_value() + duplicate_extruder_temp_offset); +#endif CooldownNoWait = true; } else if (code_seen('R')) { setTargetHotend(code_value(), tmp_extruder); +#ifdef DUAL_X_CARRIAGE + if (dual_x_carriage_mode == DXC_DUPLICATION_MODE && tmp_extruder == 0) + setTargetHotend1(code_value() == 0.0 ? 0.0 : code_value() + duplicate_extruder_temp_offset); +#endif CooldownNoWait = false; } #ifdef AUTOTEMP @@ -1263,14 +1947,16 @@ void process_commands() /* See if we are heating up or cooling down */ target_direction = isHeatingHotend(tmp_extruder); // true if heating, false if cooling + + cancel_heatup = false; #ifdef TEMP_RESIDENCY_TIME long residencyStart; residencyStart = -1; /* continue to loop until we have reached the target temp _and_ until TEMP_RESIDENCY_TIME hasn't passed since we reached it */ - while((residencyStart == -1) || - (residencyStart >= 0 && (((unsigned int) (millis() - residencyStart)) < (TEMP_RESIDENCY_TIME * 1000UL))) ) { + while((!cancel_heatup)&&((residencyStart == -1) || + (residencyStart >= 0 && (((unsigned int) (millis() - residencyStart)) < (TEMP_RESIDENCY_TIME * 1000UL)))) ) { #else while ( target_direction ? (isHeatingHotend(tmp_extruder)) : (isCoolingHotend(tmp_extruder)&&(CooldownNoWait==false)) ) { #endif //TEMP_RESIDENCY_TIME @@ -1318,7 +2004,7 @@ void process_commands() case 190: // M190 - Wait for bed heater to reach target. #if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1 LCD_MESSAGEPGM(MSG_BED_HEATING); - if (code_seen('S')) { + if (code_seen('S')) { setTargetBed(code_value()); CooldownNoWait = true; } else if (code_seen('R')) { @@ -1327,9 +2013,10 @@ void process_commands() } codenum = millis(); + cancel_heatup = false; target_direction = isHeatingBed(); // true if heating, false if cooling - - while ( target_direction ? (isHeatingBed()) : (isCoolingBed()&&(CooldownNoWait==false)) ) + + while ( (target_direction)&&(!cancel_heatup) ? (isHeatingBed()) : (isCoolingBed()&&(CooldownNoWait==false)) ) { if(( millis() - codenum) > 1000 ) //Print Temp Reading every 1 second while heating up. { @@ -1401,6 +2088,15 @@ void process_commands() case 80: // M80 - Turn on Power Supply SET_OUTPUT(PS_ON_PIN); //GND WRITE(PS_ON_PIN, PS_ON_AWAKE); + + // If you have a switch on suicide pin, this is useful + // if you want to start another print with suicide feature after + // a print without suicide... + #if defined SUICIDE_PIN && SUICIDE_PIN > -1 + SET_OUTPUT(SUICIDE_PIN); + WRITE(SUICIDE_PIN, HIGH); + #endif + #ifdef ULTIPANEL powersupply = true; LCD_MESSAGEPGM(WELCOME_MSG); @@ -1408,7 +2104,7 @@ void process_commands() #endif break; #endif - + case 81: // M81 - Turn off Power Supply disable_heater(); st_synchronize(); @@ -1445,7 +2141,7 @@ void process_commands() } else { - bool all_axis = !((code_seen(axis_codes[0])) || (code_seen(axis_codes[1])) || (code_seen(axis_codes[2]))|| (code_seen(axis_codes[3]))); + bool all_axis = !((code_seen(axis_codes[X_AXIS])) || (code_seen(axis_codes[Y_AXIS])) || (code_seen(axis_codes[Z_AXIS]))|| (code_seen(axis_codes[E_AXIS]))); if(all_axis) { st_synchronize(); @@ -1471,8 +2167,9 @@ void process_commands() } break; case 85: // M85 - code_seen('S'); - max_inactive_time = code_value() * 1000; + if(code_seen('S')) { + max_inactive_time = code_value() * 1000; + } break; case 92: // M92 for(int8_t i=0; i < NUM_AXIS; i++) @@ -1507,18 +2204,18 @@ void process_commands() case 114: // M114 SERIAL_PROTOCOLPGM("X:"); SERIAL_PROTOCOL(current_position[X_AXIS]); - SERIAL_PROTOCOLPGM("Y:"); + SERIAL_PROTOCOLPGM(" Y:"); SERIAL_PROTOCOL(current_position[Y_AXIS]); - SERIAL_PROTOCOLPGM("Z:"); + SERIAL_PROTOCOLPGM(" Z:"); SERIAL_PROTOCOL(current_position[Z_AXIS]); - SERIAL_PROTOCOLPGM("E:"); + SERIAL_PROTOCOLPGM(" E:"); SERIAL_PROTOCOL(current_position[E_AXIS]); SERIAL_PROTOCOLPGM(MSG_COUNT_X); SERIAL_PROTOCOL(float(st_get_position(X_AXIS))/axis_steps_per_unit[X_AXIS]); - SERIAL_PROTOCOLPGM("Y:"); + SERIAL_PROTOCOLPGM(" Y:"); SERIAL_PROTOCOL(float(st_get_position(Y_AXIS))/axis_steps_per_unit[Y_AXIS]); - SERIAL_PROTOCOLPGM("Z:"); + SERIAL_PROTOCOLPGM(" Z:"); SERIAL_PROTOCOL(float(st_get_position(Z_AXIS))/axis_steps_per_unit[Z_AXIS]); SERIAL_PROTOCOLLN(""); @@ -1533,30 +2230,72 @@ void process_commands() SERIAL_PROTOCOLLN(MSG_M119_REPORT); #if defined(X_MIN_PIN) && X_MIN_PIN > -1 SERIAL_PROTOCOLPGM(MSG_X_MIN); - SERIAL_PROTOCOLLN(((READ(X_MIN_PIN)^X_ENDSTOPS_INVERTING)?MSG_ENDSTOP_HIT:MSG_ENDSTOP_OPEN)); + SERIAL_PROTOCOLLN(((READ(X_MIN_PIN)^X_MIN_ENDSTOP_INVERTING)?MSG_ENDSTOP_HIT:MSG_ENDSTOP_OPEN)); #endif #if defined(X_MAX_PIN) && X_MAX_PIN > -1 SERIAL_PROTOCOLPGM(MSG_X_MAX); - SERIAL_PROTOCOLLN(((READ(X_MAX_PIN)^X_ENDSTOPS_INVERTING)?MSG_ENDSTOP_HIT:MSG_ENDSTOP_OPEN)); + SERIAL_PROTOCOLLN(((READ(X_MAX_PIN)^X_MAX_ENDSTOP_INVERTING)?MSG_ENDSTOP_HIT:MSG_ENDSTOP_OPEN)); #endif #if defined(Y_MIN_PIN) && Y_MIN_PIN > -1 SERIAL_PROTOCOLPGM(MSG_Y_MIN); - SERIAL_PROTOCOLLN(((READ(Y_MIN_PIN)^Y_ENDSTOPS_INVERTING)?MSG_ENDSTOP_HIT:MSG_ENDSTOP_OPEN)); + SERIAL_PROTOCOLLN(((READ(Y_MIN_PIN)^Y_MIN_ENDSTOP_INVERTING)?MSG_ENDSTOP_HIT:MSG_ENDSTOP_OPEN)); #endif #if defined(Y_MAX_PIN) && Y_MAX_PIN > -1 SERIAL_PROTOCOLPGM(MSG_Y_MAX); - SERIAL_PROTOCOLLN(((READ(Y_MAX_PIN)^Y_ENDSTOPS_INVERTING)?MSG_ENDSTOP_HIT:MSG_ENDSTOP_OPEN)); + SERIAL_PROTOCOLLN(((READ(Y_MAX_PIN)^Y_MAX_ENDSTOP_INVERTING)?MSG_ENDSTOP_HIT:MSG_ENDSTOP_OPEN)); #endif #if defined(Z_MIN_PIN) && Z_MIN_PIN > -1 SERIAL_PROTOCOLPGM(MSG_Z_MIN); - SERIAL_PROTOCOLLN(((READ(Z_MIN_PIN)^Z_ENDSTOPS_INVERTING)?MSG_ENDSTOP_HIT:MSG_ENDSTOP_OPEN)); + SERIAL_PROTOCOLLN(((READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING)?MSG_ENDSTOP_HIT:MSG_ENDSTOP_OPEN)); #endif #if defined(Z_MAX_PIN) && Z_MAX_PIN > -1 SERIAL_PROTOCOLPGM(MSG_Z_MAX); - SERIAL_PROTOCOLLN(((READ(Z_MAX_PIN)^Z_ENDSTOPS_INVERTING)?MSG_ENDSTOP_HIT:MSG_ENDSTOP_OPEN)); + SERIAL_PROTOCOLLN(((READ(Z_MAX_PIN)^Z_MAX_ENDSTOP_INVERTING)?MSG_ENDSTOP_HIT:MSG_ENDSTOP_OPEN)); #endif break; //TODO: update for all axis, use for loop + #ifdef BLINKM + case 150: // M150 + { + byte red; + byte grn; + byte blu; + + if(code_seen('R')) red = code_value(); + if(code_seen('U')) grn = code_value(); + if(code_seen('B')) blu = code_value(); + + SendColors(red,grn,blu); + } + break; + #endif //BLINKM + case 200: // M200 D set filament diameter and set E axis units to cubic millimeters (use S0 to set back to millimeters). + { + float area = .0; + float radius = .0; + if(code_seen('D')) { + radius = (float)code_value() * .5; + if(radius == 0) { + area = 1; + } else { + area = M_PI * pow(radius, 2); + } + } else { + //reserved for setting filament diameter via UFID or filament measuring device + break; + } + tmp_extruder = active_extruder; + if(code_seen('T')) { + tmp_extruder = code_value(); + if(tmp_extruder >= EXTRUDERS) { + SERIAL_ECHO_START; + SERIAL_ECHO(MSG_M200_INVALID_EXTRUDER); + break; + } + } + volumetric_multiplier[tmp_extruder] = 1 / area; + } + break; case 201: // M201 for(int8_t i=0; i < NUM_AXIS; i++) { @@ -1602,8 +2341,29 @@ void process_commands() if(code_seen(axis_codes[i])) add_homeing[i] = code_value(); } break; + #ifdef DELTA + case 665: // M665 set delta configurations L R S + if(code_seen('L')) { + delta_diagonal_rod= code_value(); + } + if(code_seen('R')) { + delta_radius= code_value(); + } + if(code_seen('S')) { + delta_segments_per_second= code_value(); + } + + recalc_delta_settings(delta_radius, delta_diagonal_rod); + break; + case 666: // M666 set delta endstop adjustemnt + for(int8_t i=0; i < 3; i++) + { + if(code_seen(axis_codes[i])) endstop_adj[i] = code_value(); + } + break; + #endif #ifdef FWRETRACT - case 207: //M207 - set retract length S[positive mm] F[feedrate mm/sec] Z[additional zlift/hop] + case 207: //M207 - set retract length S[positive mm] F[feedrate mm/min] Z[additional zlift/hop] { if(code_seen('S')) { @@ -1611,14 +2371,14 @@ void process_commands() } if(code_seen('F')) { - retract_feedrate = code_value() ; + retract_feedrate = code_value()/60 ; } if(code_seen('Z')) { retract_zlift = code_value() ; } }break; - case 208: // M208 - set retract recover length S[positive mm surplus to the M207 S*] F[feedrate mm/sec] + case 208: // M208 - set retract recover length S[positive mm surplus to the M207 S*] F[feedrate mm/min] { if(code_seen('S')) { @@ -1626,7 +2386,7 @@ void process_commands() } if(code_seen('F')) { - retract_recover_feedrate = code_value() ; + retract_recover_feedrate = code_value()/60 ; } }break; case 209: // M209 - S<1=true/0=false> enable automatic retract detect if the slicer did not support G10/11: every normal extrude-only move will be classified as retract depending on the direction. @@ -1662,6 +2422,12 @@ void process_commands() { extruder_offset[Y_AXIS][tmp_extruder] = code_value(); } + #ifdef DUAL_X_CARRIAGE + if(code_seen('Z')) + { + extruder_offset[Z_AXIS][tmp_extruder] = code_value(); + } + #endif SERIAL_ECHO_START; SERIAL_ECHOPGM(MSG_HOTEND_OFFSET); for(tmp_extruder = 0; tmp_extruder < EXTRUDERS; tmp_extruder++) @@ -1670,6 +2436,10 @@ void process_commands() SERIAL_ECHO(extruder_offset[X_AXIS][tmp_extruder]); SERIAL_ECHO(","); SERIAL_ECHO(extruder_offset[Y_AXIS][tmp_extruder]); + #ifdef DUAL_X_CARRIAGE + SERIAL_ECHO(","); + SERIAL_ECHO(extruder_offset[Z_AXIS][tmp_extruder]); + #endif } SERIAL_ECHOLN(""); }break; @@ -1686,11 +2456,73 @@ void process_commands() { if(code_seen('S')) { - extrudemultiply = code_value() ; + int tmp_code = code_value(); + if (code_seen('T')) + { + if(setTargetedHotend(221)){ + break; + } + extruder_multiply[tmp_extruder] = tmp_code; + } + else + { + extrudemultiply = tmp_code ; + } } } break; - + + case 226: // M226 P S- Wait until the specified pin reaches the state required + { + if(code_seen('P')){ + int pin_number = code_value(); // pin number + int pin_state = -1; // required pin state - default is inverted + + if(code_seen('S')) pin_state = code_value(); // required pin state + + if(pin_state >= -1 && pin_state <= 1){ + + for(int8_t i = 0; i < (int8_t)(sizeof(sensitive_pins)/sizeof(int)); i++) + { + if (sensitive_pins[i] == pin_number) + { + pin_number = -1; + break; + } + } + + if (pin_number > -1) + { + st_synchronize(); + + pinMode(pin_number, INPUT); + + int target; + switch(pin_state){ + case 1: + target = HIGH; + break; + + case 0: + target = LOW; + break; + + case -1: + target = !digitalRead(pin_number); + break; + } + + while(digitalRead(pin_number) != target){ + manage_heater(); + manage_inactivity(); + lcd_update(); + } + } + } + } + } + break; + #if NUM_SERVOS > 0 case 280: // M280 - set servo position absolute. P: servo index, S: angle or microseconds { @@ -1701,7 +2533,14 @@ void process_commands() if (code_seen('S')) { servo_position = code_value(); if ((servo_index >= 0) && (servo_index < NUM_SERVOS)) { +#if defined (ENABLE_AUTO_BED_LEVELING) && (PROBE_SERVO_DEACTIVATION_DELAY > 0) + servos[servo_index].attach(0); +#endif servos[servo_index].write(servo_position); +#if defined (ENABLE_AUTO_BED_LEVELING) && (PROBE_SERVO_DEACTIVATION_DELAY > 0) + delay(PROBE_SERVO_DEACTIVATION_DELAY); + servos[servo_index].detach(); +#endif } else { SERIAL_ECHO_START; @@ -1722,7 +2561,7 @@ void process_commands() break; #endif // NUM_SERVOS > 0 - #if LARGE_FLASH == true && ( BEEPER > 0 || defined(ULTRALCD) ) + #if (LARGE_FLASH == true && ( BEEPER > 0 || defined(ULTRALCD) || defined(LCD_USE_I2C_BUZZER))) case 300: // M300 { int beepS = code_seen('S') ? code_value() : 110; @@ -1734,7 +2573,9 @@ void process_commands() delay(beepP); noTone(BEEPER); #elif defined(ULTRALCD) - lcd_buzz(beepS, beepP); + lcd_buzz(beepS, beepP); + #elif defined(LCD_USE_I2C_BUZZER) + lcd_buzz(beepP, beepS); #endif } else @@ -1794,23 +2635,33 @@ void process_commands() #endif //PIDTEMP case 240: // M240 Triggers a camera by emulating a Canon RC-1 : http://www.doc-diy.net/photo/rc-1_hacked/ { - #if defined(PHOTOGRAPH_PIN) && PHOTOGRAPH_PIN > -1 - const uint8_t NUM_PULSES=16; - const float PULSE_LENGTH=0.01524; - for(int i=0; i < NUM_PULSES; i++) { - WRITE(PHOTOGRAPH_PIN, HIGH); - _delay_ms(PULSE_LENGTH); - WRITE(PHOTOGRAPH_PIN, LOW); - _delay_ms(PULSE_LENGTH); + #ifdef CHDK + + SET_OUTPUT(CHDK); + WRITE(CHDK, HIGH); + chdkHigh = millis(); + chdkActive = true; + + #else + + #if defined(PHOTOGRAPH_PIN) && PHOTOGRAPH_PIN > -1 + const uint8_t NUM_PULSES=16; + const float PULSE_LENGTH=0.01524; + for(int i=0; i < NUM_PULSES; i++) { + WRITE(PHOTOGRAPH_PIN, HIGH); + _delay_ms(PULSE_LENGTH); + WRITE(PHOTOGRAPH_PIN, LOW); + _delay_ms(PULSE_LENGTH); } delay(7.33); for(int i=0; i < NUM_PULSES; i++) { - WRITE(PHOTOGRAPH_PIN, HIGH); - _delay_ms(PULSE_LENGTH); - WRITE(PHOTOGRAPH_PIN, LOW); - _delay_ms(PULSE_LENGTH); + WRITE(PHOTOGRAPH_PIN, HIGH); + _delay_ms(PULSE_LENGTH); + WRITE(PHOTOGRAPH_PIN, LOW); + _delay_ms(PULSE_LENGTH); } - #endif + #endif + #endif //chdk end if } break; #ifdef DOGLCD @@ -1852,6 +2703,19 @@ void process_commands() st_synchronize(); } break; +#if defined(ENABLE_AUTO_BED_LEVELING) && defined(SERVO_ENDSTOPS) + case 401: + { + engage_z_probe(); // Engage Z Servo endstop if available + } + break; + + case 402: + { + retract_z_probe(); // Retract Z Servo endstop if enabled + } + break; +#endif case 500: // M500 Store settings in EEPROM { Config_StoreSettings(); @@ -1879,6 +2743,43 @@ void process_commands() } break; #endif + + #ifdef CUSTOM_M_CODE_SET_Z_PROBE_OFFSET + case CUSTOM_M_CODE_SET_Z_PROBE_OFFSET: + { + float value; + if (code_seen('Z')) + { + value = code_value(); + if ((Z_PROBE_OFFSET_RANGE_MIN <= value) && (value <= Z_PROBE_OFFSET_RANGE_MAX)) + { + zprobe_zoffset = -value; // compare w/ line 278 of ConfigurationStore.cpp + SERIAL_ECHO_START; + SERIAL_ECHOLNPGM(MSG_ZPROBE_ZOFFSET " " MSG_OK); + SERIAL_PROTOCOLLN(""); + } + else + { + SERIAL_ECHO_START; + SERIAL_ECHOPGM(MSG_ZPROBE_ZOFFSET); + SERIAL_ECHOPGM(MSG_Z_MIN); + SERIAL_ECHO(Z_PROBE_OFFSET_RANGE_MIN); + SERIAL_ECHOPGM(MSG_Z_MAX); + SERIAL_ECHO(Z_PROBE_OFFSET_RANGE_MAX); + SERIAL_PROTOCOLLN(""); + } + } + else + { + SERIAL_ECHO_START; + SERIAL_ECHOLNPGM(MSG_ZPROBE_ZOFFSET " : "); + SERIAL_ECHO(-zprobe_zoffset); + SERIAL_PROTOCOLLN(""); + } + break; + } + #endif // CUSTOM_M_CODE_SET_Z_PROBE_OFFSET + #ifdef FILAMENTCHANGEENABLE case 600: //Pause for filament change X[pos] Y[pos] Z[relative lift] E[initial retract] L[later retract distance for removal] { @@ -1978,8 +2879,12 @@ void process_commands() delay(3); WRITE(BEEPER,LOW); delay(3); - #else - lcd_buzz(1000/6,100); + #else + #if !defined(LCD_FEEDBACK_FREQUENCY_HZ) || !defined(LCD_FEEDBACK_FREQUENCY_DURATION_MS) + lcd_buzz(1000/6,100); + #else + lcd_buzz(LCD_FEEDBACK_FREQUENCY_DURATION_MS,LCD_FEEDBACK_FREQUENCY_HZ); + #endif #endif } } @@ -2004,6 +2909,53 @@ void process_commands() } break; #endif //FILAMENTCHANGEENABLE + #ifdef DUAL_X_CARRIAGE + case 605: // Set dual x-carriage movement mode: + // M605 S0: Full control mode. The slicer has full control over x-carriage movement + // M605 S1: Auto-park mode. The inactive head will auto park/unpark without slicer involvement + // M605 S2 [Xnnn] [Rmmm]: Duplication mode. The second extruder will duplicate the first with nnn + // millimeters x-offset and an optional differential hotend temperature of + // mmm degrees. E.g., with "M605 S2 X100 R2" the second extruder will duplicate + // the first with a spacing of 100mm in the x direction and 2 degrees hotter. + // + // Note: the X axis should be homed after changing dual x-carriage mode. + { + st_synchronize(); + + if (code_seen('S')) + dual_x_carriage_mode = code_value(); + + if (dual_x_carriage_mode == DXC_DUPLICATION_MODE) + { + if (code_seen('X')) + duplicate_extruder_x_offset = max(code_value(),X2_MIN_POS - x_home_pos(0)); + + if (code_seen('R')) + duplicate_extruder_temp_offset = code_value(); + + SERIAL_ECHO_START; + SERIAL_ECHOPGM(MSG_HOTEND_OFFSET); + SERIAL_ECHO(" "); + SERIAL_ECHO(extruder_offset[X_AXIS][0]); + SERIAL_ECHO(","); + SERIAL_ECHO(extruder_offset[Y_AXIS][0]); + SERIAL_ECHO(" "); + SERIAL_ECHO(duplicate_extruder_x_offset); + SERIAL_ECHO(","); + SERIAL_ECHOLN(extruder_offset[Y_AXIS][1]); + } + else if (dual_x_carriage_mode != DXC_FULL_CONTROL_MODE && dual_x_carriage_mode != DXC_AUTO_PARK_MODE) + { + dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE; + } + + active_extruder_parked = false; + extruder_duplication_enabled = false; + delayed_move_time = 0; + } + break; + #endif //DUAL_X_CARRIAGE + case 907: // M907 Set digital trimpot motor current using axis codes. { #if defined(DIGIPOTSS_PIN) && DIGIPOTSS_PIN > -1 @@ -2011,6 +2963,21 @@ void process_commands() if(code_seen('B')) digipot_current(4,code_value()); if(code_seen('S')) for(int i=0;i<=4;i++) digipot_current(i,code_value()); #endif + #ifdef MOTOR_CURRENT_PWM_XY_PIN + if(code_seen('X')) digipot_current(0, code_value()); + #endif + #ifdef MOTOR_CURRENT_PWM_Z_PIN + if(code_seen('Z')) digipot_current(1, code_value()); + #endif + #ifdef MOTOR_CURRENT_PWM_E_PIN + if(code_seen('E')) digipot_current(2, code_value()); + #endif + #ifdef DIGIPOT_I2C + // this one uses actual amps in floating point + for(int i=0;i 0.0) feedrate = next_feedrate; } - #ifdef FWRETRACT - if(autoretract_enabled) - if( !(seen[X_AXIS] || seen[Y_AXIS] || seen[Z_AXIS]) && seen[E_AXIS]) - { - float echange=destination[E_AXIS]-current_position[E_AXIS]; - if(echange<-MIN_RETRACT) //retract - { - if(!retracted) - { - - destination[Z_AXIS]+=retract_zlift; //not sure why chaninging current_position negatively does not work. - //if slicer retracted by echange=-1mm and you want to retract 3mm, corrrectede=-2mm additionally - float correctede=-echange-retract_length; - //to generate the additional steps, not the destination is changed, but inversely the current position - current_position[E_AXIS]+=-correctede; - feedrate=retract_feedrate; - retracted=true; - } - - } - else - if(echange>MIN_RETRACT) //retract_recover - { - if(retracted) - { - //current_position[Z_AXIS]+=-retract_zlift; - //if slicer retracted_recovered by echange=+1mm and you want to retract_recover 3mm, corrrectede=2mm additionally - float correctede=-echange+1*retract_length+retract_recover_length; //total unretract=retract_length+retract_recover_length[surplus] - current_position[E_AXIS]+=correctede; //to generate the additional steps, not the destination is changed, but inversely the current position - feedrate=retract_recover_feedrate; - retracted=false; - } - } - - } - #endif //FWRETRACT } void get_arc_coordinates() @@ -2243,19 +3220,30 @@ void clamp_to_software_endstops(float target[3]) } #ifdef DELTA +void recalc_delta_settings(float radius, float diagonal_rod) +{ + delta_tower1_x= -SIN_60*radius; // front left tower + delta_tower1_y= -COS_60*radius; + delta_tower2_x= SIN_60*radius; // front right tower + delta_tower2_y= -COS_60*radius; + delta_tower3_x= 0.0; // back middle tower + delta_tower3_y= radius; + delta_diagonal_rod_2= sq(diagonal_rod); +} + void calculate_delta(float cartesian[3]) { - delta[X_AXIS] = sqrt(sq(DELTA_DIAGONAL_ROD) - - sq(DELTA_TOWER1_X-cartesian[X_AXIS]) - - sq(DELTA_TOWER1_Y-cartesian[Y_AXIS]) + delta[X_AXIS] = sqrt(delta_diagonal_rod_2 + - sq(delta_tower1_x-cartesian[X_AXIS]) + - sq(delta_tower1_y-cartesian[Y_AXIS]) ) + cartesian[Z_AXIS]; - delta[Y_AXIS] = sqrt(sq(DELTA_DIAGONAL_ROD) - - sq(DELTA_TOWER2_X-cartesian[X_AXIS]) - - sq(DELTA_TOWER2_Y-cartesian[Y_AXIS]) + delta[Y_AXIS] = sqrt(delta_diagonal_rod_2 + - sq(delta_tower2_x-cartesian[X_AXIS]) + - sq(delta_tower2_y-cartesian[Y_AXIS]) ) + cartesian[Z_AXIS]; - delta[Z_AXIS] = sqrt(sq(DELTA_DIAGONAL_ROD) - - sq(DELTA_TOWER3_X-cartesian[X_AXIS]) - - sq(DELTA_TOWER3_Y-cartesian[Y_AXIS]) + delta[Z_AXIS] = sqrt(delta_diagonal_rod_2 + - sq(delta_tower3_x-cartesian[X_AXIS]) + - sq(delta_tower3_y-cartesian[Y_AXIS]) ) + cartesian[Z_AXIS]; /* SERIAL_ECHOPGM("cartesian x="); SERIAL_ECHO(cartesian[X_AXIS]); @@ -2285,7 +3273,7 @@ void prepare_move() if (cartesian_mm < 0.000001) { cartesian_mm = abs(difference[E_AXIS]); } if (cartesian_mm < 0.000001) { return; } float seconds = 6000 * cartesian_mm / feedrate / feedmultiply; - int steps = max(1, int(DELTA_SEGMENTS_PER_SECOND * seconds)); + int steps = max(1, int(delta_segments_per_second * seconds)); // SERIAL_ECHOPGM("mm="); SERIAL_ECHO(cartesian_mm); // SERIAL_ECHOPGM(" seconds="); SERIAL_ECHO(seconds); // SERIAL_ECHOPGM(" steps="); SERIAL_ECHOLN(steps); @@ -2300,6 +3288,48 @@ void prepare_move() active_extruder); } #else + +#ifdef DUAL_X_CARRIAGE + if (active_extruder_parked) + { + if (dual_x_carriage_mode == DXC_DUPLICATION_MODE && active_extruder == 0) + { + // move duplicate extruder into correct duplication position. + plan_set_position(inactive_extruder_x_pos, current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_buffer_line(current_position[X_AXIS] + duplicate_extruder_x_offset, current_position[Y_AXIS], current_position[Z_AXIS], + current_position[E_AXIS], max_feedrate[X_AXIS], 1); + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + st_synchronize(); + extruder_duplication_enabled = true; + active_extruder_parked = false; + } + else if (dual_x_carriage_mode == DXC_AUTO_PARK_MODE) // handle unparking of head + { + if (current_position[E_AXIS] == destination[E_AXIS]) + { + // this is a travel move - skit it but keep track of current position (so that it can later + // be used as start of first non-travel move) + if (delayed_move_time != 0xFFFFFFFFUL) + { + memcpy(current_position, destination, sizeof(current_position)); + if (destination[Z_AXIS] > raised_parked_position[Z_AXIS]) + raised_parked_position[Z_AXIS] = destination[Z_AXIS]; + delayed_move_time = millis(); + return; + } + } + delayed_move_time = 0; + // unpark extruder: 1) raise, 2) move into starting XY position, 3) lower + plan_buffer_line(raised_parked_position[X_AXIS], raised_parked_position[Y_AXIS], raised_parked_position[Z_AXIS], current_position[E_AXIS], max_feedrate[Z_AXIS], active_extruder); + plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], raised_parked_position[Z_AXIS], + current_position[E_AXIS], min(max_feedrate[X_AXIS],max_feedrate[Y_AXIS]), active_extruder); + plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], + current_position[E_AXIS], max_feedrate[Z_AXIS], active_extruder); + active_extruder_parked = false; + } + } +#endif //DUAL_X_CARRIAGE + // Do not use feedmultiply for E or Z only moves if( (current_position[X_AXIS] == destination [X_AXIS]) && (current_position[Y_AXIS] == destination [Y_AXIS])) { plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder); @@ -2307,7 +3337,7 @@ void prepare_move() else { plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate*feedmultiply/60/100.0, active_extruder); } -#endif +#endif //else DELTA for(int8_t i=0; i < NUM_AXIS; i++) { current_position[i] = destination[i]; } @@ -2331,10 +3361,10 @@ void prepare_arc_move(char isclockwise) { #if defined(CONTROLLERFAN_PIN) && CONTROLLERFAN_PIN > -1 #if defined(FAN_PIN) - #if CONTROLLERFAN_PIN == FAN_PIN + #if CONTROLLERFAN_PIN == FAN_PIN #error "You cannot set CONTROLLERFAN_PIN equal to FAN_PIN" #endif -#endif +#endif unsigned long lastMotor = 0; //Save the time for when a motor was turned on last unsigned long lastMotorCheck = 0; @@ -2345,7 +3375,7 @@ void controllerFan() { lastMotorCheck = millis(); - if(!READ(X_ENABLE_PIN) || !READ(Y_ENABLE_PIN) || !READ(Z_ENABLE_PIN) + if(!READ(X_ENABLE_PIN) || !READ(Y_ENABLE_PIN) || !READ(Z_ENABLE_PIN) || (soft_pwm_bed > 0) #if EXTRUDERS > 2 || !READ(E2_ENABLE_PIN) #endif @@ -2359,17 +3389,50 @@ void controllerFan() { lastMotor = millis(); //... set time to NOW so the fan will turn on } - - if ((millis() - lastMotor) >= (CONTROLLERFAN_SECS*1000UL) || lastMotor == 0) //If the last time any driver was enabled, is longer since than CONTROLLERSEC... + + if ((millis() - lastMotor) >= (CONTROLLERFAN_SECS*1000UL) || lastMotor == 0) //If the last time any driver was enabled, is longer since than CONTROLLERSEC... { - digitalWrite(CONTROLLERFAN_PIN, 0); - analogWrite(CONTROLLERFAN_PIN, 0); + digitalWrite(CONTROLLERFAN_PIN, 0); + analogWrite(CONTROLLERFAN_PIN, 0); } else { // allows digital or PWM fan output to be used (see M42 handling) digitalWrite(CONTROLLERFAN_PIN, CONTROLLERFAN_SPEED); - analogWrite(CONTROLLERFAN_PIN, CONTROLLERFAN_SPEED); + analogWrite(CONTROLLERFAN_PIN, CONTROLLERFAN_SPEED); + } + } +} +#endif + +#ifdef TEMP_STAT_LEDS +static bool blue_led = false; +static bool red_led = false; +static uint32_t stat_update = 0; + +void handle_status_leds(void) { + float max_temp = 0.0; + if(millis() > stat_update) { + stat_update += 500; // Update every 0.5s + for (int8_t cur_extruder = 0; cur_extruder < EXTRUDERS; ++cur_extruder) { + max_temp = max(max_temp, degHotend(cur_extruder)); + max_temp = max(max_temp, degTargetHotend(cur_extruder)); + } + #if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1 + max_temp = max(max_temp, degTargetBed()); + max_temp = max(max_temp, degBed()); + #endif + if((max_temp > 55.0) && (red_led == false)) { + digitalWrite(STAT_LED_RED, 1); + digitalWrite(STAT_LED_BLUE, 0); + red_led = true; + blue_led = false; + } + if((max_temp < 54.0) && (blue_led == false)) { + digitalWrite(STAT_LED_RED, 0); + digitalWrite(STAT_LED_BLUE, 1); + red_led = false; + blue_led = true; } } } @@ -2377,6 +3440,9 @@ void controllerFan() void manage_inactivity() { + if(buflen < (BUFSIZE-1)) + get_command(); + if( (millis() - previous_millis_cmd) > max_inactive_time ) if(max_inactive_time) kill(); @@ -2393,6 +3459,16 @@ void manage_inactivity() } } } + + #ifdef CHDK //Check if pin should be set to LOW after M240 set it to HIGH + if (chdkActive) + { + chdkActive = false; + if (millis()-chdkHigh < CHDK_DELAY) return; + WRITE(CHDK, LOW); + } + #endif + #if defined(KILL_PIN) && KILL_PIN > -1 if( 0 == READ(KILL_PIN) ) kill(); @@ -2408,8 +3484,8 @@ void manage_inactivity() enable_e0(); float oldepos=current_position[E_AXIS]; float oldedes=destination[E_AXIS]; - plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], - current_position[E_AXIS]+EXTRUDER_RUNOUT_EXTRUDE*EXTRUDER_RUNOUT_ESTEPS/axis_steps_per_unit[E_AXIS], + plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], + destination[E_AXIS]+EXTRUDER_RUNOUT_EXTRUDE*EXTRUDER_RUNOUT_ESTEPS/axis_steps_per_unit[E_AXIS], EXTRUDER_RUNOUT_SPEED/60.*EXTRUDER_RUNOUT_ESTEPS/axis_steps_per_unit[E_AXIS], active_extruder); current_position[E_AXIS]=oldepos; destination[E_AXIS]=oldedes; @@ -2419,6 +3495,19 @@ void manage_inactivity() WRITE(E0_ENABLE_PIN,oldstatus); } #endif + #if defined(DUAL_X_CARRIAGE) + // handle delayed move timeout + if (delayed_move_time != 0 && (millis() - delayed_move_time) > 1000 && Stopped == false) + { + // travel moves have been received so enact them + delayed_move_time = 0xFFFFFFFFUL; // force moves to be done + memcpy(destination,current_position,sizeof(destination)); + prepare_move(); + } + #endif + #ifdef TEMP_STAT_LEDS + handle_status_leds(); + #endif check_axes_activity(); } @@ -2436,7 +3525,7 @@ void kill() #if defined(PS_ON_PIN) && PS_ON_PIN > -1 pinMode(PS_ON_PIN,INPUT); -#endif +#endif SERIAL_ERROR_START; SERIAL_ERRORLNPGM(MSG_ERR_KILLED); LCD_ALERTMESSAGEPGM(MSG_KILLED); @@ -2547,6 +3636,9 @@ bool setTargetedHotend(int code){ case 218: SERIAL_ECHO(MSG_M218_INVALID_EXTRUDER); break; + case 221: + SERIAL_ECHO(MSG_M221_INVALID_EXTRUDER); + break; } SERIAL_ECHOLN(tmp_extruder); return true; diff --git a/Marlin/Menu Plans.xlsx b/Marlin/Menu Plans.xlsx index 45a58e403..8c7e2c17b 100644 Binary files a/Marlin/Menu Plans.xlsx and b/Marlin/Menu Plans.xlsx differ diff --git a/Marlin/Sd2Card.cpp b/Marlin/Sd2Card.cpp index 72f5661d8..69ae77735 100644 --- a/Marlin/Sd2Card.cpp +++ b/Marlin/Sd2Card.cpp @@ -373,6 +373,29 @@ bool Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) { * the value zero, false, is returned for failure. */ bool Sd2Card::readBlock(uint32_t blockNumber, uint8_t* dst) { +#ifdef SD_CHECK_AND_RETRY + uint8_t retryCnt = 3; + // use address if not SDHC card + if (type()!= SD_CARD_TYPE_SDHC) blockNumber <<= 9; + retry2: + retryCnt --; + if (cardCommand(CMD17, blockNumber)) { + error(SD_CARD_ERROR_CMD17); + if (retryCnt > 0) goto retry; + goto fail; + } + if (!readData(dst, 512)) + { + if (retryCnt > 0) goto retry; + goto fail; + } + return true; + retry: + chipSelectHigh(); + cardCommand(CMD12, 0);//Try sending a stop command, but ignore the result. + errorCode_ = 0; + goto retry2; +#else // use address if not SDHC card if (type()!= SD_CARD_TYPE_SDHC) blockNumber <<= 9; if (cardCommand(CMD17, blockNumber)) { @@ -380,6 +403,7 @@ bool Sd2Card::readBlock(uint32_t blockNumber, uint8_t* dst) { goto fail; } return readData(dst, 512); +#endif fail: chipSelectHigh(); @@ -397,6 +421,51 @@ bool Sd2Card::readData(uint8_t *dst) { chipSelectLow(); return readData(dst, 512); } + +#ifdef SD_CHECK_AND_RETRY +static const uint16_t crctab[] PROGMEM = { + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, + 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, + 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, + 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, + 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, + 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, + 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, + 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, + 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, + 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, + 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, + 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, + 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, + 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, + 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, + 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, + 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, + 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, + 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, + 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, + 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, + 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, + 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 +}; +static uint16_t CRC_CCITT(const uint8_t* data, size_t n) { + uint16_t crc = 0; + for (size_t i = 0; i < n; i++) { + crc = pgm_read_word(&crctab[(crc >> 8 ^ data[i]) & 0XFF]) ^ (crc << 8); + } + return crc; +} +#endif + //------------------------------------------------------------------------------ bool Sd2Card::readData(uint8_t* dst, uint16_t count) { // wait for start block token @@ -414,9 +483,22 @@ bool Sd2Card::readData(uint8_t* dst, uint16_t count) { // transfer data spiRead(dst, count); +#ifdef SD_CHECK_AND_RETRY + { + uint16_t calcCrc = CRC_CCITT(dst, count); + uint16_t recvCrc = spiRec() << 8; + recvCrc |= spiRec(); + if (calcCrc != recvCrc) + { + error(SD_CARD_ERROR_CRC); + goto fail; + } + } +#else // discard CRC spiRec(); spiRec(); +#endif chipSelectHigh(); return true; @@ -638,4 +720,4 @@ bool Sd2Card::writeStop() { return false; } -#endif +#endif diff --git a/Marlin/Sd2Card.h b/Marlin/Sd2Card.h index 7de5f11bc..d6b302bfe 100644 --- a/Marlin/Sd2Card.h +++ b/Marlin/Sd2Card.h @@ -103,6 +103,8 @@ uint8_t const SD_CARD_ERROR_WRITE_TIMEOUT = 0X17; uint8_t const SD_CARD_ERROR_SCK_RATE = 0X18; /** init() not called */ uint8_t const SD_CARD_ERROR_INIT_NOT_CALLED = 0X19; +/** crc check error */ +uint8_t const SD_CARD_ERROR_CRC = 0X20; //------------------------------------------------------------------------------ // card types /** Standard capacity V1 SD card */ diff --git a/Marlin/Sd2PinMap.h b/Marlin/Sd2PinMap.h index a40729df2..93ab943ce 100644 --- a/Marlin/Sd2PinMap.h +++ b/Marlin/Sd2PinMap.h @@ -222,10 +222,10 @@ uint8_t const SDA_PIN = 1; // D1 uint8_t const SCL_PIN = 0; // D0 // SPI port -uint8_t const SS_PIN = 20; // B0 -uint8_t const MOSI_PIN = 22; // B2 -uint8_t const MISO_PIN = 23; // B3 -uint8_t const SCK_PIN = 21; // B1 +uint8_t const SS_PIN = 20; // B0 +uint8_t const MOSI_PIN = 22; // B2 +uint8_t const MISO_PIN = 23; // B3 +uint8_t const SCK_PIN = 21; // B1 static const pin_map_t digitalPinMap[] = { {&DDRD, &PIND, &PORTD, 0}, // D0 0 diff --git a/Marlin/Servo.cpp b/Marlin/Servo.cpp index 47c16aa71..5f8c7efe3 100644 --- a/Marlin/Servo.cpp +++ b/Marlin/Servo.cpp @@ -262,6 +262,9 @@ uint8_t Servo::attach(int pin) uint8_t Servo::attach(int pin, int min, int max) { if(this->servoIndex < MAX_SERVOS ) { +#if defined (ENABLE_AUTO_BED_LEVELING) && (PROBE_SERVO_DEACTIVATION_DELAY > 0) + if (pin > 0) this->pin = pin; else pin = this->pin; +#endif 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 diff --git a/Marlin/Servo.h b/Marlin/Servo.h index 17c99f797..204497a4a 100644 --- a/Marlin/Servo.h +++ b/Marlin/Servo.h @@ -24,7 +24,7 @@ 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 sequence used to seize timers is defined in timers.h The methods are: @@ -50,7 +50,7 @@ /* * Defines for 16 bit timers used with Servo library * - * If _useTimerX is defined then TimerX is a 16 bit timer on the curent board + * If _useTimerX is defined then TimerX is a 16 bit timer on the current board * timer16_Sequence_t enumerates the sequence that the timers should be allocated * _Nbr_16timers indicates how many 16 bit timers are available. * @@ -77,7 +77,7 @@ typedef enum { _timer3, _Nbr_16timers } timer16_Sequence_t ; //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__) +#elif defined(__AVR_ATmega128__) ||defined(__AVR_ATmega1281__) || defined(__AVR_ATmega1284P__) ||defined(__AVR_ATmega2561__) #define _useTimer3 //#define _useTimer1 //typedef enum { _timer3, _timer1, _Nbr_16timers } timer16_Sequence_t ; @@ -89,12 +89,12 @@ typedef enum { _timer3, _Nbr_16timers } timer16_Sequence_t ; typedef enum { _Nbr_16timers } timer16_Sequence_t ; #endif -#define Servo_VERSION 2 // software version of this library +#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 REFRESH_INTERVAL 20000 // minimum 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) @@ -118,11 +118,14 @@ public: 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 write(int value); // if value is < 200 it is 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 +#if defined (ENABLE_AUTO_BED_LEVELING) && (PROBE_SERVO_DEACTIVATION_DELAY > 0) + int pin; // store the hardware pin of the servo +#endif 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 diff --git a/Marlin/cardreader.cpp b/Marlin/cardreader.cpp index 1eeec9193..d2fb418fb 100644 --- a/Marlin/cardreader.cpp +++ b/Marlin/cardreader.cpp @@ -19,9 +19,10 @@ CardReader::CardReader() logging = false; autostart_atmillis=0; workDirDepth = 0; + file_subcall_ctr=0; memset(workDirParents, 0, sizeof(workDirParents)); - autostart_stilltocheck=true; //the sd start is delayed, because otherwise the serial cannot answer fast enought to make contact with the hostsoftware. + autostart_stilltocheck=true; //the SD start is delayed, because otherwise the serial cannot answer fast enough to make contact with the host software. lastnr=0; //power to SD reader #if SDPOWER > -1 @@ -224,14 +225,71 @@ void CardReader::openLogFile(char* name) openFile(name, false); } -void CardReader::openFile(char* name,bool read) +void CardReader::getAbsFilename(char *t) +{ + uint8_t cnt=0; + *t='/';t++;cnt++; + for(uint8_t i=0;i(int)SD_PROCEDURE_DEPTH-1) + { + SERIAL_ERROR_START; + SERIAL_ERRORPGM("trying to call sub-gcode files with too many levels. MAX level is:"); + SERIAL_ERRORLN(SD_PROCEDURE_DEPTH); + kill(); + return; + } + + SERIAL_ECHO_START; + SERIAL_ECHOPGM("SUBROUTINE CALL target:\""); + SERIAL_ECHO(name); + SERIAL_ECHOPGM("\" parent:\""); + + //store current filename and position + getAbsFilename(filenames[file_subcall_ctr]); + + SERIAL_ECHO(filenames[file_subcall_ctr]); + SERIAL_ECHOPGM("\" pos"); + SERIAL_ECHOLN(sdpos); + filespos[file_subcall_ctr]=sdpos; + file_subcall_ctr++; + } + else + { + SERIAL_ECHO_START; + SERIAL_ECHOPGM("Now doing file: "); + SERIAL_ECHOLN(name); + } + file.close(); + } + else //opening fresh file + { + file_subcall_ctr=0; //resetting procedure depth in case user cancels print while in procedure + SERIAL_ECHO_START; + SERIAL_ECHOPGM("Now fresh file: "); + SERIAL_ECHOLN(name); + } sdprinting = false; - + SdFile myDir; curDir=&root; char *fname=name; @@ -379,7 +437,7 @@ void CardReader::removeFile(char* name) if (file.remove(curDir, fname)) { SERIAL_PROTOCOLPGM("File deleted:"); - SERIAL_PROTOCOL(fname); + SERIAL_PROTOCOLLN(fname); sdpos = 0; } else @@ -477,12 +535,21 @@ void CardReader::checkautostart(bool force) lastnr++; } -void CardReader::closefile() +void CardReader::closefile(bool store_location) { file.sync(); file.close(); saving = false; logging = false; + + if(store_location) + { + //future: store printer state, filename and position for continuing a stopped print + // so one can unplug the printer and continue printing the next day. + + } + + } void CardReader::getfilename(const uint8_t nr) @@ -547,14 +614,25 @@ void CardReader::updir() void CardReader::printingHasFinished() { st_synchronize(); - quickStop(); - file.close(); - sdprinting = false; - if(SD_FINISHED_STEPPERRELEASE) + if(file_subcall_ctr>0) //heading up to a parent file that called current as a procedure. + { + file.close(); + file_subcall_ctr--; + openFile(filenames[file_subcall_ctr],true,true); + setIndex(filespos[file_subcall_ctr]); + startFileprint(); + } + else { - //finishAndDisableSteppers(); - enquecommand_P(PSTR(SD_FINISHED_RELEASECOMMAND)); + quickStop(); + file.close(); + sdprinting = false; + if(SD_FINISHED_STEPPERRELEASE) + { + //finishAndDisableSteppers(); + enquecommand_P(PSTR(SD_FINISHED_RELEASECOMMAND)); + } + autotempShutdown(); } - autotempShutdown(); } #endif //SDSUPPORT diff --git a/Marlin/cardreader.h b/Marlin/cardreader.h index 6e5964529..78f7148b1 100644 --- a/Marlin/cardreader.h +++ b/Marlin/cardreader.h @@ -18,10 +18,10 @@ public: //this is to delay autostart and hence the initialisaiton of the sd card to some seconds after the normal init, so the device is available quick after a reset void checkautostart(bool x); - void openFile(char* name,bool read); + void openFile(char* name,bool read,bool replace_current=true); void openLogFile(char* name); void removeFile(char* name); - void closefile(); + void closefile(bool store_location=false); void release(); void startFileprint(); void pauseSDPrint(); @@ -31,6 +31,8 @@ public: void getfilename(const uint8_t nr); uint16_t getnrfilenames(); + void getAbsFilename(char *t); + void ls(); void chdir(const char * relpath); @@ -60,6 +62,11 @@ private: Sd2Card card; SdVolume volume; SdFile file; + #define SD_PROCEDURE_DEPTH 1 + #define MAXPATHNAMELENGTH (13*MAX_DIR_DEPTH+MAX_DIR_DEPTH+1) + uint8_t file_subcall_ctr; + uint32_t filespos[SD_PROCEDURE_DEPTH]; + char filenames[SD_PROCEDURE_DEPTH][MAXPATHNAMELENGTH]; uint32_t filesize; //int16_t n; unsigned long autostart_atmillis; diff --git a/Marlin/createTemperatureLookupMarlin.py b/Marlin/createTemperatureLookupMarlin.py old mode 100644 new mode 100755 index e09294e4b..01c602dff --- a/Marlin/createTemperatureLookupMarlin.py +++ b/Marlin/createTemperatureLookupMarlin.py @@ -16,9 +16,9 @@ Usage: python createTemperatureLookup.py [options] Options: -h, --help show this help --rp=... pull-up resistor - --t0=ttt:rrr low temperature temperature:resistance point (around 25C) - --t1=ttt:rrr middle temperature temperature:resistance point (around 150C) - --t2=ttt:rrr high temperature temperature:resistance point (around 250C) + --t1=ttt:rrr low temperature temperature:resistance point (around 25C) + --t2=ttt:rrr middle temperature temperature:resistance point (around 150C) + --t3=ttt:rrr high temperature temperature:resistance point (around 250C) --num-temps=... the number of temperature points to calculate (default: 20) """ @@ -54,9 +54,25 @@ class Thermistor: self.c2 = c2 self.c3 = c3 + def res(self,adc): + "Convert ADC reading into a resolution" + res = self.temp(adc)-self.temp(adc+1) + return res + + def v(self,adc): + "Convert ADC reading into a Voltage" + v = adc * self.vadc / (1024 ) # convert the 10 bit ADC value to a voltage + return v + + def r(self,adc): + "Convert ADC reading into a resistance in Ohms" + v = adc * self.vadc / (1024 ) # convert the 10 bit ADC value to a voltage + r = self.rp * v / (self.vcc - v) # resistance of thermistor + return r + def temp(self,adc): "Convert ADC reading into a temperature in Celcius" - v = adc * self.vadc / (1024 * 16) # convert the 10 bit ADC value to a voltage + v = adc * self.vadc / (1024 ) # convert the 10 bit ADC value to a voltage r = self.rp * v / (self.vcc - v) # resistance of thermistor lnr = log(r) Tinv = self.c1 + (self.c2*lnr) + (self.c3*pow(lnr,3)) @@ -67,7 +83,7 @@ class Thermistor: y = (self.c1 - (1/(temp+273.15))) / (2*self.c3) x = sqrt(pow(self.c2 / (3*self.c3),3) + pow(y,2)) r = exp(pow(x-y,1.0/3) - pow(x+y,1.0/3)) # resistance of thermistor - return (r / (self.rp + r)) * (1024*16) + return (r / (self.rp + r)) * (1024) def main(argv): @@ -82,7 +98,8 @@ def main(argv): try: opts, args = getopt.getopt(argv, "h", ["help", "rp=", "t1=", "t2=", "t3=", "num-temps="]) - except getopt.GetoptError: + except getopt.GetoptError as err: + print str(err) usage() sys.exit(2) @@ -107,7 +124,7 @@ def main(argv): elif opt == "--num-temps": num_temps = int(arg) - max_adc = (1024 * 16) - 1 + max_adc = (1024 ) - 1 min_temp = 0 max_temp = 350 increment = int(max_adc/(num_temps-1)); @@ -118,17 +135,18 @@ def main(argv): temps = range(max_temp, min_temp + tmp, tmp); print "// Thermistor lookup table for Marlin" - print "// ./createTemperatureLookup.py --rp=%s --t1=%s:%s --t2=%s:%s --t3=%s:%s --num-temps=%s" % (rp, t1, r1, t2, r2, t3, r3, num_temps) - print "#define NUMTEMPS %s" % (len(temps)) - print "short temptable[NUMTEMPS][2] = {" + print "// ./createTemperatureLookupMarlin.py --rp=%s --t1=%s:%s --t2=%s:%s --t3=%s:%s --num-temps=%s" % (rp, t1, r1, t2, r2, t3, r3, num_temps) + print "// Steinhart-Hart Coefficients: %.15g, %.15g, %.15g " % (t.c1, t.c2, t.c3) + print "//#define NUMTEMPS %s" % (len(temps)) + print "const short temptable[NUMTEMPS][2] PROGMEM = {" counter = 0 for temp in temps: counter = counter +1 if counter == len(temps): - print " {%s, %s}" % (int(t.adc(temp)), temp) + print " {(short)(%.2f*OVERSAMPLENR), %s} // v=%s r=%s res=%s C/count" % ((t.adc(temp)), temp, t.v(t.adc(temp)), t.r(t.adc(temp)),t.res(t.adc(temp))) else: - print " {%s, %s}," % (int(t.adc(temp)), temp) + print " {(short)(%.2f*OVERSAMPLENR), %s}, // v=%s r=%s res=%s C/count" % ((t.adc(temp)), temp, t.v(t.adc(temp)), t.r(t.adc(temp)),t.res(t.adc(temp))) print "};" def usage(): diff --git a/Marlin/digipot_mcp4451.cpp b/Marlin/digipot_mcp4451.cpp new file mode 100644 index 000000000..7c150558b --- /dev/null +++ b/Marlin/digipot_mcp4451.cpp @@ -0,0 +1,59 @@ +#include "Configuration.h" + +#ifdef DIGIPOT_I2C +#include "Stream.h" +#include "utility/twi.h" +#include "Wire.h" + +// Settings for the I2C based DIGIPOT (MCP4451) on Azteeg X3 Pro +#if MOTHERBOARD == 88 +#define DIGIPOT_I2C_FACTOR 117.96 +#define DIGIPOT_I2C_MAX_CURRENT 1.736 +#else +#define DIGIPOT_I2C_FACTOR 106.7 +#define DIGIPOT_I2C_MAX_CURRENT 2.5 +#endif + +static byte current_to_wiper( float current ){ + return byte(ceil(float((DIGIPOT_I2C_FACTOR*current)))); +} + +static void i2c_send(byte addr, byte a, byte b) +{ + Wire.beginTransmission(addr); + Wire.write(a); + Wire.write(b); + Wire.endTransmission(); +} + +// This is for the MCP4451 I2C based digipot +void digipot_i2c_set_current( int channel, float current ) +{ + current = min( (float) max( current, 0.0f ), DIGIPOT_I2C_MAX_CURRENT); + // these addresses are specific to Azteeg X3 Pro, can be set to others, + // In this case first digipot is at address A0=0, A1= 0, second one is at A0=0, A1= 1 + byte addr= 0x2C; // channel 0-3 + if(channel >= 4) { + addr= 0x2E; // channel 4-7 + channel-= 4; + } + + // Initial setup + i2c_send( addr, 0x40, 0xff ); + i2c_send( addr, 0xA0, 0xff ); + + // Set actual wiper value + byte addresses[4] = { 0x00, 0x10, 0x60, 0x70 }; + i2c_send( addr, addresses[channel], current_to_wiper(current) ); +} + +void digipot_i2c_init() +{ + const float digipot_motor_current[] = DIGIPOT_I2C_MOTOR_CURRENTS; + Wire.begin(); + // setup initial currents as defined in Configuration_adv.h + for(int i=0;i<=sizeof(digipot_motor_current)/sizeof(float);i++) { + digipot_i2c_set_current(i, digipot_motor_current[i]); + } +} +#endif diff --git a/Marlin/example_configurations/delta/Configuration.h b/Marlin/example_configurations/delta/Configuration.h index 7fbb4d85a..c724484bd 100644 --- a/Marlin/example_configurations/delta/Configuration.h +++ b/Marlin/example_configurations/delta/Configuration.h @@ -5,6 +5,13 @@ // Advanced settings can be found in Configuration_adv.h // BASIC SETTINGS: select your board type, temperature sensor type, axis scaling, and endstop configuration +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer rplace the configuration files wilth the files in the +// example_configurations/delta directory. +// + // User-specified version info of this build to display in [Pronterface, etc] terminal window during // startup. Implementation of an idea by Prof Braino to inform user that any changes made to this // build by the user have been successfully uploaded into firmware. @@ -18,13 +25,18 @@ // This determines the communication speed of the printer #define BAUDRATE 250000 -//#define BAUDRATE 115200 + +// This enables the serial port associated to the Bluetooth interface +//#define BTENABLED // Enable BT interface on AT90USB devices + //// The following define selects which electronics board you have. Please choose the one that matches your setup // 10 = Gen7 custom (Alfons3 Version) "https://github.com/Alfons3/Generation_7_Electronics" // 11 = Gen7 v1.1, v1.2 = 11 // 12 = Gen7 v1.3 // 13 = Gen7 v1.4 +// 2 = Cheaptronic v1.0 +// 20 = Sethi 3D_1 // 3 = MEGA/RAMPS up to 1.2 = 3 // 33 = RAMPS 1.3 / 1.4 (Power outputs: Extruder, Fan, Bed) // 34 = RAMPS 1.3 / 1.4 (Power outputs: Extruder0, Extruder1, Bed) @@ -38,6 +50,8 @@ // 64 = STB V1.1 // 65 = Azteeg X1 // 66 = Melzi with ATmega1284 (MaKr3d version) +// 67 = Azteeg X3 +// 68 = Azteeg X3 Pro // 7 = Ultimaker // 71 = Ultimaker (Older electronics. Pre 1.5.4. This is rare) // 77 = 3Drag Controller @@ -45,6 +59,7 @@ // 80 = Rumba // 81 = Printrboard (AT90USB1286) // 82 = Brainwave (AT90USB646) +// 83 = SAV Mk-I (AT90USB1286) // 9 = Gen3+ // 70 = Megatronics // 701= Megatronics v2.0 @@ -61,6 +76,10 @@ // Define this to set a custom name for your generic Mendel, // #define CUSTOM_MENDEL_NAME "This Mendel" +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4) +// #define MACHINE_UUID "00000000-0000-0000-0000-000000000000" + // This defines the number of extruders #define EXTRUDERS 1 @@ -70,6 +89,8 @@ #define POWER_SUPPLY 1 +// Define this to have the electronics keep the powersupply off on startup. If you don't know what this is leave it. +// #define PS_DEFAULT_OFF //=========================================================================== //============================== Delta Settings ============================= @@ -82,6 +103,8 @@ // and processor overload (too many expensive sqrt calls). #define DELTA_SEGMENTS_PER_SECOND 200 +// NOTE NB all values for DELTA_* values MOUST be floating point, so always have a decimal point in them + // Center-to-center distance of the holes in the diagonal push rods. #define DELTA_DIAGONAL_ROD 250.0 // mm @@ -97,16 +120,6 @@ // Effective horizontal distance bridged by diagonal push rods. #define DELTA_RADIUS (DELTA_SMOOTH_ROD_OFFSET-DELTA_EFFECTOR_OFFSET-DELTA_CARRIAGE_OFFSET) -// Effective X/Y positions of the three vertical towers. -#define SIN_60 0.8660254037844386 -#define COS_60 0.5 -#define DELTA_TOWER1_X -SIN_60*DELTA_RADIUS // front left tower -#define DELTA_TOWER1_Y -COS_60*DELTA_RADIUS -#define DELTA_TOWER2_X SIN_60*DELTA_RADIUS // front right tower -#define DELTA_TOWER2_Y -COS_60*DELTA_RADIUS -#define DELTA_TOWER3_X 0.0 // back middle tower -#define DELTA_TOWER3_Y DELTA_RADIUS - //=========================================================================== //=============================Thermal Settings ============================ //=========================================================================== @@ -121,9 +134,10 @@ // 2 is 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) // 3 is mendel-parts thermistor (4.7k pullup) // 4 is 10k thermistor !! do not use it for a hotend. It gives bad resolution at high temp. !! -// 5 is 100K thermistor - ATC Semitec 104GT-2 (Used in ParCan) (4.7k pullup) +// 5 is 100K thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (4.7k pullup) // 6 is 100k EPCOS - Not as accurate as table 1 (created using a fluke thermocouple) (4.7k pullup) // 7 is 100k Honeywell thermistor 135-104LAG-J01 (4.7k pullup) +// 71 is 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) // 8 is 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) // 9 is 100k GE Sensing AL03006-58.2K-97-G1 (4.7k pullup) // 10 is 100k RS thermistor 198-961 (4.7k pullup) @@ -133,7 +147,7 @@ // (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) -// 55 is 100k thermistor - ATC Semitec 104GT-2 (Used in ParCan) (1k pullup) +// 55 is 100k thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (1k pullup) #define TEMP_SENSOR_0 -1 #define TEMP_SENSOR_1 -1 @@ -141,7 +155,7 @@ #define TEMP_SENSOR_BED 0 // This makes temp sensor 1 a redundant sensor for sensor 0. If the temperatures difference between these sensors is to high the print will be aborted. -//#define TEMP_SENSOR_1_AS_REDUNDANT +//#define TEMP_SENSOR_1_AS_REDUNDANT #define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 // Actual temperature must be close to target for this long before M109 returns success @@ -278,13 +292,15 @@ #endif // The pullups are needed if you directly connect a mechanical endswitch between the signal and ground pins. -const bool X_ENDSTOPS_INVERTING = false; // set to true to invert the logic of the endstops. -const bool Y_ENDSTOPS_INVERTING = false; // set to true to invert the logic of the endstops. -const bool Z_ENDSTOPS_INVERTING = false; // set to true to invert the logic of the endstops. - -// deltas never have min endstops +const bool X_MIN_ENDSTOP_INVERTING = true; // set to true to invert the logic of the endstop. +const bool Y_MIN_ENDSTOP_INVERTING = true; // set to true to invert the logic of the endstop. +const bool Z_MIN_ENDSTOP_INVERTING = true; // set to true to invert the logic of the endstop. +const bool X_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of the endstop. +const bool Y_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of the endstop. +const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of the endstop. +//#define DISABLE_MAX_ENDSTOPS +// Deltas never have min endstops #define DISABLE_MIN_ENDSTOPS - // Disable max endstops for compatibility with endstop checking routine #if defined(COREXY) && !defined(DISABLE_MAX_ENDSTOPS) #define DISABLE_MAX_ENDSTOPS @@ -331,6 +347,58 @@ const bool Z_ENDSTOPS_INVERTING = false; // set to true to invert the logic of t #define X_MAX_LENGTH (X_MAX_POS - X_MIN_POS) #define Y_MAX_LENGTH (Y_MAX_POS - Y_MIN_POS) #define Z_MAX_LENGTH (Z_MAX_POS - Z_MIN_POS) +//============================= Bed Auto Leveling =========================== + +//#define ENABLE_AUTO_BED_LEVELING // Delete the comment to enable (remove // at the start of the line) + +#ifdef ENABLE_AUTO_BED_LEVELING + + // these are the positions on the bed to do the probing + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define BACK_PROBE_BED_POSITION 180 + #define FRONT_PROBE_BED_POSITION 20 + + // these are the offsets to the prob relative to the extruder tip (Hotend - Probe) + #define X_PROBE_OFFSET_FROM_EXTRUDER -25 + #define Y_PROBE_OFFSET_FROM_EXTRUDER -29 + #define Z_PROBE_OFFSET_FROM_EXTRUDER -12.35 + + #define Z_RAISE_BEFORE_HOMING 4 // (in mm) Raise Z before homing (G28) for Probe Clearance. + // Be sure you have this distance over your Z_MAX_POS in case + + #define XY_TRAVEL_SPEED 8000 // X and Y axis travel speed between probes, in mm/min + + #define Z_RAISE_BEFORE_PROBING 15 //How much the extruder will be raised before traveling to the first probing point. + #define Z_RAISE_BETWEEN_PROBINGS 5 //How much the extruder will be raised when traveling from between next probing points + + + //If defined, the Probe servo will be turned on only during movement and then turned off to avoid jerk + //The value is the delay to turn the servo off after powered on - depends on the servo speed; 300ms is good value, but you can try lower it. + // You MUST HAVE the SERVO_ENDSTOPS defined to use here a value higher than zero otherwise your code will not compile. + +// #define PROBE_SERVO_DEACTIVATION_DELAY 300 + + +//If you have enabled the Bed Auto Levelling and are using the same Z Probe for Z Homing, +//it is highly recommended you let this Z_SAFE_HOMING enabled!!! + + #define Z_SAFE_HOMING // This feature is meant to avoid Z homing with probe outside the bed area. + // When defined, it will: + // - Allow Z homing only after X and Y homing AND stepper drivers still enabled + // - If stepper drivers timeout, it will need X and Y homing again before Z homing + // - Position the probe in a defined XY point before Z Homing when homing all axis (G28) + // - Block Z homing only when the probe is outside bed area. + + #ifdef Z_SAFE_HOMING + + #define Z_SAFE_HOMING_X_POINT (X_MAX_LENGTH/2) // X point for Z homing when homing all axis (G28) + #define Z_SAFE_HOMING_Y_POINT (Y_MAX_LENGTH/2) // Y point for Z homing when homing all axis (G28) + + #endif + +#endif + // The position of the homing switches //#define MANUAL_HOME_POSITIONS // If defined, MANUAL_*_HOME_POS below will be used @@ -386,7 +454,7 @@ const bool Z_ENDSTOPS_INVERTING = false; // set to true to invert the logic of t //#define EEPROM_CHITCHAT // Preheat Constants -#define PLA_PREHEAT_HOTEND_TEMP 180 +#define PLA_PREHEAT_HOTEND_TEMP 180 #define PLA_PREHEAT_HPB_TEMP 70 #define PLA_PREHEAT_FAN_SPEED 255 // Insert Value between 0 and 255 @@ -399,7 +467,8 @@ const bool Z_ENDSTOPS_INVERTING = false; // set to true to invert the logic of t //#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) - +//#define ENCODER_PULSES_PER_STEP 1 // Increase if you have a high resolution encoder +//#define ENCODER_STEPS_PER_MENU_ITEM 5 // Set according to ENCODER_PULSES_PER_STEP or your liking //#define ULTIMAKERCONTROLLER //as available from the ultimaker online store. //#define ULTIPANEL //the ultipanel as on thingiverse @@ -471,7 +540,7 @@ const bool Z_ENDSTOPS_INVERTING = false; // set to true to invert the logic of t #define LCD_I2C_TYPE_PCF8575 #define LCD_I2C_ADDRESS 0x27 // I2C Address of the port expander #define NEWPANEL - #define ULTIPANEL + #define ULTIPANEL #endif // PANELOLU2 LCD with status LEDs, separate encoder and click inputs @@ -480,13 +549,13 @@ const bool Z_ENDSTOPS_INVERTING = false; // set to true to invert the logic of t // 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). + // 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 + #define ULTIPANEL #endif // Panucatt VIKI LCD with status LEDs, integrated click & L/R/U/P buttons, separate encoder inputs @@ -496,13 +565,24 @@ const bool Z_ENDSTOPS_INVERTING = false; // set to true to invert the logic of t // 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_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 + #define ULTIPANEL +#endif + +// Shift register panels +// --------------------- +// 2 wire Non-latching LCD SR from: +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/schematics#!shiftregister-connection +//#define SR_LCD +#ifdef SR_LCD + #define SR_LCD_2W_NL // Non latching 2 wire shiftregister + //#define NEWPANEL #endif + #ifdef ULTIPANEL // #define NEWPANEL //enable this if you have a click-encoder panel #define SDSUPPORT @@ -536,6 +616,11 @@ const bool Z_ENDSTOPS_INVERTING = false; // set to true to invert the logic of t // Increase the FAN pwm frequency. Removes the PWM noise but increases heating in the FET/Arduino //#define FAST_PWM_FAN +// Temperature status leds that display the hotend and bet temperature. +// If alle hotends and bed temperature and temperature setpoint are < 54C then the BLUE led is on. +// Otherwise the RED led is on. There is 1C hysteresis. +//#define TEMP_STAT_LEDS + // Use software PWM to drive the fan, as for the heaters. This uses a very low frequency // which is not ass annoying as with the hardware PWM. On the other hand, if this frequency // is too low, you should also increment SOFT_PWM_SCALE. @@ -557,6 +642,9 @@ const bool Z_ENDSTOPS_INVERTING = false; // set to true to invert the logic of t // Support for the BariCUDA Paste Extruder. //#define BARICUDA +//define BlinkM/CyzRgb Support +//#define BLINKM + /*********************************************************************\ * R/C SERVO support * Sponsored by TrinityLabs, Reworked by codexmas @@ -572,10 +660,10 @@ const bool Z_ENDSTOPS_INVERTING = false; // set to true to invert the logic of t //#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command // Servo Endstops -// +// // This allows for servo actuated endstops, primary usage is for the Z Axis to eliminate calibration or bed height changes. // Use M206 command to correct for switch height offset to actual nozzle height. Store that setting with M500. -// +// //#define SERVO_ENDSTOPS {-1, -1, 0} // Servo index for X, Y, Z. Disable with -1 //#define SERVO_ENDSTOP_ANGLES {0,0, 0,0, 70,0} // X,Y,Z Axis Extend and Retract angles diff --git a/Marlin/example_configurations/delta/Configuration_adv.h b/Marlin/example_configurations/delta/Configuration_adv.h index f279b0e21..4d6e78b4d 100644 --- a/Marlin/example_configurations/delta/Configuration_adv.h +++ b/Marlin/example_configurations/delta/Configuration_adv.h @@ -40,6 +40,10 @@ #define AUTOTEMP_OLDWEIGHT 0.98 #endif +//Show Temperature ADC value +//The M105 command return, besides traditional information, the ADC value read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + // extruder run-out prevention. //if the machine is idle, and the temperature over MINTEMP, every couple of SECONDS some filament is extruded //#define EXTRUDER_RUNOUT_PREVENT @@ -146,6 +150,21 @@ #define EXTRUDERS 1 #endif +// Same again but for Y Axis. +//#define Y_DUAL_STEPPER_DRIVERS + +// Define if the two Y drives need to rotate in opposite directions +#define INVERT_Y2_VS_Y_DIR true + +#ifdef Y_DUAL_STEPPER_DRIVERS + #undef EXTRUDERS + #define EXTRUDERS 1 +#endif + +#if defined (Z_DUAL_STEPPER_DRIVERS) && defined (Y_DUAL_STEPPER_DRIVERS) + #error "You cannot have dual drivers for both Y and Z" +#endif + // Enable this for dual x-carriage printers. // A dual x-carriage design has the advantage that the inactive extruder can be parked which // prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage @@ -155,8 +174,8 @@ // Configuration for second X-carriage // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; // the second x-carriage always homes to the maximum endstop. -#define X2_MIN_POS 88 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage -#define X2_MAX_POS 350.45 // set maximum to the distance between toolheads when both heads are homed +#define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage +#define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position // However: In this mode the EXTRUDER_OFFSET_X value for the second extruder provides a software @@ -169,14 +188,35 @@ #define X2_STEP_PIN 25 #define X2_DIR_PIN 23 -#endif // DUAL_X_CARRIAGE +// There are a few selectable movement modes for dual x-carriages using M605 S +// Mode 0: Full control. The slicer has full control over both x-carriages and can achieve optimal travel results +// as long as it supports dual x-carriages. (M605 S0) +// Mode 1: Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so +// that additional slicer support is not required. (M605 S1) +// Mode 2: Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all +// actions of the first x-carriage. This allows the printer to print 2 arbitrary items at +// once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + +// This is the default power-up mode which can be later using M605. +#define DEFAULT_DUAL_X_CARRIAGE_MODE 0 + +// As the x-carriages are independent we can now account for any relative Z offset +#define EXTRUDER1_Z_OFFSET 0.0 // z offset relative to extruder 0 + +// Default settings in "Auto-park Mode" +#define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder +#define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + +// Default x offset in duplication mode (typically set to half print bed width) +#define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif //DUAL_X_CARRIAGE //homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: #define X_HOME_RETRACT_MM 5 -#define Y_HOME_RETRACT_MM 5 +#define Y_HOME_RETRACT_MM 5 #define Z_HOME_RETRACT_MM 5 // deltas need the same for all three axis - //#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. #define AXIS_RELATIVE_MODES {false, false, false, false} @@ -195,6 +235,11 @@ #define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate #define DEFAULT_MINTRAVELFEEDRATE 0.0 +// Feedrates for manual moves along X, Y, Z, E from panel +#ifdef ULTIPANEL +#define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // set the speeds for manual moves (mm/min) +#endif + // minimum time in microseconds that a movement needs to take if the buffer is emptied. #define DEFAULT_MINSEGMENTTIME 20000 @@ -225,6 +270,12 @@ // Motor Current setting (Only functional when motor driver current ref pins are connected to a digital trimpot on supported boards) #define DIGIPOT_MOTOR_CURRENT {135,135,135,135,135} // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A) +// uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +// Number of channels available for I2C digipot, For Azteeg X3 Pro we have 8 +#define DIGIPOT_I2C_NUM_CHANNELS 8 +// actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#define DIGIPOT_I2C_MOTOR_CURRENTS {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0} //=========================================================================== //=============================Additional Features=========================== @@ -233,6 +284,11 @@ #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. +#define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the filesystem block order. +// if a file is deleted, it frees a block. hence, the order is not purely cronological. To still have auto0.g accessible, there is again the option to do that. +// using: +//#define MENU_ADDAUTOSTART + // The hardware watchdog should reset the Microcontroller disabling all outputs, in case the firmware gets stuck and doesn't do temperature regulation. //#define USE_WATCHDOG @@ -246,6 +302,26 @@ // 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 +// Babystepping enables the user to control the axis in tiny amounts, independently from the normal printing process +// it can e.g. be used to change z-positions in the print startup phase in realtime +// does not respect endstops! +//#define BABYSTEPPING +#ifdef BABYSTEPPING + #define BABYSTEP_XY //not only z, but also XY in the menu. more clutter, more functions + #define BABYSTEP_INVERT_Z false //true for inverse movements in Z + #define BABYSTEP_Z_MULTIPLICATOR 2 //faster z movements + + #ifdef COREXY + #error BABYSTEPPING not implemented for COREXY yet. + #endif + + #ifdef DELTA + #ifdef BABYSTEP_XY + #error BABYSTEPPING only implemented for Z axis on deltabots. + #endif + #endif +#endif + // extruder advance constant (s2/mm3) // // advance (steps) = STEPS_PER_CUBIC_MM_E * EXTUDER_ADVANCE_K * cubic mm per second ^ 2 @@ -297,6 +373,9 @@ const unsigned int dropsegments=5; //everything with less than this number of st #define PS_ON_ASLEEP LOW #endif +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + //=========================================================================== //=============================Buffers ============================ //=========================================================================== @@ -327,7 +406,7 @@ const unsigned int dropsegments=5; //everything with less than this number of st //adds support for experimental filament exchange support M600; requires display #ifdef ULTIPANEL - //#define FILAMENTCHANGEENABLE + #define FILAMENTCHANGEENABLE #ifdef FILAMENTCHANGEENABLE #define FILAMENTCHANGE_XPOS 3 #define FILAMENTCHANGE_YPOS 3 @@ -336,6 +415,12 @@ const unsigned int dropsegments=5; //everything with less than this number of st #define FILAMENTCHANGE_FINALRETRACT -100 #endif #endif + +#ifdef FILAMENTCHANGEENABLE + #ifdef EXTRUDER_RUNOUT_PREVENT + #error EXTRUDER_RUNOUT_PREVENT currently incompatible with FILAMENTCHANGE + #endif +#endif //=========================================================================== //============================= Define Defines ============================ @@ -344,6 +429,10 @@ const unsigned int dropsegments=5; //everything with less than this number of st #error "You cannot use TEMP_SENSOR_1_AS_REDUNDANT if EXTRUDERS > 1" #endif +#if EXTRUDERS > 1 && defined HEATERS_PARALLEL + #error "You cannot use HEATERS_PARALLEL if EXTRUDERS > 1" +#endif + #if TEMP_SENSOR_0 > 0 #define THERMISTORHEATER_0 TEMP_SENSOR_0 #define HEATER_0_USES_THERMISTOR diff --git a/Marlin/example_configurations/makibox/Configuration.h b/Marlin/example_configurations/makibox/Configuration.h new file mode 100644 index 000000000..6ebd08f43 --- /dev/null +++ b/Marlin/example_configurations/makibox/Configuration.h @@ -0,0 +1,725 @@ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H + +// This configuration file contains the basic settings. +// Advanced settings can be found in Configuration_adv.h +// BASIC SETTINGS: select your board type, temperature sensor type, axis scaling, and endstop configuration + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer replace the configuration files with the files in the +// example_configurations/delta directory. +// + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_VERSION_CONFIG_H __DATE__ " " __TIME__ // build date and time +#define STRING_CONFIG_H_AUTHOR "(none, default config)" // Who made the changes. + +// SERIAL_PORT selects which serial port should be used for communication with the host. +// This allows the connection of wireless adapters (for instance) to non-default port pins. +// Serial port 0 is still used by the Arduino bootloader regardless of this setting. +#define SERIAL_PORT 0 + +// This determines the communication speed of the printer +// This determines the communication speed of the printer +#define BAUDRATE 250000 + +// This enables the serial port associated to the Bluetooth interface +//#define BTENABLED // Enable BT interface on AT90USB devices + + +//// The following define selects which electronics board you have. Please choose the one that matches your setup +// 10 = Gen7 custom (Alfons3 Version) "https://github.com/Alfons3/Generation_7_Electronics" +// 11 = Gen7 v1.1, v1.2 = 11 +// 12 = Gen7 v1.3 +// 13 = Gen7 v1.4 +// 2 = Cheaptronic v1.0 +// 20 = Sethi 3D_1 +// 3 = MEGA/RAMPS up to 1.2 = 3 +// 33 = RAMPS 1.3 / 1.4 (Power outputs: Extruder, Fan, Bed) +// 34 = RAMPS 1.3 / 1.4 (Power outputs: Extruder0, Extruder1, Bed) +// 35 = RAMPS 1.3 / 1.4 (Power outputs: Extruder, Fan, Fan) +// 4 = Duemilanove w/ ATMega328P pin assignment +// 5 = Gen6 +// 51 = Gen6 deluxe +// 6 = Sanguinololu < 1.2 +// 62 = Sanguinololu 1.2 and above +// 63 = Melzi +// 64 = STB V1.1 +// 65 = Azteeg X1 +// 66 = Melzi with ATmega1284 (MaKr3d version) +// 67 = Azteeg X3 +// 68 = Azteeg X3 Pro +// 7 = Ultimaker +// 71 = Ultimaker (Older electronics. Pre 1.5.4. This is rare) +// 72 = Ultimainboard 2.x (Uses TEMP_SENSOR 20) +// 77 = 3Drag Controller +// 8 = Teensylu +// 80 = Rumba +// 81 = Printrboard (AT90USB1286) +// 82 = Brainwave (AT90USB646) +// 83 = SAV Mk-I (AT90USB1286) +// 9 = Gen3+ +// 70 = Megatronics +// 701= Megatronics v2.0 +// 702= Minitronics v1.0 +// 90 = Alpha OMCA board +// 91 = Final OMCA board +// 301= Rambo +// 21 = Elefu Ra Board (v3) +// 88 = 5DPrint D8 Driver Board + +#ifndef MOTHERBOARD +#define MOTHERBOARD 88 +#endif + +// Define this to set a custom name for your generic Mendel, +// #define CUSTOM_MENDEL_NAME "This Mendel" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4) +// #define MACHINE_UUID "00000000-0000-0000-0000-000000000000" + +// 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) + +#define POWER_SUPPLY 1 + +// Define this to have the electronics keep the power supply off on startup. If you don't know what this is leave it. +// #define PS_DEFAULT_OFF + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== +// +//--NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table +// +//// Temperature sensor settings: +// -2 is thermocouple with MAX6675 (only for sensor 0) +// -1 is thermocouple with AD595 +// 0 is not used +// 1 is 100k thermistor - best choice for EPCOS 100k (4.7k pullup) +// 2 is 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) +// 3 is Mendel-parts thermistor (4.7k pullup) +// 4 is 10k thermistor !! do not use it for a hotend. It gives bad resolution at high temp. !! +// 5 is 100K thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (4.7k pullup) +// 6 is 100k EPCOS - Not as accurate as table 1 (created using a fluke thermocouple) (4.7k pullup) +// 7 is 100k Honeywell thermistor 135-104LAG-J01 (4.7k pullup) +// 71 is 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) +// 8 is 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) +// 9 is 100k GE Sensing AL03006-58.2K-97-G1 (4.7k pullup) +// 10 is 100k RS thermistor 198-961 (4.7k pullup) +// 11 is 100k beta 3950 1% thermistor (4.7k pullup) +// 12 is 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) (calibrated for Makibox hot bed) +// 20 is the PT100 circuit found in the Ultimainboard V2.x +// 60 is 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 +// +// 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) +// 55 is 100k thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (1k pullup) +// +// 1047 is Pt1000 with 4k7 pullup +// 1010 is Pt1000 with 1k pullup (non standard) +// 147 is Pt100 with 4k7 pullup +// 110 is Pt100 with 1k pullup (non standard) + +#define TEMP_SENSOR_0 1 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_BED 12 + +// This makes temp sensor 1 a redundant sensor for sensor 0. If the temperatures difference between these sensors is to high the print will be aborted. +//#define TEMP_SENSOR_1_AS_REDUNDANT +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Actual temperature must be close to target for this long before M109 returns success +#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 residency 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. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define BED_MAXTEMP 150 + +// If your bed has low resistance e.g. .6 ohm and throws the fuse you can duty cycle it to reduce the +// average current. The value should be an integer and the heat bed will be turned on for 1 interval of +// HEATER_BED_DUTY_CYCLE_DIVIDER intervals. +//#define HEATER_BED_DUTY_CYCLE_DIVIDER 4 + +// If you want the M105 heater power reported in watts, define the BED_WATTS, and (shared for all extruders) EXTRUDER_WATTS +//#define EXTRUDER_WATTS (12.0*12.0/6.7) // P=I^2/R +//#define BED_WATTS (12.0*12.0/1.1) // P=I^2/R + +// PID settings: +// Comment the following line to disable PID and enable bang-bang. +#define PIDTEMP +#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX 255 // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#ifdef PIDTEMP + //#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. + #define PID_INTEGRAL_DRIVE_MAX 255 //limit for the integral term + #define K1 0.95 //smoothing factor within the PID + #define PID_dT ((OVERSAMPLENR * 8.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the temperature routine + +// If you are using a pre-configured 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 + +// MakerGear +// #define DEFAULT_Kp 7.0 +// #define DEFAULT_Ki 0.1 +// #define DEFAULT_Kd 12 + +// Mendel Parts V9 on 12V +// #define DEFAULT_Kp 63.0 +// #define DEFAULT_Ki 2.25 +// #define DEFAULT_Kd 440 +#endif // PIDTEMP + +// 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 frequency 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 probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +//#define PIDTEMPBED +// +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 175 // limits duty cycle to bed; 255=full current +// This limit is set to 175 by default in the Makibox configuration and it can adjusted +// to increase the heat up rate. However, if changed, user must be aware of the safety concerns +// of drawing too much current from the power supply. + +#ifdef PIDTEMPBED +//120v 250W silicone heater into 4mm borosilicate (MendelMax 1.5+) +//from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10) + #define DEFAULT_bedKp 10.00 + #define DEFAULT_bedKi .023 + #define DEFAULT_bedKd 305.4 + +//120v 250W silicone heater into 4mm borosilicate (MendelMax 1.5+) +//from pidautotune +// #define DEFAULT_bedKp 97.1 +// #define DEFAULT_bedKi 1.41 +// #define DEFAULT_bedKd 1675.16 + +// FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles. +#endif // PIDTEMPBED + + + +//this prevents dangerous Extruder moves, i.e. if the temperature is under the limit +//can be software-disabled for whatever purposes by +#define PREVENT_DANGEROUS_EXTRUDE +//if PREVENT_DANGEROUS_EXTRUDE is on, you can still disable (uncomment) very long bits of extrusion separately. +#define PREVENT_LENGTHY_EXTRUDE + +#define EXTRUDE_MINTEMP 170 +#define EXTRUDE_MAXLENGTH (X_MAX_LENGTH+Y_MAX_LENGTH) //prevent extrusion of very large distances. + +//=========================================================================== +//=============================Mechanical Settings=========================== +//=========================================================================== + +// Uncomment the following line to enable CoreXY kinematics +// #define COREXY + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#ifndef ENDSTOPPULLUPS + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + // #define ENDSTOPPULLUP_XMAX + // #define ENDSTOPPULLUP_YMAX + // #define ENDSTOPPULLUP_ZMAX + // #define ENDSTOPPULLUP_XMIN + // #define ENDSTOPPULLUP_YMIN + // #define ENDSTOPPULLUP_ZMIN +#endif + +#ifdef ENDSTOPPULLUPS + #define ENDSTOPPULLUP_XMAX + #define ENDSTOPPULLUP_YMAX + #define ENDSTOPPULLUP_ZMAX + #define ENDSTOPPULLUP_XMIN + #define ENDSTOPPULLUP_YMIN + #define ENDSTOPPULLUP_ZMIN +#endif + +// The pullups are needed if you directly connect a mechanical endswitch between the signal and ground pins. +const bool X_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic of the endstop. +const bool Y_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic of the endstop. +const bool Z_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic of the endstop. +const bool X_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of the endstop. +const bool Y_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of the endstop. +const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of the endstop. +//#define DISABLE_MAX_ENDSTOPS +//#define DISABLE_MIN_ENDSTOPS + +// Disable max endstops for compatibility with endstop checking routine +#if defined(COREXY) && !defined(DISABLE_MAX_ENDSTOPS) + #define DISABLE_MAX_ENDSTOPS +#endif + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis when it's not being used. +#define DISABLE_X false +#define DISABLE_Y false +#define DISABLE_Z false +#define DISABLE_E false // For all extruders + +#define INVERT_X_DIR false // for Mendel set to false, for Orca set to true +#define INVERT_Y_DIR false // for Mendel set to true, for Orca set to false +#define INVERT_Z_DIR false // for Mendel set to false, for Orca set to true +#define INVERT_E0_DIR true // for direct drive extruder v9 set to true, for geared extruder set to false +#define INVERT_E1_DIR false // for direct drive extruder v9 set to true, for geared extruder set to false +#define INVERT_E2_DIR false // for direct drive extruder v9 set to true, for geared extruder set to false + +// ENDSTOP SETTINGS: +// Sets direction of endstops when homing; 1=MAX, -1=MIN +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR -1 + +#define min_software_endstops true // If true, axis won't move to coordinates less than HOME_POS. +#define max_software_endstops true // If true, axis won't move to coordinates greater than the defined lengths below. + +// Travel limits after homing +#define X_MAX_POS 110 +#define X_MIN_POS 0 +#define Y_MAX_POS 150 +#define Y_MIN_POS 0 +#define Z_MAX_POS 86 +#define Z_MIN_POS 0 + +#define X_MAX_LENGTH (X_MAX_POS - X_MIN_POS) +#define Y_MAX_LENGTH (Y_MAX_POS - Y_MIN_POS) +#define Z_MAX_LENGTH (Z_MAX_POS - Z_MIN_POS) +//============================= Bed Auto Leveling =========================== + +//#define ENABLE_AUTO_BED_LEVELING // Delete the comment to enable (remove // at the start of the line) + +#ifdef ENABLE_AUTO_BED_LEVELING + +// There are 2 different ways to pick the X and Y locations to probe: + +// - "grid" mode +// Probe every point in a rectangular grid +// You must specify the rectangle, and the density of sample points +// This mode is preferred because there are more measurements. +// It used to be called ACCURATE_BED_LEVELING but "grid" is more descriptive + +// - "3-point" mode +// Probe 3 arbitrary points on the bed (that aren't colinear) +// You must specify the X & Y coordinates of all 3 points + + #define AUTO_BED_LEVELING_GRID + // with AUTO_BED_LEVELING_GRID, the bed is sampled in a + // AUTO_BED_LEVELING_GRID_POINTSxAUTO_BED_LEVELING_GRID_POINTS grid + // and least squares solution is calculated + // Note: this feature occupies 10'206 byte + #ifdef AUTO_BED_LEVELING_GRID + + // set the rectangle in which to probe + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define BACK_PROBE_BED_POSITION 180 + #define FRONT_PROBE_BED_POSITION 20 + + // set the number of grid points per dimension + // I wouldn't see a reason to go above 3 (=9 probing points on the bed) + #define AUTO_BED_LEVELING_GRID_POINTS 2 + + + #else // not AUTO_BED_LEVELING_GRID + // with no grid, just probe 3 arbitrary points. A simple cross-product + // is used to esimate the plane of the print bed + + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + + #endif // AUTO_BED_LEVELING_GRID + + + // these are the offsets to the probe relative to the extruder tip (Hotend - Probe) + #define X_PROBE_OFFSET_FROM_EXTRUDER -25 + #define Y_PROBE_OFFSET_FROM_EXTRUDER -29 + #define Z_PROBE_OFFSET_FROM_EXTRUDER -12.35 + + #define Z_RAISE_BEFORE_HOMING 4 // (in mm) Raise Z before homing (G28) for Probe Clearance. + // Be sure you have this distance over your Z_MAX_POS in case + + #define XY_TRAVEL_SPEED 8000 // X and Y axis travel speed between probes, in mm/min + + #define Z_RAISE_BEFORE_PROBING 15 //How much the extruder will be raised before traveling to the first probing point. + #define Z_RAISE_BETWEEN_PROBINGS 5 //How much the extruder will be raised when traveling from between next probing points + + + //If defined, the Probe servo will be turned on only during movement and then turned off to avoid jerk + //The value is the delay to turn the servo off after powered on - depends on the servo speed; 300ms is good value, but you can try lower it. + // You MUST HAVE the SERVO_ENDSTOPS defined to use here a value higher than zero otherwise your code will not compile. + +// #define PROBE_SERVO_DEACTIVATION_DELAY 300 + + +//If you have enabled the Bed Auto Leveling and are using the same Z Probe for Z Homing, +//it is highly recommended you let this Z_SAFE_HOMING enabled!!! + + #define Z_SAFE_HOMING // This feature is meant to avoid Z homing with probe outside the bed area. + // When defined, it will: + // - Allow Z homing only after X and Y homing AND stepper drivers still enabled + // - If stepper drivers timeout, it will need X and Y homing again before Z homing + // - Position the probe in a defined XY point before Z Homing when homing all axis (G28) + // - Block Z homing only when the probe is outside bed area. + + #ifdef Z_SAFE_HOMING + + #define Z_SAFE_HOMING_X_POINT (X_MAX_LENGTH/2) // X point for Z homing when homing all axis (G28) + #define Z_SAFE_HOMING_Y_POINT (Y_MAX_LENGTH/2) // Y point for Z homing when homing all axis (G28) + + #endif + +#endif // ENABLE_AUTO_BED_LEVELING + + +// The position of the homing switches +//#define MANUAL_HOME_POSITIONS // If defined, MANUAL_*_HOME_POS below will be used +//#define BED_CENTER_AT_0_0 // If defined, the center of the bed is at (X=0, Y=0) + +//Manual homing switch locations: +// For deltabots this means top and center of the Cartesian print volume. +#define MANUAL_X_HOME_POS 0 +#define MANUAL_Y_HOME_POS 0 +#define MANUAL_Z_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 402 // For delta: Distance between nozzle and print surface after homing. + +//// MOVEMENT SETTINGS +#define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E +#define HOMING_FEEDRATE {1500, 1500, 120, 0} // set the homing speeds (mm/min) ***** MakiBox A6 ***** + +// default settings + +#define DEFAULT_AXIS_STEPS_PER_UNIT {400, 400, 400, 163} // default steps per unit for ***** MakiBox A6 ***** +#define DEFAULT_MAX_FEEDRATE {60, 60, 20, 45} // (mm/sec) +#define DEFAULT_MAX_ACCELERATION {2000,2000,30,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_RETRACT_ACCELERATION 3000 // X, Y, Z and E max acceleration in mm/s^2 for retracts + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +// #define EXTRUDER_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +// #define EXTRUDER_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// The speed change that does not require acceleration (i.e. the software might assume it can be done instantaneously) +#define DEFAULT_XYJERK 20.0 // (mm/sec) +#define DEFAULT_ZJERK 0.4 // (mm/sec) +#define DEFAULT_EJERK 5.0 // (mm/sec) + +//=========================================================================== +//=============================Additional Features=========================== +//=========================================================================== + +// Custom M code points +#define CUSTOM_M_CODES +#ifdef CUSTOM_M_CODES + #define CUSTOM_M_CODE_SET_Z_PROBE_OFFSET 851 + #define Z_PROBE_OFFSET_RANGE_MIN -15 + #define Z_PROBE_OFFSET_RANGE_MAX -5 +#endif + + +// EEPROM +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// 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 +//to disable EEPROM Serial responses and decrease program space by ~1700 byte: comment this out: +// 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 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) +//#define ENCODER_PULSES_PER_STEP 1 // Increase if you have a high resolution encoder +//#define ENCODER_STEPS_PER_MENU_ITEM 5 // Set according to ENCODER_PULSES_PER_STEP or your liking +//#define ULTIMAKERCONTROLLER //as available from the Ultimaker online store. +//#define ULTIPANEL //the UltiPanel as on Thingiverse +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 // this is the tone frequency the buzzer plays when on UI feedback. ie Screen Click +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 // the duration the buzzer plays the UI feedback sound. ie Screen Click + +// The MaKr3d Makr-Panel with graphic controller and SD support +// http://reprap.org/wiki/MaKr3d_MaKrPanel +//#define MAKRPANEL + +// The RepRapDiscount Smart Controller (white PCB) +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +//#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// The GADGETS3D G3D LCD/SD Controller (blue PCB) +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +//#define G3D_PANEL + +// The RepRapDiscount FULL GRAPHIC Smart Controller (quadratic white PCB) +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +// ==> REMEMBER TO INSTALL U8glib to your ARDUINO library folder: http://code.google.com/p/u8glib/wiki/u8glib +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// The RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 10.0 // how much should be moved when a key is pressed, eg 10.0 means 10mm per click + +// The Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// REMEMBER TO INSTALL LiquidCrystal_I2C.h in your ARUDINO library folder: https://github.com/kiyoshigawa/LiquidCrystal_I2C +//#define RA_CONTROL_PANEL + +//automatic expansion +#if defined (MAKRPANEL) + #define DOGLCD + #define SDSUPPORT + #define ULTIPANEL + #define NEWPANEL + #define DEFAULT_LCD_CONTRAST 17 +#endif + +#if defined (REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) + #define DOGLCD + #define U8GLIB_ST7920 + #define REPRAP_DISCOUNT_SMART_CONTROLLER +#endif + +#if defined(ULTIMAKERCONTROLLER) || defined(REPRAP_DISCOUNT_SMART_CONTROLLER) || defined(G3D_PANEL) + #define ULTIPANEL + #define NEWPANEL +#endif + +#if defined(REPRAPWORLD_KEYPAD) + #define NEWPANEL + #define ULTIPANEL +#endif +#if defined(RA_CONTROL_PANEL) + #define ULTIPANEL + #define NEWPANEL + #define LCD_I2C_TYPE_PCA8574 + #define LCD_I2C_ADDRESS 0x27 // I2C Address of the port expander +#endif + +//I2C PANELS + +//#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 + + #ifndef ENCODER_PULSES_PER_STEP + #define ENCODER_PULSES_PER_STEP 4 + #endif + + #ifndef ENCODER_STEPS_PER_MENU_ITEM + #define ENCODER_STEPS_PER_MENU_ITEM 1 + #endif + + + #ifdef LCD_USE_I2C_BUZZER + #define LCD_FEEDBACK_FREQUENCY_HZ 1000 + #define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 + #endif + +#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 + +// Shift register panels +// --------------------- +// 2 wire Non-latching LCD SR from: +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/schematics#!shiftregister-connection +//#define SR_LCD +#ifdef SR_LCD + #define SR_LCD_2W_NL // Non latching 2 wire shift register + //#define NEWPANEL +#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 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 + #endif +#endif + +// default LCD contrast for dogm-like LCD displays +#ifdef DOGLCD +# ifndef DEFAULT_LCD_CONTRAST +# define DEFAULT_LCD_CONTRAST 32 +# endif +#endif + +// Increase the FAN pwm frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Temperature status LEDs that display the hotend and bet temperature. +// If all hotends and bed temperature and temperature setpoint are < 54C then the BLUE led is on. +// Otherwise the RED led is on. There is 1C hysteresis. +//#define TEMP_STAT_LEDS + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not ass annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +// #define PHOTOGRAPH_PIN 23 + +// 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 + +//define BlinkM/CyzRgb Support +//#define BLINKM + +/*********************************************************************\ +* 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 // Servo index starts with 0 for M280 command + +// Servo Endstops +// +// This allows for servo actuated endstops, primary usage is for the Z Axis to eliminate calibration or bed height changes. +// Use M206 command to correct for switch height offset to actual nozzle height. Store that setting with M500. +// + +#define DIGIPOT_I2C + +//#define SERVO_ENDSTOPS {-1, -1, 0} // Servo index for X, Y, Z. Disable with -1 +//#define SERVO_ENDSTOP_ANGLES {0,0, 0,0, 70,0} // X,Y,Z Axis Extend and Retract angles + +#include "Configuration_adv.h" +#include "thermistortables.h" + +#endif //__CONFIGURATION_H diff --git a/Marlin/example_configurations/makibox/Configuration_adv.h b/Marlin/example_configurations/makibox/Configuration_adv.h new file mode 100644 index 000000000..7883c7999 --- /dev/null +++ b/Marlin/example_configurations/makibox/Configuration_adv.h @@ -0,0 +1,498 @@ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#ifdef BED_LIMIT_SWITCHING + #define BED_HYSTERESIS 2 //only disable heating if T>target+BED_HYSTERESIS and enable heating if T>target-BED_HYSTERESIS +#endif +#define BED_CHECK_INTERVAL 5000 //ms between checks in bang-bang control + +//// Heating sanity check: +// This waits for the watch period in milliseconds whenever an M104 or M109 increases the target temperature +// If the temperature has not increased at the end of that period, the target temperature is set to zero. +// It can be reset with another M104/M109. This check is also only triggered if the target temperature and the current temperature +// differ by at least 2x WATCH_TEMP_INCREASE +//#define WATCH_TEMP_PERIOD 40000 //40 seconds +//#define WATCH_TEMP_INCREASE 10 //Heat up at least 10 degree in 20 seconds + +#ifdef PIDTEMP + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + #define PID_ADD_EXTRUSION_RATE + #ifdef PID_ADD_EXTRUSION_RATE + #define DEFAULT_Kc (1) //heating power=Kc*(e_speed) + #endif +#endif + + +//automatic temperature: The hot end target temperature is calculated by all the buffered lines of gcode. +//The maximum buffered steps/sec of the extruder motor are called "se". +//You enter the autotemp mode by a M109 S T F +// the target temperature is set to mintemp+factor*se[steps/sec] and limited by mintemp and maxtemp +// you exit the value by any M109 without F* +// Also, if the temperature is set to a value +// Mode 0: Full control. The slicer has full control over both x-carriages and can achieve optimal travel results +// as long as it supports dual x-carriages. (M605 S0) +// Mode 1: Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so +// that additional slicer support is not required. (M605 S1) +// Mode 2: Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all +// actions of the first x-carriage. This allows the printer to print 2 arbitrary items at +// once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + +// This is the default power-up mode which can be later using M605. +#define DEFAULT_DUAL_X_CARRIAGE_MODE 0 + +// As the x-carriages are independent we can now account for any relative Z offset +#define EXTRUDER1_Z_OFFSET 0.0 // z offset relative to extruder 0 + +// Default settings in "Auto-park Mode" +#define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder +#define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + +// Default x offset in duplication mode (typically set to half print bed width) +#define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif //DUAL_X_CARRIAGE + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#define X_HOME_RETRACT_MM 5 +#define Y_HOME_RETRACT_MM 5 +#define Z_HOME_RETRACT_MM 2 +//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +#define MAX_STEP_FREQUENCY 40000 // Max step frequency for Ultimaker (5000 pps / half step) + +//By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#define INVERT_Z_STEP_PIN false +#define INVERT_E_STEP_PIN false + +//default stepper release if idle +#define DEFAULT_STEPPER_DEACTIVE_TIME 60 + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +// Feedrates for manual moves along X, Y, Z, E from panel +#ifdef ULTIPANEL +#define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // set the speeds for manual moves (mm/min) +#endif + +//Comment to disable setting feedrate multiplier via encoder +#ifdef ULTIPANEL + #define ULTIPANEL_FEEDMULTIPLY +#endif + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// Minimum planner junction speed. Sets the default minimum speed the planner plans for at the end +// of the buffer and all stops. This should not be much greater than zero and should only be changed +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05// (mm/sec) + +// MS1 MS2 Stepper Driver Microstepping mode table +#define MICROSTEP1 LOW,LOW +#define MICROSTEP2 HIGH,LOW +#define MICROSTEP4 LOW,HIGH +#define MICROSTEP8 HIGH,HIGH +#define MICROSTEP16 HIGH,HIGH + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] + +// Motor Current setting (Only functional when motor driver current ref pins are connected to a digital trimpot on supported boards) +#define DIGIPOT_MOTOR_CURRENT {135,135,135,135,135} // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A) + +// uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +// Number of channels available for I2C digipot, For Azteeg X3 Pro we have 8 +#define DIGIPOT_I2C_NUM_CHANNELS 4 +// actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +//#define DIGIPOT_I2C_MOTOR_CURRENTS {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0} +#define DIGIPOT_I2C_MOTOR_CURRENTS {1.7, 1.7, 1.7, 1.7} + +//=========================================================================== +//=============================Additional Features=========================== +//=========================================================================== + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +#define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? +#define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + +#define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. +// if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. +// using: +//#define MENU_ADDAUTOSTART + +// The hardware watchdog should reset the microcontroller disabling all outputs, in case the firmware gets stuck and doesn't do temperature regulation. +//#define USE_WATCHDOG + +#ifdef USE_WATCHDOG +// If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. +// The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. +// 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 + +// Babystepping enables the user to control the axis in tiny amounts, independently from the normal printing process +// it can e.g. be used to change z-positions in the print startup phase in real-time +// does not respect endstops! +//#define BABYSTEPPING +#ifdef BABYSTEPPING + #define BABYSTEP_XY //not only z, but also XY in the menu. more clutter, more functions + #define BABYSTEP_INVERT_Z false //true for inverse movements in Z + #define BABYSTEP_Z_MULTIPLICATOR 2 //faster z movements + + #ifdef COREXY + #error BABYSTEPPING not implemented for COREXY yet. + #endif + + #ifdef DELTA + #ifdef BABYSTEP_XY + #error BABYSTEPPING only implemented for Z axis on deltabots. + #endif + #endif +#endif + +// extruder advance constant (s2/mm3) +// +// advance (steps) = STEPS_PER_CUBIC_MM_E * EXTUDER_ADVANCE_K * cubic mm per second ^ 2 +// +// Hooke's law says: force = k * distance +// Bernoulli's principle says: v ^ 2 / 2 + g . h + pressure / density = constant +// so: v ^ 2 is proportional to number of steps we advance the extruder +//#define ADVANCE + +#ifdef ADVANCE + #define EXTRUDER_ADVANCE_K .0 + + #define D_FILAMENT 2.85 + #define STEPS_MM_E 836 + #define EXTRUTION_AREA (0.25 * D_FILAMENT * D_FILAMENT * 3.14159) + #define STEPS_PER_CUBIC_MM_E (axis_steps_per_unit[E_AXIS]/ EXTRUTION_AREA) + +#endif // ADVANCE + +// Arc interpretation settings: +#define MM_PER_ARC_SEGMENT 1 +#define N_ARC_CORRECTION 25 + +const unsigned int dropsegments=5; //everything with less than this number of steps will be ignored as move and joined with the next movement + +// If you are using a RAMPS board or cheap E-bay purchased boards that do not detect when an SD card is inserted +// You can get round this by connecting a push button or single throw switch to the pin defined as SDCARDCARDDETECT +// in the pins.h file. When using a push button pulling the pin to ground this will need inverted. This setting should +// be commented out otherwise +//#define SDCARDDETECTINVERTED + +#ifdef ULTIPANEL + #undef SDCARDDETECTINVERTED +#endif + +// Power Signal Control Definitions +// By default use ATX definition +#ifndef POWER_SUPPLY + #define POWER_SUPPLY 1 +#endif +// 1 = ATX +#if (POWER_SUPPLY == 1) + #define PS_ON_AWAKE LOW + #define PS_ON_ASLEEP HIGH +#endif +// 2 = X-Box 360 203W +#if (POWER_SUPPLY == 2) + #define PS_ON_AWAKE HIGH + #define PS_ON_ASLEEP LOW +#endif + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//=============================Buffers ============================ +//=========================================================================== + +// The number of linear motions that can be in the plan at any give time. +// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +#if defined SDSUPPORT + #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + + +//The ASCII buffer for receiving from the serial: +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + + +// Firmware based and LCD controlled retract +// M207 and M208 can be used to define parameters for the retraction. +// The retraction can be called by the slicer using G10 and G11 +// until then, intended retractions can be detected by moves that only extrude and the direction. +// the moves are than replaced by the firmware controlled ones. + +// #define FWRETRACT //ONLY PARTIALLY TESTED +#ifdef FWRETRACT + #define MIN_RETRACT 0.1 //minimum extruded mm to accept a automatic gcode retraction attempt + #define RETRACT_LENGTH 3 //default retract length (positive mm) + #define RETRACT_FEEDRATE 45 //default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 //default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 //default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_FEEDRATE 8 //default feedrate for recovering from retraction (mm/s) +#endif + +//adds support for experimental filament exchange support M600; requires display +#ifdef ULTIPANEL + #define FILAMENTCHANGEENABLE + #ifdef FILAMENTCHANGEENABLE + #define FILAMENTCHANGE_XPOS 3 + #define FILAMENTCHANGE_YPOS 3 + #define FILAMENTCHANGE_ZADD 10 + #define FILAMENTCHANGE_FIRSTRETRACT -2 + #define FILAMENTCHANGE_FINALRETRACT -100 + #endif +#endif + +#ifdef FILAMENTCHANGEENABLE + #ifdef EXTRUDER_RUNOUT_PREVENT + #error EXTRUDER_RUNOUT_PREVENT currently incompatible with FILAMENTCHANGE + #endif +#endif + +//=========================================================================== +//============================= Define Defines ============================ +//=========================================================================== +#if EXTRUDERS > 1 && defined TEMP_SENSOR_1_AS_REDUNDANT + #error "You cannot use TEMP_SENSOR_1_AS_REDUNDANT if EXTRUDERS > 1" +#endif + +#if EXTRUDERS > 1 && defined HEATERS_PARALLEL + #error "You cannot use HEATERS_PARALLEL if EXTRUDERS > 1" +#endif + +#if TEMP_SENSOR_0 > 0 + #define THERMISTORHEATER_0 TEMP_SENSOR_0 + #define HEATER_0_USES_THERMISTOR +#endif +#if TEMP_SENSOR_1 > 0 + #define THERMISTORHEATER_1 TEMP_SENSOR_1 + #define HEATER_1_USES_THERMISTOR +#endif +#if TEMP_SENSOR_2 > 0 + #define THERMISTORHEATER_2 TEMP_SENSOR_2 + #define HEATER_2_USES_THERMISTOR +#endif +#if TEMP_SENSOR_BED > 0 + #define THERMISTORBED TEMP_SENSOR_BED + #define BED_USES_THERMISTOR +#endif +#if TEMP_SENSOR_0 == -1 + #define HEATER_0_USES_AD595 +#endif +#if TEMP_SENSOR_1 == -1 + #define HEATER_1_USES_AD595 +#endif +#if TEMP_SENSOR_2 == -1 + #define HEATER_2_USES_AD595 +#endif +#if TEMP_SENSOR_BED == -1 + #define BED_USES_AD595 +#endif +#if TEMP_SENSOR_0 == -2 + #define HEATER_0_USES_MAX6675 +#endif +#if TEMP_SENSOR_0 == 0 + #undef HEATER_0_MINTEMP + #undef HEATER_0_MAXTEMP +#endif +#if TEMP_SENSOR_1 == 0 + #undef HEATER_1_MINTEMP + #undef HEATER_1_MAXTEMP +#endif +#if TEMP_SENSOR_2 == 0 + #undef HEATER_2_MINTEMP + #undef HEATER_2_MAXTEMP +#endif +#if TEMP_SENSOR_BED == 0 + #undef BED_MINTEMP + #undef BED_MAXTEMP +#endif + + +#endif //__CONFIGURATION_ADV_H diff --git a/Marlin/fastio.h b/Marlin/fastio.h index 0746bf12b..53f8221df 100644 --- a/Marlin/fastio.h +++ b/Marlin/fastio.h @@ -1,5 +1,5 @@ /* - This code contibuted by Triffid_Hunter and modified by Kliment + This code contributed by Triffid_Hunter and modified by Kliment why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html */ @@ -1385,7 +1385,101 @@ pins #define DIO69_DDR DDRK #define DIO69_PWM NULL - +#define DIO70_PIN PING4 +#define DIO70_RPORT PING +#define DIO70_WPORT PORTG +#define DIO70_DDR DDRG +#define DIO70_PWM NULL + +#define DIO71_PIN PING3 +#define DIO71_RPORT PING +#define DIO71_WPORT PORTG +#define DIO71_DDR DDRG +#define DIO71_PWM NULL + +#define DIO72_PIN PINJ2 +#define DIO72_RPORT PINJ +#define DIO72_WPORT PORTJ +#define DIO72_DDR DDRJ +#define DIO72_PWM NULL + +#define DIO73_PIN PINJ3 +#define DIO73_RPORT PINJ +#define DIO73_WPORT PORTJ +#define DIO73_DDR DDRJ +#define DIO73_PWM NULL + +#define DIO74_PIN PINJ7 +#define DIO74_RPORT PINJ +#define DIO74_WPORT PORTJ +#define DIO74_DDR DDRJ +#define DIO74_PWM NULL + +#define DIO75_PIN PINJ4 +#define DIO75_RPORT PINJ +#define DIO75_WPORT PORTJ +#define DIO75_DDR DDRJ +#define DIO75_PWM NULL + +#define DIO76_PIN PINJ5 +#define DIO76_RPORT PINJ +#define DIO76_WPORT PORTJ +#define DIO76_DDR DDRJ +#define DIO76_PWM NULL + +#define DIO77_PIN PINJ6 +#define DIO77_RPORT PINJ +#define DIO77_WPORT PORTJ +#define DIO77_DDR DDRJ +#define DIO77_PWM NULL + +#define DIO78_PIN PINE2 +#define DIO78_RPORT PINE +#define DIO78_WPORT PORTE +#define DIO78_DDR DDRE +#define DIO78_PWM NULL + +#define DIO79_PIN PINE6 +#define DIO79_RPORT PINE +#define DIO79_WPORT PORTE +#define DIO79_DDR DDRE +#define DIO79_PWM NULL + +#define DIO80_PIN PINE7 +#define DIO80_RPORT PINE +#define DIO80_WPORT PORTE +#define DIO80_DDR DDRE +#define DIO80_PWM NULL + +#define DIO81_PIN PIND4 +#define DIO81_RPORT PIND +#define DIO81_WPORT PORTD +#define DIO81_DDR DDRD +#define DIO81_PWM NULL + +#define DIO82_PIN PIND5 +#define DIO82_RPORT PIND +#define DIO82_WPORT PORTD +#define DIO82_DDR DDRD +#define DIO82_PWM NULL + +#define DIO83_PIN PIND6 +#define DIO83_RPORT PIND +#define DIO83_WPORT PORTD +#define DIO83_DDR DDRD +#define DIO83_PWM NULL + +#define DIO84_PIN PINH2 +#define DIO84_RPORT PINH +#define DIO84_WPORT PORTH +#define DIO84_DDR DDRH +#define DIO84_PWM NULL + +#define DIO85_PIN PINH7 +#define DIO85_RPORT PINH +#define DIO85_WPORT PORTH +#define DIO85_DDR DDRH +#define DIO85_PWM NULL #undef PA0 #define PA0_PIN PINA0 @@ -1941,6 +2035,10 @@ pins /* pins */ + +//#define AT90USBxx_TEENSYPP_ASSIGNMENTS // Use Teensy++ 2.0 assignments +#ifndef AT90USBxx_TEENSYPP_ASSIGNMENTS // Use traditional Marlin pin assignments + #define DIO0_PIN PINA0 #define DIO0_RPORT PINA #define DIO0_WPORT PORTA @@ -2573,7 +2671,653 @@ pins #define PF7_WPORT PORTF #define PF7_PWM NULL #define PF7_DDR DDRF -#endif + +#else // AT90USBxx_TEENSYPP_ASSIGNMENTS -- Use Teensyduino Teensy++2.0 assignments. + +/* + +AT90USB 51 50 49 48 47 46 45 44 10 11 12 13 14 15 16 17 35 36 37 38 39 40 41 42 25 26 27 28 29 30 31 32 33 34 43 09 18 19 01 02 61 60 59 58 57 56 55 54 +Port A0 A1 A2 A3 A4 A5 A6 A7 B0 B1 B2 B3 B4 B5 B6 B7 C0 C1 C2 C3 C4 C5 C6 C7 D0 D1 D2 D3 D4 D5 D6 D7 E0 E1 E2 E3 E4 E5 E6 E7 F0 F1 F2 F3 F4 F5 F6 F7 +Marlin 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 +Teensy 28 29 30 31 32 33 34 35 20 21 22 23 24 25 26 27 10 11 12 13 14 15 16 17 00 01 02 03 04 05 06 07 08 09(46*47)36 37 18 19 38 39 40 41 42 43 44 45 + The pins 46 and 47 are not supported by Teensyduino, but are supported below. +*/ + +#define DIO0_PIN PIND0 +#define DIO0_RPORT PIND +#define DIO0_WPORT PORTD +#define DIO0_PWM NULL +#define DIO0_DDR DDRD + +#define DIO1_PIN PIND1 +#define DIO1_RPORT PIND +#define DIO1_WPORT PORTD +#define DIO1_PWM NULL +#define DIO1_DDR DDRD + +#define DIO2_PIN PIND2 +#define DIO2_RPORT PIND +#define DIO2_WPORT PORTD +#define DIO2_PWM NULL +#define DIO2_DDR DDRD + +#define DIO3_PIN PIND3 +#define DIO3_RPORT PIND +#define DIO3_WPORT PORTD +#define DIO3_PWM NULL +#define DIO3_DDR DDRD + +#define DIO4_PIN PIND4 +#define DIO4_RPORT PIND +#define DIO4_WPORT PORTD +#define DIO4_PWM NULL +#define DIO4_DDR DDRD + +#define DIO5_PIN PIND5 +#define DIO5_RPORT PIND +#define DIO5_WPORT PORTD +#define DIO5_PWM NULL +#define DIO5_DDR DDRD + +#define DIO6_PIN PIND6 +#define DIO6_RPORT PIND +#define DIO6_WPORT PORTD +#define DIO6_PWM NULL +#define DIO6_DDR DDRD + +#define DIO7_PIN PIND7 +#define DIO7_RPORT PIND +#define DIO7_WPORT PORTD +#define DIO7_PWM NULL +#define DIO7_DDR DDRD + +#define DIO8_PIN PINE0 +#define DIO8_RPORT PINE +#define DIO8_WPORT PORTE +#define DIO8_PWM NULL +#define DIO8_DDR DDRE + +#define DIO9_PIN PINE1 +#define DIO9_RPORT PINE +#define DIO9_WPORT PORTE +#define DIO9_PWM NULL +#define DIO9_DDR DDRE + +#define DIO10_PIN PINC0 +#define DIO10_RPORT PINC +#define DIO10_WPORT PORTC +#define DIO10_PWM NULL +#define DIO10_DDR DDRC + +#define DIO11_PIN PINC1 +#define DIO11_RPORT PINC +#define DIO11_WPORT PORTC +#define DIO11_PWM NULL +#define DIO11_DDR DDRC + +#define DIO12_PIN PINC2 +#define DIO12_RPORT PINC +#define DIO12_WPORT PORTC +#define DIO12_PWM NULL +#define DIO12_DDR DDRC + +#define DIO13_PIN PINC3 +#define DIO13_RPORT PINC +#define DIO13_WPORT PORTC +#define DIO13_PWM NULL +#define DIO13_DDR DDRC + +#define DIO14_PIN PINC4 +#define DIO14_RPORT PINC +#define DIO14_WPORT PORTC +#define DIO14_PWM NULL +#define DIO14_DDR DDRC + +#define DIO15_PIN PINC5 +#define DIO15_RPORT PINC +#define DIO15_WPORT PORTC +#define DIO15_PWM NULL +#define DIO15_DDR DDRC + +#define DIO16_PIN PINC6 +#define DIO16_RPORT PINC +#define DIO16_WPORT PORTC +#define DIO16_PWM NULL +#define DIO16_DDR DDRC + +#define DIO17_PIN PINC7 +#define DIO17_RPORT PINC +#define DIO17_WPORT PORTC +#define DIO17_PWM NULL +#define DIO17_DDR DDRC + +#define DIO18_PIN PINE6 +#define DIO18_RPORT PINE +#define DIO18_WPORT PORTE +#define DIO18_PWM NULL +#define DIO18_DDR DDRE + +#define DIO19_PIN PINE7 +#define DIO19_RPORT PINE +#define DIO19_WPORT PORTE +#define DIO19_PWM NULL +#define DIO19_DDR DDRE + +#define DIO20_PIN PINB0 +#define DIO20_RPORT PINB +#define DIO20_WPORT PORTB +#define DIO20_PWM NULL +#define DIO20_DDR DDRB + +#define DIO21_PIN PINB1 +#define DIO21_RPORT PINB +#define DIO21_WPORT PORTB +#define DIO21_PWM NULL +#define DIO21_DDR DDRB + +#define DIO22_PIN PINB2 +#define DIO22_RPORT PINB +#define DIO22_WPORT PORTB +#define DIO22_PWM NULL +#define DIO22_DDR DDRB + +#define DIO23_PIN PINB3 +#define DIO23_RPORT PINB +#define DIO23_WPORT PORTB +#define DIO23_PWM NULL +#define DIO23_DDR DDRB + +#define DIO24_PIN PINB4 +#define DIO24_RPORT PINB +#define DIO24_WPORT PORTB +#define DIO24_PWM NULL +#define DIO24_DDR DDRB + +#define DIO25_PIN PINB5 +#define DIO25_RPORT PINB +#define DIO25_WPORT PORTB +#define DIO25_PWM NULL +#define DIO25_DDR DDRB + +#define DIO26_PIN PINB6 +#define DIO26_RPORT PINB +#define DIO26_WPORT PORTB +#define DIO26_PWM NULL +#define DIO26_DDR DDRB + +#define DIO27_PIN PINB7 +#define DIO27_RPORT PINB +#define DIO27_WPORT PORTB +#define DIO27_PWM NULL +#define DIO27_DDR DDRB + +#define DIO28_PIN PINA0 +#define DIO28_RPORT PINA +#define DIO28_WPORT PORTA +#define DIO28_PWM NULL +#define DIO28_DDR DDRA + +#define DIO29_PIN PINA1 +#define DIO29_RPORT PINA +#define DIO29_WPORT PORTA +#define DIO29_PWM NULL +#define DIO29_DDR DDRA + +#define DIO30_PIN PINA2 +#define DIO30_RPORT PINA +#define DIO30_WPORT PORTA +#define DIO30_PWM NULL +#define DIO30_DDR DDRA + +#define DIO31_PIN PINA3 +#define DIO31_RPORT PINA +#define DIO31_WPORT PORTA +#define DIO31_PWM NULL +#define DIO31_DDR DDRA + +#define DIO32_PIN PINA4 +#define DIO32_RPORT PINA +#define DIO32_WPORT PORTA +#define DIO32_PWM NULL +#define DIO32_DDR DDRA + +#define DIO33_PIN PINA5 +#define DIO33_RPORT PINA +#define DIO33_WPORT PORTA +#define DIO33_PWM NULL +#define DIO33_DDR DDRA + +#define DIO34_PIN PINA6 +#define DIO34_RPORT PINA +#define DIO34_WPORT PORTA +#define DIO34_PWM NULL +#define DIO34_DDR DDRA + +#define DIO35_PIN PINA7 +#define DIO35_RPORT PINA +#define DIO35_WPORT PORTA +#define DIO35_PWM NULL +#define DIO35_DDR DDRA + +#define DIO36_PIN PINE4 +#define DIO36_RPORT PINE +#define DIO36_WPORT PORTE +#define DIO36_PWM NULL +#define DIO36_DDR DDRE + +#define DIO37_PIN PINE5 +#define DIO37_RPORT PINE +#define DIO37_WPORT PORTE +#define DIO37_PWM NULL +#define DIO37_DDR DDRE + +#define DIO38_PIN PINF0 +#define DIO38_RPORT PINF +#define DIO38_WPORT PORTF +#define DIO38_PWM NULL +#define DIO38_DDR DDRF + +#define DIO39_PIN PINF1 +#define DIO39_RPORT PINF +#define DIO39_WPORT PORTF +#define DIO39_PWM NULL +#define DIO39_DDR DDRF + +#define DIO40_PIN PINF2 +#define DIO40_RPORT PINF +#define DIO40_WPORT PORTF +#define DIO40_PWM NULL +#define DIO40_DDR DDRF + +#define DIO41_PIN PINF3 +#define DIO41_RPORT PINF +#define DIO41_WPORT PORTF +#define DIO41_PWM NULL +#define DIO41_DDR DDRF + +#define DIO42_PIN PINF4 +#define DIO42_RPORT PINF +#define DIO42_WPORT PORTF +#define DIO42_PWM NULL +#define DIO42_DDR DDRF + +#define DIO43_PIN PINF5 +#define DIO43_RPORT PINF +#define DIO43_WPORT PORTF +#define DIO43_PWM NULL +#define DIO43_DDR DDRF + +#define DIO44_PIN PINF6 +#define DIO44_RPORT PINF +#define DIO44_WPORT PORTF +#define DIO44_PWM NULL +#define DIO44_DDR DDRF + +#define DIO45_PIN PINF7 +#define DIO45_RPORT PINF +#define DIO45_WPORT PORTF +#define DIO45_PWM NULL +#define DIO45_DDR DDRF + +#define AIO0_PIN PINF0 +#define AIO0_RPORT PINF +#define AIO0_WPORT PORTF +#define AIO0_PWM NULL +#define AIO0_DDR DDRF + +#define AIO1_PIN PINF1 +#define AIO1_RPORT PINF +#define AIO1_WPORT PORTF +#define AIO1_PWM NULL +#define AIO1_DDR DDRF + +#define AIO2_PIN PINF2 +#define AIO2_RPORT PINF +#define AIO2_WPORT PORTF +#define AIO2_PWM NULL +#define AIO2_DDR DDRF + +#define AIO3_PIN PINF3 +#define AIO3_RPORT PINF +#define AIO3_WPORT PORTF +#define AIO3_PWM NULL +#define AIO3_DDR DDRF + +#define AIO4_PIN PINF4 +#define AIO4_RPORT PINF +#define AIO4_WPORT PORTF +#define AIO4_PWM NULL +#define AIO4_DDR DDRF + +#define AIO5_PIN PINF5 +#define AIO5_RPORT PINF +#define AIO5_WPORT PORTF +#define AIO5_PWM NULL +#define AIO5_DDR DDRF + +#define AIO6_PIN PINF6 +#define AIO6_RPORT PINF +#define AIO6_WPORT PORTF +#define AIO6_PWM NULL +#define AIO6_DDR DDRF + +#define AIO7_PIN PINF7 +#define AIO7_RPORT PINF +#define AIO7_WPORT PORTF +#define AIO7_PWM NULL +#define AIO7_DDR DDRF + +//-- Begin not supported by Teensyduino +//-- don't use Arduino functions on these pins pinMode/digitalWrite/etc +#define DIO46_PIN PINE2 +#define DIO46_RPORT PINE +#define DIO46_WPORT PORTE +#define DIO46_PWM NULL +#define DIO46_DDR DDRE + +#define DIO47_PIN PINE3 +#define DIO47_RPORT PINE +#define DIO47_WPORT PORTE +#define DIO47_PWM NULL +#define DIO47_DDR DDRE +//-- end not supported by Teensyduino + +#undef PA0 +#define PA0_PIN PINA0 +#define PA0_RPORT PINA +#define PA0_WPORT PORTA +#define PA0_PWM NULL +#define PA0_DDR DDRA +#undef PA1 +#define PA1_PIN PINA1 +#define PA1_RPORT PINA +#define PA1_WPORT PORTA +#define PA1_PWM NULL +#define PA1_DDR DDRA +#undef PA2 +#define PA2_PIN PINA2 +#define PA2_RPORT PINA +#define PA2_WPORT PORTA +#define PA2_PWM NULL +#define PA2_DDR DDRA +#undef PA3 +#define PA3_PIN PINA3 +#define PA3_RPORT PINA +#define PA3_WPORT PORTA +#define PA3_PWM NULL +#define PA3_DDR DDRA +#undef PA4 +#define PA4_PIN PINA4 +#define PA4_RPORT PINA +#define PA4_WPORT PORTA +#define PA4_PWM NULL +#define PA4_DDR DDRA +#undef PA5 +#define PA5_PIN PINA5 +#define PA5_RPORT PINA +#define PA5_WPORT PORTA +#define PA5_PWM NULL +#define PA5_DDR DDRA +#undef PA6 +#define PA6_PIN PINA6 +#define PA6_RPORT PINA +#define PA6_WPORT PORTA +#define PA6_PWM NULL +#define PA6_DDR DDRA +#undef PA7 +#define PA7_PIN PINA7 +#define PA7_RPORT PINA +#define PA7_WPORT PORTA +#define PA7_PWM NULL +#define PA7_DDR DDRA + +#undef PB0 +#define PB0_PIN PINB0 +#define PB0_RPORT PINB +#define PB0_WPORT PORTB +#define PB0_PWM NULL +#define PB0_DDR DDRB +#undef PB1 +#define PB1_PIN PINB1 +#define PB1_RPORT PINB +#define PB1_WPORT PORTB +#define PB1_PWM NULL +#define PB1_DDR DDRB +#undef PB2 +#define PB2_PIN PINB2 +#define PB2_RPORT PINB +#define PB2_WPORT PORTB +#define PB2_PWM NULL +#define PB2_DDR DDRB +#undef PB3 +#define PB3_PIN PINB3 +#define PB3_RPORT PINB +#define PB3_WPORT PORTB +#define PB3_PWM NULL +#define PB3_DDR DDRB +#undef PB4 +#define PB4_PIN PINB4 +#define PB4_RPORT PINB +#define PB4_WPORT PORTB +#define PB4_PWM NULL +#define PB4_DDR DDRB +#undef PB5 +#define PB5_PIN PINB5 +#define PB5_RPORT PINB +#define PB5_WPORT PORTB +#define PB5_PWM NULL +#define PB5_DDR DDRB +#undef PB6 +#define PB6_PIN PINB6 +#define PB6_RPORT PINB +#define PB6_WPORT PORTB +#define PB6_PWM NULL +#define PB6_DDR DDRB +#undef PB7 +#define PB7_PIN PINB7 +#define PB7_RPORT PINB +#define PB7_WPORT PORTB +#define PB7_PWM NULL +#define PB7_DDR DDRB + +#undef PC0 +#define PC0_PIN PINC0 +#define PC0_RPORT PINC +#define PC0_WPORT PORTC +#define PC0_PWM NULL +#define PC0_DDR DDRC +#undef PC1 +#define PC1_PIN PINC1 +#define PC1_RPORT PINC +#define PC1_WPORT PORTC +#define PC1_PWM NULL +#define PC1_DDR DDRC +#undef PC2 +#define PC2_PIN PINC2 +#define PC2_RPORT PINC +#define PC2_WPORT PORTC +#define PC2_PWM NULL +#define PC2_DDR DDRC +#undef PC3 +#define PC3_PIN PINC3 +#define PC3_RPORT PINC +#define PC3_WPORT PORTC +#define PC3_PWM NULL +#define PC3_DDR DDRC +#undef PC4 +#define PC4_PIN PINC4 +#define PC4_RPORT PINC +#define PC4_WPORT PORTC +#define PC4_PWM NULL +#define PC4_DDR DDRC +#undef PC5 +#define PC5_PIN PINC5 +#define PC5_RPORT PINC +#define PC5_WPORT PORTC +#define PC5_PWM NULL +#define PC5_DDR DDRC +#undef PC6 +#define PC6_PIN PINC6 +#define PC6_RPORT PINC +#define PC6_WPORT PORTC +#define PC6_PWM NULL +#define PC6_DDR DDRC +#undef PC7 +#define PC7_PIN PINC7 +#define PC7_RPORT PINC +#define PC7_WPORT PORTC +#define PC7_PWM NULL +#define PC7_DDR DDRC + +#undef PD0 +#define PD0_PIN PIND0 +#define PD0_RPORT PIND +#define PD0_WPORT PORTD +#define PD0_PWM NULL +#define PD0_DDR DDRD +#undef PD1 +#define PD1_PIN PIND1 +#define PD1_RPORT PIND +#define PD1_WPORT PORTD +#define PD1_PWM NULL +#define PD1_DDR DDRD +#undef PD2 +#define PD2_PIN PIND2 +#define PD2_RPORT PIND +#define PD2_WPORT PORTD +#define PD2_PWM NULL +#define PD2_DDR DDRD +#undef PD3 +#define PD3_PIN PIND3 +#define PD3_RPORT PIND +#define PD3_WPORT PORTD +#define PD3_PWM NULL +#define PD3_DDR DDRD +#undef PD4 +#define PD4_PIN PIND4 +#define PD4_RPORT PIND +#define PD4_WPORT PORTD +#define PD4_PWM NULL +#define PD4_DDR DDRD +#undef PD5 +#define PD5_PIN PIND5 +#define PD5_RPORT PIND +#define PD5_WPORT PORTD +#define PD5_PWM NULL +#define PD5_DDR DDRD +#undef PD6 +#define PD6_PIN PIND6 +#define PD6_RPORT PIND +#define PD6_WPORT PORTD +#define PD6_PWM NULL +#define PD6_DDR DDRD +#undef PD7 +#define PD7_PIN PIND7 +#define PD7_RPORT PIND +#define PD7_WPORT PORTD +#define PD7_PWM NULL +#define PD7_DDR DDRD + +#undef PE0 +#define PE0_PIN PINE0 +#define PE0_RPORT PINE +#define PE0_WPORT PORTE +#define PE0_PWM NULL +#define PE0_DDR DDRE +#undef PE1 +#define PE1_PIN PINE1 +#define PE1_RPORT PINE +#define PE1_WPORT PORTE +#define PE1_PWM NULL +#define PE1_DDR DDRE +#undef PE2 +#define PE2_PIN PINE2 +#define PE2_RPORT PINE +#define PE2_WPORT PORTE +#define PE2_PWM NULL +#define PE2_DDR DDRE +#undef PE3 +#define PE3_PIN PINE3 +#define PE3_RPORT PINE +#define PE3_WPORT PORTE +#define PE3_PWM NULL +#define PE3_DDR DDRE +#undef PE4 +#define PE4_PIN PINE4 +#define PE4_RPORT PINE +#define PE4_WPORT PORTE +#define PE4_PWM NULL +#define PE4_DDR DDRE +#undef PE5 +#define PE5_PIN PINE5 +#define PE5_RPORT PINE +#define PE5_WPORT PORTE +#define PE5_PWM NULL +#define PE5_DDR DDRE +#undef PE6 +#define PE6_PIN PINE6 +#define PE6_RPORT PINE +#define PE6_WPORT PORTE +#define PE6_PWM NULL +#define PE6_DDR DDRE +#undef PE7 +#define PE7_PIN PINE7 +#define PE7_RPORT PINE +#define PE7_WPORT PORTE +#define PE7_PWM NULL +#define PE7_DDR DDRE + +#undef PF0 +#define PF0_PIN PINF0 +#define PF0_RPORT PINF +#define PF0_WPORT PORTF +#define PF0_PWM NULL +#define PF0_DDR DDRF +#undef PF1 +#define PF1_PIN PINF1 +#define PF1_RPORT PINF +#define PF1_WPORT PORTF +#define PF1_PWM NULL +#define PF1_DDR DDRF +#undef PF2 +#define PF2_PIN PINF2 +#define PF2_RPORT PINF +#define PF2_WPORT PORTF +#define PF2_PWM NULL +#define PF2_DDR DDRF +#undef PF3 +#define PF3_PIN PINF3 +#define PF3_RPORT PINF +#define PF3_WPORT PORTF +#define PF3_PWM NULL +#define PF3_DDR DDRF +#undef PF4 +#define PF4_PIN PINF4 +#define PF4_RPORT PINF +#define PF4_WPORT PORTF +#define PF4_PWM NULL +#define PF4_DDR DDRF +#undef PF5 +#define PF5_PIN PINF5 +#define PF5_RPORT PINF +#define PF5_WPORT PORTF +#define PF5_PWM NULL +#define PF5_DDR DDRF +#undef PF6 +#define PF6_PIN PINF6 +#define PF6_RPORT PINF +#define PF6_WPORT PORTF +#define PF6_PWM NULL +#define PF6_DDR DDRF +#undef PF7 +#define PF7_PIN PINF7 +#define PF7_RPORT PINF +#define PF7_WPORT PORTF +#define PF7_PWM NULL +#define PF7_DDR DDRF + +#endif // AT90USBxx_TEENSYPP_ASSIGNMENTS Teensyduino assignments +#endif // __AVR_AT90usbxxx__ #if defined (__AVR_ATmega1281__) || defined (__AVR_ATmega2561__) diff --git a/Marlin/language.h b/Marlin/language.h index 17222c7cd..c032aca89 100644 --- a/Marlin/language.h +++ b/Marlin/language.h @@ -16,14 +16,18 @@ // 7 Italian // 8 Portuguese // 9 Finnish +// 10 Aragonese +// 11 Dutch +// 12 Catalan +// 13 Basque-Euskera #ifndef LANGUAGE_CHOICE -#define LANGUAGE_CHOICE 1 // Pick your language from the list above + #define LANGUAGE_CHOICE 1 // Pick your language from the list above #endif #define PROTOCOL_VERSION "1.0" -#if MOTHERBOARD == 7 || MOTHERBOARD == 71 +#if MOTHERBOARD == 7 || MOTHERBOARD == 71 || MOTHERBOARD == 72 #define MACHINE_NAME "Ultimaker" #define FIRMWARE_URL "http://firmware.ultimaker.com" #elif MOTHERBOARD == 80 @@ -32,39 +36,80 @@ #elif MOTHERBOARD == 77 #define MACHINE_NAME "3Drag" #define FIRMWARE_URL "http://3dprint.elettronicain.it/" +#elif MOTHERBOARD == 88 + #define MACHINE_NAME "Makibox" + #define FIRMWARE_URL "https://github.com/ErikZalm/Marlin/" #else #ifdef CUSTOM_MENDEL_NAME #define MACHINE_NAME CUSTOM_MENDEL_NAME #else #define MACHINE_NAME "Mendel" #endif - #define FIRMWARE_URL "http://www.mendel-parts.com" + +// Default firmware set to Mendel + #define FIRMWARE_URL "https://github.com/ErikZalm/Marlin/" +#endif + + +#ifndef MACHINE_UUID + #define MACHINE_UUID "00000000-0000-0000-0000-000000000000" #endif + #define STRINGIFY_(n) #n #define STRINGIFY(n) STRINGIFY_(n) + +// Common LCD messages +/* nothing here as of yet */ + +// Common serial messages +#define MSG_MARLIN "Marlin" + + + #if LANGUAGE_CHOICE == 1 // LCD Menu Messages - #define WELCOME_MSG MACHINE_NAME " Ready." +// Please note these are limited to 17 characters! + + #define WELCOME_MSG MACHINE_NAME " ready." #define MSG_SD_INSERTED "Card inserted" #define MSG_SD_REMOVED "Card removed" #define MSG_MAIN "Main" #define MSG_AUTOSTART "Autostart" - #define MSG_DISABLE_STEPPERS "Disable Steppers" - #define MSG_AUTO_HOME "Auto Home" - #define MSG_SET_ORIGIN "Set Origin" + #define MSG_DISABLE_STEPPERS "Disable steppers" + #define MSG_AUTO_HOME "Auto home" + #define MSG_SET_ORIGIN "Set origin" #define MSG_PREHEAT_PLA "Preheat PLA" - #define MSG_PREHEAT_PLA_SETTINGS "Preheat PLA Conf" + #define MSG_PREHEAT_PLA0 "Preheat PLA 1" + #define MSG_PREHEAT_PLA1 "Preheat PLA 2" + #define MSG_PREHEAT_PLA2 "Preheat PLA 3" + #define MSG_PREHEAT_PLA012 "Preheat PLA All" + #define MSG_PREHEAT_PLA_BEDONLY "Preheat PLA Bed" + #define MSG_PREHEAT_PLA_SETTINGS "Preheat PLA conf" #define MSG_PREHEAT_ABS "Preheat ABS" - #define MSG_PREHEAT_ABS_SETTINGS "Preheat ABS Conf" + #define MSG_PREHEAT_ABS0 "Preheat ABS 1" + #define MSG_PREHEAT_ABS1 "Preheat ABS 2" + #define MSG_PREHEAT_ABS2 "Preheat ABS 3" + #define MSG_PREHEAT_ABS012 "Preheat ABS All" + #define MSG_PREHEAT_ABS_BEDONLY "Preheat ABS Bed" + #define MSG_PREHEAT_ABS_SETTINGS "Preheat ABS conf" #define MSG_COOLDOWN "Cooldown" - #define MSG_SWITCH_PS_ON "Switch Power On" - #define MSG_SWITCH_PS_OFF "Switch Power Off" + #define MSG_SWITCH_PS_ON "Switch power on" + #define MSG_SWITCH_PS_OFF "Switch power off" #define MSG_EXTRUDE "Extrude" #define MSG_RETRACT "Retract" - #define MSG_MOVE_AXIS "Move Axis" + #define MSG_MOVE_AXIS "Move axis" + #define MSG_MOVE_X "Move X" + #define MSG_MOVE_Y "Move Y" + #define MSG_MOVE_Z "Move Z" + #define MSG_MOVE_E "Extruder" + #define MSG_MOVE_E1 "Extruder2" + #define MSG_MOVE_E2 "Extruder3" + #define MSG_MOVE_01MM "Move 0.1mm" + #define MSG_MOVE_1MM "Move 1mm" + #define MSG_MOVE_10MM "Move 10mm" #define MSG_SPEED "Speed" #define MSG_NOZZLE "Nozzle" #define MSG_NOZZLE1 "Nozzle2" @@ -72,6 +117,9 @@ #define MSG_BED "Bed" #define MSG_FAN_SPEED "Fan speed" #define MSG_FLOW "Flow" + #define MSG_FLOW0 "Flow 0" + #define MSG_FLOW1 "Flow 1" + #define MSG_FLOW2 "Flow 2" #define MSG_CONTROL "Control" #define MSG_MIN " \002 Min" #define MSG_MAX " \002 Max" @@ -106,16 +154,16 @@ #define MSG_CONTRAST "LCD contrast" #define MSG_STORE_EPROM "Store memory" #define MSG_LOAD_EPROM "Load memory" - #define MSG_RESTORE_FAILSAFE "Restore Failsafe" + #define MSG_RESTORE_FAILSAFE "Restore failsafe" #define MSG_REFRESH "Refresh" #define MSG_WATCH "Info screen" #define MSG_PREPARE "Prepare" #define MSG_TUNE "Tune" - #define MSG_PAUSE_PRINT "Pause Print" - #define MSG_RESUME_PRINT "Resume Print" - #define MSG_STOP_PRINT "Stop Print" + #define MSG_PAUSE_PRINT "Pause print" + #define MSG_RESUME_PRINT "Resume print" + #define MSG_STOP_PRINT "Stop print" #define MSG_CARD_MENU "Print from SD" - #define MSG_NO_CARD "No Card" + #define MSG_NO_CARD "No SD card" #define MSG_DWELL "Sleep..." #define MSG_USERWAIT "Wait for user..." #define MSG_RESUMING "Resuming print" @@ -123,14 +171,21 @@ #define MSG_KILLED "KILLED. " #define MSG_STOPPED "STOPPED. " #define MSG_CONTROL_RETRACT "Retract mm" - #define MSG_CONTROL_RETRACTF "Retract F" + #define MSG_CONTROL_RETRACTF "Retract V" #define MSG_CONTROL_RETRACT_ZLIFT "Hop mm" #define MSG_CONTROL_RETRACT_RECOVER "UnRet +mm" - #define MSG_CONTROL_RETRACT_RECOVERF "UnRet F" + #define MSG_CONTROL_RETRACT_RECOVERF "UnRet V" #define MSG_AUTORETRACT "AutoRetr." #define MSG_FILAMENTCHANGE "Change filament" - #define MSG_INIT_SDCARD "Init. SD-Card" - #define MSG_CNG_SDCARD "Change SD-Card" + #define MSG_INIT_SDCARD "Init. SD card" + #define MSG_CNG_SDCARD "Change SD card" + #define MSG_ZPROBE_OUT "Z probe out. bed" + #define MSG_POSITION_UNKNOWN "Home X/Y before Z" + #define MSG_ZPROBE_ZOFFSET "Z Offset" + #define MSG_BABYSTEP_X "Babystep X" + #define MSG_BABYSTEP_Y "Babystep Y" + #define MSG_BABYSTEP_Z "Babystep Z" + #define MSG_ENDSTOP_ABORT "Endstop abort" // Serial Console Messages @@ -140,7 +195,6 @@ #define MSG_BROWNOUT_RESET " Brown out Reset" #define MSG_WATCHDOG_RESET " Watchdog Reset" #define MSG_SOFTWARE_RESET " Software Reset" - #define MSG_MARLIN "Marlin " #define MSG_AUTHOR " | Author: " #define MSG_CONFIGURATION_VER " Last Updated: " #define MSG_FREE_MEMORY " Free Memory: " @@ -156,14 +210,16 @@ #define MSG_END_FILE_LIST "End file list" #define MSG_M104_INVALID_EXTRUDER "M104 Invalid extruder " #define MSG_M105_INVALID_EXTRUDER "M105 Invalid extruder " + #define MSG_M200_INVALID_EXTRUDER "M200 Invalid extruder " #define MSG_M218_INVALID_EXTRUDER "M218 Invalid extruder " + #define MSG_M221_INVALID_EXTRUDER "M221 Invalid extruder " #define MSG_ERR_NO_THERMISTORS "No thermistors - no temperature" #define MSG_M109_INVALID_EXTRUDER "M109 Invalid extruder " #define MSG_HEATING "Heating..." #define MSG_HEATING_COMPLETE "Heating done." #define MSG_BED_HEATING "Bed Heating." #define MSG_BED_DONE "Bed done." - #define MSG_M115_REPORT "FIRMWARE_NAME:Marlin V1; Sprinter/grbl mashup for gen6 FIRMWARE_URL:" FIRMWARE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) "\n" + #define MSG_M115_REPORT "FIRMWARE_NAME:Marlin V1; Sprinter/grbl mashup for gen6 FIRMWARE_URL:" FIRMWARE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) " UUID:" MACHINE_UUID "\n" #define MSG_COUNT_X " Count X: " #define MSG_ERR_KILLED "Printer halted. kill() called!" #define MSG_ERR_STOPPED "Printer stopped due to errors. Fix the error and use M999 to restart. (Temperature is reset. Set it after restarting)" @@ -202,6 +258,10 @@ #define MSG_ENDSTOPS_HIT "endstops hit: " #define MSG_ERR_COLD_EXTRUDE_STOP " cold extrusion prevented" #define MSG_ERR_LONG_EXTRUDE_STOP " too long extrusion prevented" + #define MSG_BABYSTEPPING_X "Babystepping X" + #define MSG_BABYSTEPPING_Y "Babystepping Y" + #define MSG_BABYSTEPPING_Z "Babystepping Z" + #define MSG_SERIAL_ERROR_MENU_STRUCTURE "Error in menu structure" #endif @@ -209,43 +269,67 @@ #if LANGUAGE_CHOICE == 2 // LCD Menu Messages - #define WELCOME_MSG MACHINE_NAME " Gotowe." +// Please note these are limited to 17 characters! + + #define WELCOME_MSG MACHINE_NAME " gotowy." #define MSG_SD_INSERTED "Karta wlozona" #define MSG_SD_REMOVED "Karta usunieta" - #define MSG_MAIN "Main" + #define MSG_MAIN "Menu glowne" #define MSG_AUTOSTART "Autostart" #define MSG_DISABLE_STEPPERS "Wylacz silniki" #define MSG_AUTO_HOME "Auto. poz. zerowa" - #define MSG_SET_ORIGIN "Ustaw punkt zerowy" + #define MSG_SET_ORIGIN "Ustaw punkt zero" #define MSG_PREHEAT_PLA "Rozgrzej PLA" - #define MSG_PREHEAT_PLA_SETTINGS "Ustawienia roz. PLA" + #define MSG_PREHEAT_PLA0 "Rozgrzej PLA 1" + #define MSG_PREHEAT_PLA1 "Rozgrzej PLA 2" + #define MSG_PREHEAT_PLA2 "Rozgrzej PLA 3" + #define MSG_PREHEAT_PLA012 "Roz. PLA Wszystko" + #define MSG_PREHEAT_PLA_BEDONLY "Rozgrzej PLA Loze" + #define MSG_PREHEAT_PLA_SETTINGS "Ustaw. rozg. PLA" #define MSG_PREHEAT_ABS "Rozgrzej ABS" - #define MSG_PREHEAT_ABS_SETTINGS "Ustawienia roz. ABS" + #define MSG_PREHEAT_ABS0 "Rozgrzej ABS 1" + #define MSG_PREHEAT_ABS1 "Rozgrzej ABS 2" + #define MSG_PREHEAT_ABS2 "Rozgrzej ABS 3" + #define MSG_PREHEAT_ABS012 "Roz. ABS Wszystko" + #define MSG_PREHEAT_ABS_BEDONLY "Rozgrzej ABS Loze" + #define MSG_PREHEAT_ABS_SETTINGS "Ustaw. rozg. ABS" #define MSG_COOLDOWN "Chlodzenie" - #define MSG_SWITCH_PS_ON "Switch Power On" - #define MSG_SWITCH_PS_OFF "Switch Power Off" + #define MSG_SWITCH_PS_ON "Wlacz zasilacz" + #define MSG_SWITCH_PS_OFF "Wylacz zasilacz" #define MSG_EXTRUDE "Ekstruzja" #define MSG_RETRACT "Cofanie" #define MSG_MOVE_AXIS "Ruch osi" + #define MSG_MOVE_X "Przesun w X" + #define MSG_MOVE_Y "Przesun w Y" + #define MSG_MOVE_Z "Przesun w Z" + #define MSG_MOVE_E "Ekstruzja (os E)" + #define MSG_MOVE_E1 "Extruder2" + #define MSG_MOVE_E2 "Extruder3" + #define MSG_MOVE_01MM "Przesuwaj co .1mm" + #define MSG_MOVE_1MM "Przesuwaj co 1mm" + #define MSG_MOVE_10MM "Przesuwaj co 10mm" #define MSG_SPEED "Predkosc" #define MSG_NOZZLE "Dysza" - #define MSG_NOZZLE1 "Dysza2" - #define MSG_NOZZLE2 "Dysza3" + #define MSG_NOZZLE1 "Dysza 2" + #define MSG_NOZZLE2 "Dysza 3" #define MSG_BED "Loze" #define MSG_FAN_SPEED "Obroty wiatraka" #define MSG_FLOW "Przeplyw" + #define MSG_FLOW0 "Przeplyw 0" + #define MSG_FLOW1 "Przeplyw 1" + #define MSG_FLOW2 "Przeplyw 2" #define MSG_CONTROL "Kontrola" #define MSG_MIN " \002 Min" #define MSG_MAX " \002 Max" #define MSG_FACTOR " \002 Mnoznik" - #define MSG_AUTOTEMP "Auto. temp." + #define MSG_AUTOTEMP "Auto. temperatura" #define MSG_ON "Wl. " #define MSG_OFF "Wyl." #define MSG_PID_P "PID-P" #define MSG_PID_I "PID-I" #define MSG_PID_D "PID-D" #define MSG_PID_C "PID-C" - #define MSG_ACC "Acc" + #define MSG_ACC "Przyspieszenie" #define MSG_VXY_JERK "Zryw Vxy" #define MSG_VZ_JERK "Zryw Vz" #define MSG_VE_JERK "Zryw Ve" @@ -265,37 +349,44 @@ #define MSG_RECTRACT "Wycofanie" #define MSG_TEMPERATURE "Temperatura" #define MSG_MOTION "Ruch" - #define MSG_CONTRAST "LCD contrast" + #define MSG_CONTRAST "Kontrast LCD" #define MSG_STORE_EPROM "Zapisz w pamieci" #define MSG_LOAD_EPROM "Wczytaj z pamieci" - #define MSG_RESTORE_FAILSAFE " Ustawienia fabryczne" + #define MSG_RESTORE_FAILSAFE "Ustaw. fabryczne" #define MSG_REFRESH "\004Odswiez" - #define MSG_WATCH "Obserwuj" + #define MSG_WATCH "Ekran glowny" #define MSG_PREPARE "Przygotuj" - #define MSG_CONTROL "Kontroluj" + #define MSG_CONTROL "Ustawienia" #define MSG_TUNE "Strojenie" #define MSG_PAUSE_PRINT "Pauza" #define MSG_RESUME_PRINT "Wznowienie" #define MSG_STOP_PRINT "Stop" - #define MSG_CARD_MENU "Menu SDCard" + #define MSG_CARD_MENU "Menu karty SD" #define MSG_NO_CARD "Brak karty" #define MSG_DWELL "Uspij..." - #define MSG_USERWAIT "Czekaj na uzytkownika..." - #define MSG_RESUMING "Wznawiam drukowanie" - #define MSG_NO_MOVE "Brak ruchu." - #define MSG_PART_RELEASE "Czesciowe zwolnienie" + #define MSG_USERWAIT "Oczekiwanie..." + #define MSG_RESUMING "Wznawianie druku" + #define MSG_NO_MOVE "Brak ruchu" #define MSG_KILLED "Ubity. " #define MSG_STOPPED "Zatrzymany. " #define MSG_STEPPER_RELEASED "Zwolniony." #define MSG_CONTROL_RETRACT "Wycofaj mm" - #define MSG_CONTROL_RETRACTF "Wycofaj F" + #define MSG_CONTROL_RETRACTF "Wycofaj V" #define MSG_CONTROL_RETRACT_ZLIFT "Skok Z mm:" #define MSG_CONTROL_RETRACT_RECOVER "Cof. wycof. +mm" - #define MSG_CONTROL_RETRACT_RECOVERF "Cof. wycof. F" + #define MSG_CONTROL_RETRACT_RECOVERF "Cof. wycof. V" #define MSG_AUTORETRACT "Auto. wycofanie" - #define MSG_FILAMENTCHANGE "Change filament" - #define MSG_INIT_SDCARD "Init. SD-Card" - #define MSG_CNG_SDCARD "Change SD-Card" + #define MSG_FILAMENTCHANGE "Zmien filament" + #define MSG_INIT_SDCARD "Inicjal. karty SD" + #define MSG_CNG_SDCARD "Zmiana karty SD" + #define MSG_ZPROBE_OUT "Sonda Z za lozem" + #define MSG_POSITION_UNKNOWN "Wroc w XY przed Z" + #define MSG_ZPROBE_ZOFFSET "Offset Z" + #define MSG_BABYSTEP_X "Babystep X" + #define MSG_BABYSTEP_Y "Babystep Y" + #define MSG_BABYSTEP_Z "Babystep Z" + #define MSG_ENDSTOP_ABORT "Blad wyl. kranc." + #define MSG_CONTRAST "Kontrast" // Serial Console Messages @@ -305,12 +396,11 @@ #define MSG_BROWNOUT_RESET " Reset (spadek napiecia)" #define MSG_WATCHDOG_RESET " Reset (watchdog)" #define MSG_SOFTWARE_RESET " Reset (programowy)" - #define MSG_MARLIN "Marlin " #define MSG_AUTHOR " | Autor: " #define MSG_CONFIGURATION_VER " Ostatnia aktualizacja: " #define MSG_FREE_MEMORY " Wolna pamiec: " #define MSG_PLANNER_BUFFER_BYTES " Bufor planisty krokow (w bajtach): " - #define MSG_OK "ok" + #define MSG_OK "OK" #define MSG_FILE_SAVED "Plik zapisany." #define MSG_ERR_LINE_NO "Numer linijki nie jest ostatnim numerem linijki+1; ostatnia linijka:" #define MSG_ERR_CHECKSUM_MISMATCH "Niezgodna suma kontrolna; ostatnia linijka: " @@ -321,15 +411,17 @@ #define MSG_END_FILE_LIST "Koniec listy plikow" #define MSG_M104_INVALID_EXTRUDER "M104 Niepoprawny ekstruder " #define MSG_M105_INVALID_EXTRUDER "M105 Niepoprawny ekstruder " + #define MSG_M200_INVALID_EXTRUDER "M200 Niepoprawny ekstruder " #define MSG_M218_INVALID_EXTRUDER "M218 Niepoprawny ekstruder " + #define MSG_M221_INVALID_EXTRUDER "M221 Niepoprawny ekstruder " #define MSG_ERR_NO_THERMISTORS "Brak termistorow - brak temperatury :(" #define MSG_M109_INVALID_EXTRUDER "M109 Niepoprawny ekstruder " #define MSG_HEATING "Nagrzewanie ekstrudera..." #define MSG_HEATING_COMPLETE "Nagrzewanie ekstrudera zakonczone." #define MSG_BED_HEATING "Nagrzewanie loza..." #define MSG_BED_DONE "Nagrzewanie loza zakonczone." - #define MSG_M115_REPORT "FIRMWARE_NAME:Marlin V1; Sprinter/grbl mashup for gen6 FIRMWARE_URL:" FIRMWARE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) "\n" - #define MSG_COUNT_X " Liczenie X: " + #define MSG_M115_REPORT "FIRMWARE_NAME:Marlin V1; Sprinter/grbl mashup for gen6 FIRMWARE_URL:" FIRMWARE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) " UUID:" MACHINE_UUID "\n" + #define MSG_COUNT_X " Licznik X: " #define MSG_ERR_KILLED "Drukarka zatrzymana. Wywolano kill()" #define MSG_ERR_STOPPED "Drukarka zatrzymana z powodu bledu. Usun problem i zrestartuj drukartke komenda M999. (temperatura zostala zresetowana; ustaw temperature po restarcie)" #define MSG_RESEND "Wyslij ponownie: " @@ -343,9 +435,9 @@ #define MSG_Z_MIN "z_min: " #define MSG_Z_MAX "z_max: " #define MSG_M119_REPORT "Zgloszenie statusu wylacznikow krancowych" - #define MSG_ENDSTOP_HIT "WYZWOLONY" - #define MSG_ENDSTOP_OPEN "otwarty" - #define MSG_HOTEND_OFFSET "Hotend offsets:" + #define MSG_ENDSTOP_HIT "Wyzwolony" + #define MSG_ENDSTOP_OPEN "Otwarty" + #define MSG_HOTEND_OFFSET "Offsety dysz:" #define MSG_SD_CANT_OPEN_SUBDIR "Nie mozna otworzyc podkatalogu" #define MSG_SD_INIT_FAIL "Blad inicjalizacji karty SD" @@ -360,111 +452,142 @@ #define MSG_SD_WRITE_TO_FILE "Zapisywanie do pliku: " #define MSG_SD_PRINTING_BYTE "Drukowanie z karty SD, bajt " #define MSG_SD_NOT_PRINTING "Nie trwa drukowanie z karty SD" - #define MSG_SD_ERR_WRITE_TO_FILE "blad podczas zapisu do pliku" + #define MSG_SD_ERR_WRITE_TO_FILE "Wystapil blad podczas zapisu do pliku" #define MSG_SD_CANT_ENTER_SUBDIR "Nie mozna odczytac podkatalogu: " #define MSG_STEPPER_TOO_HIGH "Za duza czestotliwosc krokow: " #define MSG_ENDSTOPS_HIT "Wylacznik krancowy zostal wyzwolony na pozycji: " #define MSG_ERR_COLD_EXTRUDE_STOP " uniemozliwiono zimna ekstruzje" #define MSG_ERR_LONG_EXTRUDE_STOP " uniemozliwiono zbyt dluga ekstruzje" + #define MSG_BABYSTEPPING_X "Babystepping w osi X" + #define MSG_BABYSTEPPING_Y "Babystepping w osi Y" + #define MSG_BABYSTEPPING_Z "Babystepping w osi Z" + #define MSG_SERIAL_ERROR_MENU_STRUCTURE "Error in menu structure" #endif #if LANGUAGE_CHOICE == 3 - #define WELCOME_MSG MACHINE_NAME " Pret." +// LCD Menu Messages +// Please note these are limited to 17 characters! + + #define WELCOME_MSG MACHINE_NAME " prete." #define MSG_SD_INSERTED "Carte inseree" #define MSG_SD_REMOVED "Carte retiree" - #define MSG_MAIN " Principal \003" - #define MSG_AUTOSTART " Demarrage auto." - #define MSG_DISABLE_STEPPERS " Desactiver moteurs" - #define MSG_AUTO_HOME " Home auto." - #define MSG_SET_ORIGIN " Regler origine" - #define MSG_PREHEAT_PLA " Prechauffage PLA" - #define MSG_PREHEAT_PLA_SETTINGS " Regl. prechauffe PLA" - #define MSG_PREHEAT_ABS " Prechauffage ABS" - #define MSG_PREHEAT_ABS_SETTINGS " Regl. prechauffe ABS" - #define MSG_COOLDOWN " Refroidissement" - #define MSG_SWITCH_PS_ON "Allumer alimentation" - #define MSG_SWITCH_PS_OFF "Eteindre alimentation" - #define MSG_EXTRUDE " Extrusion" - #define MSG_RETRACT " Retractation" + #define MSG_MAIN "Menu principal" + #define MSG_AUTOSTART "Demarrage auto" + #define MSG_DISABLE_STEPPERS "Arreter moteurs" + #define MSG_AUTO_HOME "Home auto." + #define MSG_SET_ORIGIN "Regler origine" #define MSG_PREHEAT_PLA " Prechauffage PLA" - #define MSG_PREHEAT_ABS " Prechauffage ABS" - #define MSG_MOVE_AXIS " Deplacer axe \x7E" - #define MSG_SPEED " Vitesse:" - #define MSG_NOZZLE " \002Buse:" - #define MSG_NOZZLE1 " \002Buse2:" - #define MSG_NOZZLE2 " \002Buse3:" - #define MSG_BED " \002Lit:" - #define MSG_FAN_SPEED " Vitesse ventilateur:" - #define MSG_FLOW " Flux:" - #define MSG_CONTROL " Controle \003" - #define MSG_MIN " \002 Min:" - #define MSG_MAX " \002 Max:" - #define MSG_FACTOR " \002 Facteur:" - #define MSG_AUTOTEMP " Temp. Auto.:" + #define MSG_PREHEAT_PLA0 "Prechauff. PLA 1" + #define MSG_PREHEAT_PLA1 "Prechauff. PLA 2" + #define MSG_PREHEAT_PLA2 "Prechauff. PLA 3" + #define MSG_PREHEAT_PLA012 "Prech. PLA Tout" + #define MSG_PREHEAT_PLA_BEDONLY "Prech. PLA Plateau" + #define MSG_PREHEAT_PLA_SETTINGS "Regl. prech. PLA" + #define MSG_PREHEAT_ABS "Prechauffage ABS" + #define MSG_PREHEAT_ABS0 "Prechauff. ABS 1" + #define MSG_PREHEAT_ABS1 "Prechauff. ABS 2" + #define MSG_PREHEAT_ABS2 "Prechauff. ABS 3" + #define MSG_PREHEAT_ABS012 "Prech. ABS Tout" + #define MSG_PREHEAT_ABS_BEDONLY "Prech. ABS Plateau" + #define MSG_PREHEAT_ABS_SETTINGS "Regl. prech. ABS" + #define MSG_COOLDOWN "Refroidir" + #define MSG_SWITCH_PS_ON "Allumer alim." + #define MSG_SWITCH_PS_OFF "Eteindre alim." + #define MSG_EXTRUDE "Extrusion" + #define MSG_RETRACT "Retraction" + #define MSG_PREHEAT_PLA "Prechauffage PLA" + #define MSG_PREHEAT_ABS "Prechauffage ABS" + #define MSG_MOVE_AXIS "Deplacer un axe" + #define MSG_MOVE_X "Move X" + #define MSG_MOVE_Y "Move Y" + #define MSG_MOVE_Z "Move Z" + #define MSG_MOVE_E "Extruder" + #define MSG_MOVE_E1 "Extruder2" + #define MSG_MOVE_E2 "Extruder3" + #define MSG_MOVE_01MM "Move 0.1mm" + #define MSG_MOVE_1MM "Move 1mm" + #define MSG_MOVE_10MM "Move 10mm" + #define MSG_SPEED " Vitesse" + #define MSG_NOZZLE "Buse" + #define MSG_NOZZLE1 "Buse2" + #define MSG_NOZZLE2 "Buse3" + #define MSG_BED "Plateau" + #define MSG_FAN_SPEED "Vite. ventilateur" + #define MSG_FLOW "Flux" + #define MSG_FLOW0 "Flux 0" + #define MSG_FLOW1 "Flux 1" + #define MSG_FLOW2 "Flux 2" + #define MSG_CONTROL "Controler" + #define MSG_MIN " \002 Min" + #define MSG_MAX " \002 Max" + #define MSG_FACTOR " \002 Facteur" + #define MSG_AUTOTEMP "Temp. Auto." #define MSG_ON "Marche " #define MSG_OFF "Arret" - #define MSG_PID_P " PID-P: " - #define MSG_PID_I " PID-I: " - #define MSG_PID_D " PID-D: " - #define MSG_PID_C " PID-C: " - #define MSG_ACC " Acc:" + #define MSG_PID_P "PID-P" + #define MSG_PID_I "PID-I" + #define MSG_PID_D "PID-D" + #define MSG_PID_C "PID-C" + #define MSG_ACC "Accel" #define MSG_VXY_JERK "Vxy-jerk" #define MSG_VZ_JERK "Vz-jerk" #define MSG_VE_JERK "Ve-jerk" - #define MSG_VMAX " Vmax " - #define MSG_X "x:" - #define MSG_Y "y:" - #define MSG_Z "z:" - #define MSG_E "e:" - #define MSG_VMIN " Vmin:" - #define MSG_VTRAV_MIN " Vdepl min:" - #define MSG_AMAX " Amax " - #define MSG_A_RETRACT " A-retract:" - #define MSG_XSTEPS " Xpas/mm:" - #define MSG_YSTEPS " Ypas/mm:" - #define MSG_ZSTEPS " Zpas/mm:" - #define MSG_ESTEPS " Epas/mm:" - #define MSG_MAIN_WIDE " Principal \003" - #define MSG_RECTRACT "Rectracter" + #define MSG_VMAX "Vmax" + #define MSG_X "x" + #define MSG_Y "y" + #define MSG_Z "z" + #define MSG_E "e" + #define MSG_VMIN "Vmin" + #define MSG_VTRAV_MIN "Vdepl min" + #define MSG_AMAX "Amax " + #define MSG_A_RETRACT "A-retract" + #define MSG_XSTEPS "Xpas/mm" + #define MSG_YSTEPS "Ypas/mm" + #define MSG_ZSTEPS "Zpas/mm" + #define MSG_ESTEPS "Epas/mm" #define MSG_TEMPERATURE "Temperature" #define MSG_MOTION "Mouvement" - #define MSG_CONTRAST "LCD contrast" - #define MSG_STORE_EPROM " Sauvegarder memoire" - #define MSG_LOAD_EPROM " Lire memoire" - #define MSG_RESTORE_FAILSAFE " Restaurer memoire" - #define MSG_REFRESH "\004Actualiser" - #define MSG_WATCH " Surveiller \003" - #define MSG_PREPARE " Preparer \x7E" - #define MSG_PREPARE_ALT " Prepare \003" - #define MSG_CONTROL_ARROW " Controle \x7E" - #define MSG_RETRACT_ARROW " Retracter \x7E" - #define MSG_TUNE " Regler \x7E" - #define MSG_PAUSE_PRINT " Pause impression \x7E" - #define MSG_RESUME_PRINT " Reprendre impression \x7E" - #define MSG_STOP_PRINT " Arreter impression \x7E" - #define MSG_CARD_MENU " Menu carte \x7E" - #define MSG_NO_CARD " Pas de carte" + #define MSG_CONTRAST "Contraste LCD" + #define MSG_STORE_EPROM "Sauver config" + #define MSG_LOAD_EPROM "Lire config" + #define MSG_RESTORE_FAILSAFE "Restaurer defauts" + #define MSG_REFRESH "Actualiser" + #define MSG_WATCH "Surveiller" + #define MSG_PREPARE "Preparer" + #define MSG_TUNE "Regler" + #define MSG_PAUSE_PRINT "Interrompre impr." + #define MSG_RESUME_PRINT "Reprendre impr." + #define MSG_STOP_PRINT "Arreter impr." + #define MSG_CARD_MENU "Impr. depuis SD" + #define MSG_NO_CARD "Pas de carte" #define MSG_DWELL "Repos..." - #define MSG_USERWAIT "Attente de l'utilisateur..." - #define MSG_RESUMING "Reprise de l'impression" + #define MSG_USERWAIT "Atten. de l'util." + #define MSG_RESUMING "Repri. de l'impr." #define MSG_NO_MOVE "Aucun mouvement." - #define MSG_PART_RELEASE "Relache partielle" - #define MSG_KILLED "TUE." + #define MSG_KILLED "MORT." #define MSG_STOPPED "STOPPE." #define MSG_STEPPER_RELEASED "RELACHE." - #define MSG_CONTROL_RETRACT " Retractation mm:" - #define MSG_CONTROL_RETRACTF " Retractation F:" - #define MSG_CONTROL_RETRACT_ZLIFT " Hop mm:" - #define MSG_CONTROL_RETRACT_RECOVER " UnRet +mm:" - #define MSG_CONTROL_RETRACT_RECOVERF " UnRet F:" - #define MSG_AUTORETRACT " Retract. Auto.:" - #define MSG_FILAMENTCHANGE "Change filament" - #define MSG_INIT_SDCARD "Init. la carte SD" - #define MSG_CNG_SDCARD "Changer de carte SD" + #define MSG_CONTROL_RETRACT "Retraction mm" + #define MSG_CONTROL_RETRACTF "Retraction V" + #define MSG_CONTROL_RETRACT_ZLIFT "Hop mm" + #define MSG_CONTROL_RETRACT_RECOVER "UnRet +mm" + #define MSG_CONTROL_RETRACT_RECOVERF "UnRet V" + #define MSG_AUTORETRACT "Retract. Auto." + #define MSG_FILAMENTCHANGE "Changer filament" + #define MSG_INIT_SDCARD "Init. la carte SD" + #define MSG_CNG_SDCARD "Changer de carte" + #define MSG_ZPROBE_OUT "Z sonde exte. lit" + #define MSG_POSITION_UNKNOWN "Rev. dans XY av.Z" + #define MSG_ZPROBE_ZOFFSET "Offset Z" + #define MSG_BABYSTEP_X "Babystep X" + #define MSG_BABYSTEP_Y "Babystep Y" + #define MSG_BABYSTEP_Z "Babystep Z" + #define MSG_ENDSTOP_ABORT "Butee abandon" + #define MSG_CONTRAST "Contrast" // Serial Console Messages @@ -474,7 +597,6 @@ #define MSG_BROWNOUT_RESET " RAZ defaut alim." #define MSG_WATCHDOG_RESET " RAZ Watchdog" #define MSG_SOFTWARE_RESET " RAZ logicielle" - #define MSG_MARLIN "Marlin " #define MSG_AUTHOR " | Auteur: " #define MSG_CONFIGURATION_VER " Derniere MaJ: " #define MSG_FREE_MEMORY " Memoire libre: " @@ -490,14 +612,16 @@ #define MSG_END_FILE_LIST "Fin de la liste de fichiers" #define MSG_M104_INVALID_EXTRUDER "M104 Extruder invalide" #define MSG_M105_INVALID_EXTRUDER "M105 Extruder invalide" + #define MSG_M200_INVALID_EXTRUDER "M200 Extruder invalide" #define MSG_M218_INVALID_EXTRUDER "M218 Extruder invalide" + #define MSG_M221_INVALID_EXTRUDER "M221 Extruder invalide" #define MSG_ERR_NO_THERMISTORS "Pas de thermistor, pas de temperature" #define MSG_M109_INVALID_EXTRUDER "M109 Extruder invalide " #define MSG_HEATING "En chauffe..." #define MSG_HEATING_COMPLETE "Chauffe terminee." #define MSG_BED_HEATING "Chauffe du lit." #define MSG_BED_DONE "Chauffe du lit terminee." - #define MSG_M115_REPORT "FIRMWARE_NAME:Marlin V1; Sprinter/grbl mashup for gen6 FIRMWARE_URL:" FIRMWARE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) "\n" + #define MSG_M115_REPORT "FIRMWARE_NAME:Marlin V1; Sprinter/grbl mashup for gen6 FIRMWARE_URL:" FIRMWARE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) " UUID:" MACHINE_UUID "\n" #define MSG_COUNT_X " Compteur X: " #define MSG_ERR_KILLED "Impression arretee. kill() appelee!" #define MSG_ERR_STOPPED "Impression arretee a cause d'erreurs. Corriger les erreurs et utiliser M999 pour la reprendre. (Temperature remise a zero. Reactivez la apres redemarrage)" @@ -536,13 +660,18 @@ #define MSG_ENDSTOPS_HIT "Fin de course atteint: " #define MSG_ERR_COLD_EXTRUDE_STOP " Extrusion a froid evitee" #define MSG_ERR_LONG_EXTRUDE_STOP " Extrusion longue evitee" - + #define MSG_BABYSTEPPING_X "Babystepping X" + #define MSG_BABYSTEPPING_Y "Babystepping Y" + #define MSG_BABYSTEPPING_Z "Babystepping Z" + #define MSG_SERIAL_ERROR_MENU_STRUCTURE "Error in menu structure" + #endif #if LANGUAGE_CHOICE == 4 // LCD Menu Messages +// Please note these are limited to 17 characters! #define WELCOME_MSG MACHINE_NAME " Bereit." @@ -550,19 +679,38 @@ #define MSG_SD_REMOVED "SDKarte entfernt" #define MSG_MAIN "Hauptmenü" #define MSG_AUTOSTART "Autostart" - #define MSG_DISABLE_STEPPERS "Stepper abschalten" + #define MSG_DISABLE_STEPPERS "Stepper abschalt." #define MSG_AUTO_HOME "Auto Nullpunkt" #define MSG_SET_ORIGIN "Setze Nullpunkt" #define MSG_PREHEAT_PLA "Vorwärmen PLA" - #define MSG_PREHEAT_PLA_SETTINGS "Vorwärmen PLA Einstellungen" + #define MSG_PREHEAT_PLA0 "Vorwärmen PLA 1" + #define MSG_PREHEAT_PLA1 "Vorwärmen PLA 2" + #define MSG_PREHEAT_PLA2 "Vorwärmen PLA 3" + #define MSG_PREHEAT_PLA012 "Vorw. PLA Alle" + #define MSG_PREHEAT_PLA_BEDONLY "Vorw. PLA Bett" + #define MSG_PREHEAT_PLA_SETTINGS "Vorwärm. PLA Ein." #define MSG_PREHEAT_ABS "Vorwärmen ABS" - #define MSG_PREHEAT_ABS_SETTINGS "Vorwärmen ABS Einstellungen" + #define MSG_PREHEAT_ABS0 "Vorwärmen ABS 1" + #define MSG_PREHEAT_ABS1 "Vorwärmen ABS 2" + #define MSG_PREHEAT_ABS2 "Vorwärmen ABS 3" + #define MSG_PREHEAT_ABS012 "Vorw. ABS Alle" + #define MSG_PREHEAT_ABS_BEDONLY "Vorw. ABS Bett" + #define MSG_PREHEAT_ABS_SETTINGS "Vorwärm. ABS Ein." #define MSG_COOLDOWN "Abkühlen" #define MSG_SWITCH_PS_ON "Switch Power On" #define MSG_SWITCH_PS_OFF "Switch Power Off" #define MSG_EXTRUDE "Extrude" #define MSG_RETRACT "Retract" #define MSG_MOVE_AXIS "Achsen bewegen" + #define MSG_MOVE_X "X bewegen" + #define MSG_MOVE_Y "Y bewegen" + #define MSG_MOVE_Z "Z bewegen" + #define MSG_MOVE_E "Extruder" + #define MSG_MOVE_E1 "Extruder2" + #define MSG_MOVE_E2 "Extruder3" + #define MSG_MOVE_01MM "0.1mm bewegen" + #define MSG_MOVE_1MM "1mm bewegen" + #define MSG_MOVE_10MM "10mm bewegen" #define MSG_SPEED "Geschw" #define MSG_NOZZLE "Düse" #define MSG_NOZZLE1 "Düse2" @@ -570,6 +718,9 @@ #define MSG_BED "Bett" #define MSG_FAN_SPEED "Lüftergeschw." #define MSG_FLOW "Fluss" + #define MSG_FLOW0 "Fluss 0" + #define MSG_FLOW1 "Fluss 1" + #define MSG_FLOW2 "Fluss 2" #define MSG_CONTROL "Einstellungen" #define MSG_MIN "\002 Min" #define MSG_MAX "\002 Max" @@ -615,24 +766,31 @@ #define MSG_STOP_PRINT "Druck stoppen" #define MSG_CARD_MENU "SDKarten Menü" #define MSG_NO_CARD "Keine SDKarte" - #define MSG_DWELL "Warten..." - #define MSG_USERWAIT "Warte auf Nutzer..." + #define MSG_DWELL "Warten..." + #define MSG_USERWAIT "Warte auf Nutzer" #define MSG_RESUMING "Druck fortsetzung" #define MSG_NO_MOVE "Kein Zug." - #define MSG_PART_RELEASE "Stepper tlw frei" #define MSG_KILLED "KILLED" #define MSG_STOPPED "GESTOPPT" #define MSG_STEPPER_RELEASED "Stepper frei" #define MSG_CONTROL_RETRACT "Retract mm" - #define MSG_CONTROL_RETRACTF "Retract F" + #define MSG_CONTROL_RETRACTF "Retract V" #define MSG_CONTROL_RETRACT_ZLIFT "Hop mm" #define MSG_CONTROL_RETRACT_RECOVER "UnRet +mm" - #define MSG_CONTROL_RETRACT_RECOVERF "UnRet F" + #define MSG_CONTROL_RETRACT_RECOVERF "UnRet V" #define MSG_AUTORETRACT "AutoRetr." #define MSG_FILAMENTCHANGE "Filament wechseln" - #define MSG_INIT_SDCARD "Init. SD-Card" + #define MSG_INIT_SDCARD "Init. SD-Card" #define MSG_CNG_SDCARD "Change SD-Card" - + #define MSG_ZPROBE_OUT "Z probe out. bed" + #define MSG_POSITION_UNKNOWN "Home X/Y before Z" + #define MSG_ZPROBE_ZOFFSET "Z Offset" + #define MSG_BABYSTEP_X "Babystep X" + #define MSG_BABYSTEP_Y "Babystep Y" + #define MSG_BABYSTEP_Z "Babystep Z" + #define MSG_ENDSTOP_ABORT "Endstop abort" + #define MSG_CONTRAST "Contrast" + // Serial Console Messages #define MSG_Enqueing "enqueing \"" @@ -641,7 +799,6 @@ #define MSG_BROWNOUT_RESET " Brown out Reset" #define MSG_WATCHDOG_RESET " Watchdog Reset" #define MSG_SOFTWARE_RESET " Software Reset" - #define MSG_MARLIN "Marlin: " #define MSG_AUTHOR " | Author: " #define MSG_CONFIGURATION_VER " Last Updated: " #define MSG_FREE_MEMORY " Free Memory: " @@ -657,14 +814,16 @@ #define MSG_END_FILE_LIST "End file list" #define MSG_M104_INVALID_EXTRUDER "M104 Invalid extruder " #define MSG_M105_INVALID_EXTRUDER "M105 Invalid extruder " + #define MSG_M200_INVALID_EXTRUDER "M200 Invalid extruder " #define MSG_M218_INVALID_EXTRUDER "M218 Invalid extruder " + #define MSG_M221_INVALID_EXTRUDER "M221 Invalid extruder " #define MSG_ERR_NO_THERMISTORS "No thermistors - no temp" #define MSG_M109_INVALID_EXTRUDER "M109 Invalid extruder " #define MSG_HEATING "Heating..." #define MSG_HEATING_COMPLETE "Heating done." #define MSG_BED_HEATING "Bed Heating." #define MSG_BED_DONE "Bed done." - #define MSG_M115_REPORT "FIRMWARE_NAME:Marlin V1; Sprinter/grbl mashup for gen6 FIRMWARE_URL:" FIRMWARE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) "\n" + #define MSG_M115_REPORT "FIRMWARE_NAME:Marlin V1; Sprinter/grbl mashup for gen6 FIRMWARE_URL:" FIRMWARE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) " UUID:" MACHINE_UUID "\n" #define MSG_COUNT_X " Count X:" #define MSG_ERR_KILLED "Printer halted. kill() called !!" #define MSG_ERR_STOPPED "Printer stopped due to errors. Fix the error and use M999 to restart!" @@ -703,6 +862,10 @@ #define MSG_ENDSTOPS_HIT "endstops hit: " #define MSG_ERR_COLD_EXTRUDE_STOP " cold extrusion prevented" #define MSG_ERR_LONG_EXTRUDE_STOP " too long extrusion prevented" + #define MSG_BABYSTEPPING_X "Babystepping X" + #define MSG_BABYSTEPPING_Y "Babystepping Y" + #define MSG_BABYSTEPPING_Z "Babystepping Z" + #define MSG_SERIAL_ERROR_MENU_STRUCTURE "Error in menu structure" #endif @@ -710,24 +873,45 @@ #if LANGUAGE_CHOICE == 5 // LCD Menu Messages - #define WELCOME_MSG MACHINE_NAME "Lista." - #define MSG_SD_INSERTED "Tarjeta SD Colocada" - #define MSG_SD_REMOVED "Tarjeta SD Retirada" - #define MSG_MAIN "Menu Principal" +// Please note these are limited to 17 characters! + + #define WELCOME_MSG MACHINE_NAME " lista." + #define MSG_SD_INSERTED "Tarjeta colocada" + #define MSG_SD_REMOVED "Tarjeta retirada" + #define MSG_MAIN "Menu principal" #define MSG_AUTOSTART " Autostart" - #define MSG_DISABLE_STEPPERS "Apagar Motores" - #define MSG_AUTO_HOME "Llevar al Origen" // "Llevar Ejes al Cero" - #define MSG_SET_ORIGIN "Establecer Cero" + #define MSG_DISABLE_STEPPERS "Apagar motores" + #define MSG_AUTO_HOME "Llevar al origen" + #define MSG_SET_ORIGIN "Establecer cero" #define MSG_PREHEAT_PLA "Precalentar PLA" + #define MSG_PREHEAT_PLA0 "Precalentar PLA 1" + #define MSG_PREHEAT_PLA1 "Precalentar PLA 2" + #define MSG_PREHEAT_PLA2 "Precalentar PLA 3" + #define MSG_PREHEAT_PLA012 "Precal. PLA Todo" + #define MSG_PREHEAT_PLA_BEDONLY "Precal. PLA Base" #define MSG_PREHEAT_PLA_SETTINGS "Ajustar temp. PLA" #define MSG_PREHEAT_ABS "Precalentar ABS" + #define MSG_PREHEAT_ABS0 "Precalentar ABS 1" + #define MSG_PREHEAT_ABS1 "Precalentar ABS 2" + #define MSG_PREHEAT_ABS2 "Precalentar ABS 3" + #define MSG_PREHEAT_ABS012 "Precal. ABS Todo" + #define MSG_PREHEAT_ABS_BEDONLY "Precal. ABS Base" #define MSG_PREHEAT_ABS_SETTINGS "Ajustar temp. ABS" #define MSG_COOLDOWN "Enfriar" #define MSG_SWITCH_PS_ON "Switch Power On" #define MSG_SWITCH_PS_OFF "Switch Power Off" #define MSG_EXTRUDE "Extruir" #define MSG_RETRACT "Retraer" - #define MSG_MOVE_AXIS "Mover Ejes" + #define MSG_MOVE_AXIS "Mover ejes" + #define MSG_MOVE_X "Mover X" + #define MSG_MOVE_Y "Mover Y" + #define MSG_MOVE_Z "Mover Z" + #define MSG_MOVE_E "Extrusor" + #define MSG_MOVE_E1 "Extrusor2" + #define MSG_MOVE_E2 "Extrusor3" + #define MSG_MOVE_01MM "Mover 0.1mm" + #define MSG_MOVE_1MM "Mover 1mm" + #define MSG_MOVE_10MM "Mover 10mm" #define MSG_SPEED "Velocidad" #define MSG_NOZZLE "Nozzle" #define MSG_NOZZLE1 "Nozzle2" @@ -735,6 +919,9 @@ #define MSG_BED "Base" #define MSG_FAN_SPEED "Ventilador" #define MSG_FLOW "Flujo" + #define MSG_FLOW0 "Flujo 0" + #define MSG_FLOW1 "Flujo 1" + #define MSG_FLOW2 "Flujo 2" #define MSG_CONTROL "Control" #define MSG_MIN "\002 Min" #define MSG_MAX "\002 Max" @@ -766,43 +953,50 @@ #define MSG_RECTRACT "Retraer" #define MSG_TEMPERATURE "Temperatura" #define MSG_MOTION "Movimiento" - #define MSG_STORE_EPROM "Guardar Memoria" - #define MSG_LOAD_EPROM "Cargar Memoria" - #define MSG_RESTORE_FAILSAFE "Rest. de emergencia" + #define MSG_STORE_EPROM "Guardar memoria" + #define MSG_LOAD_EPROM "Cargar memoria" + #define MSG_RESTORE_FAILSAFE "Rest. de emergen." #define MSG_REFRESH "Volver a cargar" #define MSG_WATCH "Monitorizar" #define MSG_PREPARE "Preparar" #define MSG_TUNE "Ajustar" - #define MSG_PAUSE_PRINT "Pausar Impresion" - #define MSG_RESUME_PRINT "Reanudar Impresion" - #define MSG_STOP_PRINT "Detener Impresion" + #define MSG_PAUSE_PRINT "Pausar impresion" + #define MSG_RESUME_PRINT "Reanudar impres." + #define MSG_STOP_PRINT "Detener impresion" #define MSG_CARD_MENU "Menu de SD" - #define MSG_NO_CARD "No hay Tarjeta SD" + #define MSG_NO_CARD "No hay tarjeta SD" #define MSG_DWELL "Reposo..." - #define MSG_USERWAIT "Esperando Ordenes..." - #define MSG_RESUMING "Resumiendo Impresion" + #define MSG_USERWAIT "Esperando ordenes" + #define MSG_RESUMING "Resumiendo impre." #define MSG_NO_MOVE "Sin movimiento" - #define MSG_KILLED "PARADA DE EMERGENCIA. " - #define MSG_STOPPED "PARADA." + #define MSG_KILLED "PARADA DE EMERG." + #define MSG_STOPPED "PARADA" #define MSG_CONTROL_RETRACT "Retraer mm" - #define MSG_CONTROL_RETRACTF "Retraer F" + #define MSG_CONTROL_RETRACTF "Retraer V" #define MSG_CONTROL_RETRACT_ZLIFT "Levantar mm" #define MSG_CONTROL_RETRACT_RECOVER "DesRet +mm" - #define MSG_CONTROL_RETRACT_RECOVERF "DesRet F" + #define MSG_CONTROL_RETRACT_RECOVERF "DesRet V" #define MSG_AUTORETRACT "AutoRetr." - #define MSG_FILAMENTCHANGE "Change filament" - #define MSG_INIT_SDCARD "Iniciando. Tarjeta-SD" - #define MSG_CNG_SDCARD "Cambiar Tarjeta-SD" + #define MSG_FILAMENTCHANGE "Cambiar filamento" + #define MSG_INIT_SDCARD "Iniciando tarjeta" + #define MSG_CNG_SDCARD "Cambiar tarjeta" #define MSG_RECTRACT_WIDE "Retraer" #define MSG_TEMPERATURE_WIDE "Temperatura" #define MSG_TEMPERATURE_RTN "Temperatura" - #define MSG_MAIN_WIDE "Menu Principal" + #define MSG_MAIN_WIDE "Menu principal" #define MSG_MOTION_WIDE "Movimiento" #define MSG_PREPARE_ALT "Preparar" #define MSG_CONTROL_ARROW "Control" #define MSG_RETRACT_ARROW "Retraer" - #define MSG_PART_RELEASE "Desacople Parcial" #define MSG_STEPPER_RELEASED "Desacoplada." + #define MSG_ZPROBE_OUT "Z probe out. bed" + #define MSG_POSITION_UNKNOWN "Home X/Y before Z" + #define MSG_ZPROBE_ZOFFSET "Z Offset" + #define MSG_BABYSTEP_X "Babystep X" + #define MSG_BABYSTEP_Y "Babystep Y" + #define MSG_BABYSTEP_Z "Babystep Z" + #define MSG_ENDSTOP_ABORT "Endstop abort" + #define MSG_CONTRAST "Contrast" // Serial Console Messages @@ -812,7 +1006,6 @@ #define MSG_BROWNOUT_RESET " Reset por Voltaje Incorrecto" #define MSG_WATCHDOG_RESET " Reset por Bloqueo" #define MSG_SOFTWARE_RESET " Reset por Software" - #define MSG_MARLIN "Marlin " #define MSG_AUTHOR " | Autor: " #define MSG_CONFIGURATION_VER " Ultima actualizacion: " #define MSG_FREE_MEMORY " Memoria libre: " @@ -828,17 +1021,19 @@ #define MSG_END_FILE_LIST "Fin de la lista de archivos" #define MSG_M104_INVALID_EXTRUDER "M104 Extrusor Invalido " #define MSG_M105_INVALID_EXTRUDER "M105 Extrusor Invalido " + #define MSG_M200_INVALID_EXTRUDER "M200 Extrusor Invalido " #define MSG_M218_INVALID_EXTRUDER "M218 Extrusor Invalido " + #define MSG_M221_INVALID_EXTRUDER "M221 Extrusor Invalido " #define MSG_ERR_NO_THERMISTORS "No hay termistores - no temp" #define MSG_M109_INVALID_EXTRUDER "M109 Extrusor Invalido " #define MSG_HEATING "Calentando..." #define MSG_HEATING_COMPLETE "Calentamiento Hecho." #define MSG_BED_HEATING "Calentando la base." #define MSG_BED_DONE "Base Caliente." - #define MSG_M115_REPORT "FIRMWARE_NAME:Marlin V1; Sprinter/grbl mashup for gen6 FIRMWARE_URL:" FIRMWARE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) "\n" + #define MSG_M115_REPORT "FIRMWARE_NAME:Marlin V1; Sprinter/grbl mashup for gen6 FIRMWARE_URL:" FIRMWARE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) " UUID:" MACHINE_UUID "\n" #define MSG_COUNT_X " Cuenta X:" #define MSG_ERR_KILLED "¡¡Impresora Parada con kill()!!" - #define MSG_ERR_STOPPED "¡Impresora parada por errores. Arregle el error y use M999 Para reiniciar!. (La temperatura se reestablece. Ajustela antes de continuar)" + #define MSG_ERR_STOPPED "¡Impresora parada por errores. Arregle el error y use M999 Para reiniciar!. (La temperatura se reestablece. Ajustela despues de continuar)" #define MSG_RESEND "Reenviar:" #define MSG_UNKNOWN_COMMAND "Comando Desconocido:\"" #define MSG_ACTIVE_EXTRUDER "Extrusor Activo: " @@ -873,97 +1068,133 @@ #define MSG_ENDSTOPS_HIT "Se ha tocado el fin de carril: " #define MSG_ERR_COLD_EXTRUDE_STOP " extrusion fria evitada" #define MSG_ERR_LONG_EXTRUDE_STOP " extrusion demasiado larga evitada" + #define MSG_BABYSTEPPING_X "Babystepping X" + #define MSG_BABYSTEPPING_Y "Babystepping Y" + #define MSG_BABYSTEPPING_Z "Babystepping Z" + #define MSG_SERIAL_ERROR_MENU_STRUCTURE "Error in menu structure" #endif #if LANGUAGE_CHOICE == 6 - // LCD Menu Messages - #define WELCOME_MSG MACHINE_NAME " Готов" + +// LCD Menu Messages +// Please note these are limited to 17 characters! + + #define WELCOME_MSG MACHINE_NAME "Готов." #define MSG_SD_INSERTED "Карта вставлена" #define MSG_SD_REMOVED "Карта извлечена" - #define MSG_MAIN " Меню \003" - #define MSG_AUTOSTART " Автостарт " - #define MSG_DISABLE_STEPPERS " Выключить двигатели" - #define MSG_AUTO_HOME " Парковка " - #define MSG_SET_ORIGIN " Запомнить ноль " - #define MSG_PREHEAT_PLA " Преднагрев PLA " - #define MSG_PREHEAT_PLA_SETTINGS " Настр. преднагр.PLA" - #define MSG_PREHEAT_ABS " Преднагрев ABS " - #define MSG_PREHEAT_ABS_SETTINGS " Настр. преднагр.ABS" - #define MSG_COOLDOWN " Охлаждение " + #define MSG_MAIN "Меню \003" + #define MSG_AUTOSTART "Автостарт" + #define MSG_DISABLE_STEPPERS "Выкл. двигатели" + #define MSG_AUTO_HOME "Парковка" + #define MSG_SET_ORIGIN "Запомнить ноль" + #define MSG_PREHEAT_PLA "Преднагрев PLA" + #define MSG_PREHEAT_PLA0 "Преднагрев PLA0" + #define MSG_PREHEAT_PLA1 "Преднагрев PLA1" + #define MSG_PREHEAT_PLA2 "Преднагрев PLA2" + #define MSG_PREHEAT_PLA012 "Преднаг. PLA все" + #define MSG_PREHEAT_PLA_BEDONLY "Пред. PLA Кровать" + #define MSG_PREHEAT_PLA_SETTINGS "Настройки PLA" + #define MSG_PREHEAT_ABS "Преднагрев ABS" + #define MSG_PREHEAT_ABS0 "Преднагрев ABS0" + #define MSG_PREHEAT_ABS1 "Преднагрев ABS1" + #define MSG_PREHEAT_ABS2 "Преднагрев ABS2" + #define MSG_PREHEAT_ABS012 "Преднаг. ABS все " + #define MSG_PREHEAT_ABS_BEDONLY "Пред. ABS Кровать" + #define MSG_PREHEAT_ABS_SETTINGS "Настройки ABS" + #define MSG_COOLDOWN "Охлаждение" #define MSG_SWITCH_PS_ON "Switch Power On" #define MSG_SWITCH_PS_OFF "Switch Power Off" - #define MSG_EXTRUDE " Экструзия " - #define MSG_RETRACT " Откат" - #define MSG_MOVE_AXIS " Движение по осям \x7E" - #define MSG_SPEED " Скорость:" - #define MSG_NOZZLE " \002 Фильера:" - #define MSG_NOZZLE1 " \002 Фильера2:" - #define MSG_NOZZLE2 " \002 Фильера3:" - #define MSG_BED " \002 Кровать:" - #define MSG_FAN_SPEED " Куллер:" - #define MSG_FLOW " Поток:" - #define MSG_CONTROL " Настройки \003" - #define MSG_MIN " \002 Минимум:" - #define MSG_MAX " \002 Максимум:" - #define MSG_FACTOR " \002 Фактор:" - #define MSG_AUTOTEMP " Autotemp:" + #define MSG_EXTRUDE "Экструзия" + #define MSG_RETRACT "Откат" + #define MSG_MOVE_AXIS "Движение по осям" + #define MSG_MOVE_X "Move X" + #define MSG_MOVE_Y "Move Y" + #define MSG_MOVE_Z "Move Z" + #define MSG_MOVE_E "Extruder" + #define MSG_MOVE_E1 "Extruder2" + #define MSG_MOVE_E2 "Extruder3" + #define MSG_MOVE_01MM "Move 0.1mm" + #define MSG_MOVE_1MM "Move 1mm" + #define MSG_MOVE_10MM "Move 10mm" + #define MSG_SPEED "Скорость:" + #define MSG_NOZZLE "\002 Фильера:" + #define MSG_NOZZLE1 "\002 Фильера2:" + #define MSG_NOZZLE2 "\002 Фильера3:" + #define MSG_BED "\002 Кровать:" + #define MSG_FAN_SPEED "Куллер:" + #define MSG_FLOW "Поток:" + #define MSG_FLOW0 " Поток0:" + #define MSG_FLOW1 " Поток1:" + #define MSG_FLOW2 " Поток2:" + #define MSG_CONTROL "Настройки \003" + #define MSG_MIN "\002 Минимум:" + #define MSG_MAX "\002 Максимум:" + #define MSG_FACTOR "\002 Фактор:" + #define MSG_AUTOTEMP "Autotemp:" #define MSG_ON "Вкл. " #define MSG_OFF "Выкл. " - #define MSG_PID_P " PID-P: " - #define MSG_PID_I " PID-I: " - #define MSG_PID_D " PID-D: " - #define MSG_PID_C " PID-C: " - #define MSG_ACC " Acc:" - #define MSG_VXY_JERK " Vxy-jerk: " + #define MSG_PID_P "PID-P: " + #define MSG_PID_I "PID-I: " + #define MSG_PID_D "PID-D: " + #define MSG_PID_C "PID-C: " + #define MSG_ACC "Acc:" + #define MSG_VXY_JERK "Vxy-jerk: " #define MSG_VZ_JERK "Vz-jerk" #define MSG_VE_JERK "Ve-jerk" - #define MSG_VMAX " Vmax " + #define MSG_VMAX "Vmax " #define MSG_X "x:" #define MSG_Y "y:" #define MSG_Z "z:" #define MSG_E "e:" - #define MSG_VMIN " Vmin:" - #define MSG_VTRAV_MIN " VTrav min:" - #define MSG_AMAX " Amax " - #define MSG_A_RETRACT " A-retract:" - #define MSG_XSTEPS " X шаг/mm:" - #define MSG_YSTEPS " Y шаг/mm:" - #define MSG_ZSTEPS " Z шаг/mm:" - #define MSG_ESTEPS " E шаг/mm:" - #define MSG_RECTRACT " Откат подачи \x7E" - #define MSG_TEMPERATURE " Температура \x7E" - #define MSG_MOTION " Скорости \x7E" - #define MSG_CONTRAST "LCD contrast" - #define MSG_STORE_EPROM " Сохранить настройки" - #define MSG_LOAD_EPROM " Загрузить настройки" - #define MSG_RESTORE_FAILSAFE " Сброс настроек " - #define MSG_REFRESH "\004Обновить " - #define MSG_WATCH " Обзор \003" - #define MSG_PREPARE " Действия \x7E" - #define MSG_TUNE " Настройки \x7E" - #define MSG_PAUSE_PRINT " Пауза печати \x7E" - #define MSG_RESUME_PRINT " Продолжить печать \x7E" - #define MSG_STOP_PRINT " Остановить печать \x7E" - #define MSG_CARD_MENU " Меню карты \x7E" - #define MSG_NO_CARD " Нет карты" + #define MSG_VMIN "Vmin:" + #define MSG_VTRAV_MIN "VTrav min:" + #define MSG_AMAX "Amax " + #define MSG_A_RETRACT "A-retract:" + #define MSG_XSTEPS "X шаг/mm:" + #define MSG_YSTEPS "Y шаг/mm:" + #define MSG_ZSTEPS "Z шаг/mm:" + #define MSG_ESTEPS "E шаг/mm:" + #define MSG_RECTRACT "Откат подачи \x7E" + #define MSG_TEMPERATURE "Температура \x7E" + #define MSG_MOTION "Скорости \x7E" + #define MSG_CONTRAST "LCD contrast" + #define MSG_STORE_EPROM "Сохранить в EPROM" + #define MSG_LOAD_EPROM "Загруз. из EPROM" + #define MSG_RESTORE_FAILSAFE "Сброс настроек" + #define MSG_REFRESH "\004Обновить" + #define MSG_WATCH "Обзор \003" + #define MSG_PREPARE "Действия \x7E" + #define MSG_TUNE "Настройки \x7E" + #define MSG_PAUSE_PRINT "Продолжить печать" + #define MSG_RESUME_PRINT "возобн. печать" + #define MSG_STOP_PRINT "Остановить печать" + #define MSG_CARD_MENU "Меню карты \x7E" + #define MSG_NO_CARD "Нет карты" #define MSG_DWELL "Сон..." - #define MSG_USERWAIT "Нажмите для продолж." - #define MSG_RESUMING "Resuming print" - #define MSG_NO_MOVE "Нет движения. " - #define MSG_PART_RELEASE " Извлечение принта " - #define MSG_KILLED "УБИТО. " - #define MSG_STOPPED "ОСТАНОВЛЕНО. " - #define MSG_CONTROL_RETRACT " Откат mm:" - #define MSG_CONTROL_RETRACTF " Откат F:" - #define MSG_CONTROL_RETRACT_ZLIFT " Прыжок mm:" - #define MSG_CONTROL_RETRACT_RECOVER " Возврат +mm:" - #define MSG_CONTROL_RETRACT_RECOVERF " Возврат F:" - #define MSG_AUTORETRACT " АвтоОткат:" - #define MSG_FILAMENTCHANGE "Change filament" - #define MSG_INIT_SDCARD "Init. SD-Card" - #define MSG_CNG_SDCARD "Change SD-Card" + #define MSG_USERWAIT "Ожиданиие" + #define MSG_RESUMING "Resuming print" + #define MSG_NO_MOVE "Нет движения." + #define MSG_KILLED "УБИТО." + #define MSG_STOPPED "ОСТАНОВЛЕНО." + #define MSG_CONTROL_RETRACT "Откат mm:" + #define MSG_CONTROL_RETRACTF "Откат V:" + #define MSG_CONTROL_RETRACT_ZLIFT "Прыжок mm:" + #define MSG_CONTROL_RETRACT_RECOVER "Возврат +mm:" + #define MSG_CONTROL_RETRACT_RECOVERF "Возврат V:" + #define MSG_AUTORETRACT "АвтоОткат:" + #define MSG_FILAMENTCHANGE "Change filament" + #define MSG_INIT_SDCARD "Init. SD-Card" + #define MSG_CNG_SDCARD "Change SD-Card" + #define MSG_ZPROBE_OUT "Z probe out. bed" + #define MSG_POSITION_UNKNOWN "Home X/Y before Z" + #define MSG_ZPROBE_ZOFFSET "Z Offset" + #define MSG_BABYSTEP_X "Babystep X" + #define MSG_BABYSTEP_Y "Babystep Y" + #define MSG_BABYSTEP_Z "Babystep Z" + #define MSG_ENDSTOP_ABORT "Endstop abort" + #define MSG_CONTRAST "Contrast" // Serial Console Messages @@ -973,7 +1204,6 @@ #define MSG_BROWNOUT_RESET " Brown out сброс" #define MSG_WATCHDOG_RESET " Watchdog сброс" #define MSG_SOFTWARE_RESET " программный сброс" - #define MSG_MARLIN "Marlin " #define MSG_AUTHOR " | Автор: " #define MSG_CONFIGURATION_VER " Последнее обновление: " #define MSG_FREE_MEMORY " Памяти свободно: " @@ -989,14 +1219,16 @@ #define MSG_END_FILE_LIST "Конец списка файлов" #define MSG_M104_INVALID_EXTRUDER "M104 ошибка экструдера " #define MSG_M105_INVALID_EXTRUDER "M105 ошибка экструдера " + #define MSG_M200_INVALID_EXTRUDER "M200 ошибка экструдера " #define MSG_M218_INVALID_EXTRUDER "M218 ошибка экструдера " + #define MSG_M221_INVALID_EXTRUDER "M221 ошибка экструдера " #define MSG_ERR_NO_THERMISTORS "Нет термистра - нет температуры" #define MSG_M109_INVALID_EXTRUDER "M109 ошибка экструдера " #define MSG_HEATING "Нагрев... " #define MSG_HEATING_COMPLETE "Наргето. " #define MSG_BED_HEATING "Нагрев стола... " #define MSG_BED_DONE "Стол нагрет. " - #define MSG_M115_REPORT "FIRMWARE_NAME:Marlin V1; Sprinter/grbl mashup for gen6 FIRMWARE_URL:" FIRMWARE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) "\n" + #define MSG_M115_REPORT "FIRMWARE_NAME:Marlin V1; Sprinter/grbl mashup for gen6 FIRMWARE_URL:" FIRMWARE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) " UUID:" MACHINE_UUID "\n" #define MSG_COUNT_X " Count X:" #define MSG_ERR_KILLED "Принтер остановлен. вызов kill() !!" #define MSG_ERR_STOPPED "Ошибка принтера, останов. Устраните неисправность и используйте M999 для перезагрузки!. (Температура недоступна. Проверьте датчики)" @@ -1033,14 +1265,20 @@ #define MSG_ENDSTOPS_HIT "концевик сработал: " #define MSG_ERR_COLD_EXTRUDE_STOP " защита холодной экструзии" #define MSG_ERR_LONG_EXTRUDE_STOP " защита превышения длинны экструзии" + #define MSG_BABYSTEPPING_X "Babystepping X" + #define MSG_BABYSTEPPING_Y "Babystepping Y" + #define MSG_BABYSTEPPING_Z "Babystepping Z" + #define MSG_SERIAL_ERROR_MENU_STRUCTURE "Error in menu structure" #endif #if LANGUAGE_CHOICE == 7 - // LCD Menu Messages - #define WELCOME_MSG MACHINE_NAME " Pronta" +// LCD Menu Messages +// Please note these are limited to 17 characters! + + #define WELCOME_MSG MACHINE_NAME " pronto." #define MSG_SD_INSERTED "SD Card inserita" #define MSG_SD_REMOVED "SD Card rimossa" #define MSG_MAIN "Menu principale" @@ -1049,8 +1287,18 @@ #define MSG_AUTO_HOME "Auto Home" #define MSG_SET_ORIGIN "Imposta Origine" #define MSG_PREHEAT_PLA "Preriscalda PLA" + #define MSG_PREHEAT_PLA0 "Preriscalda PLA 1" + #define MSG_PREHEAT_PLA1 "Preriscalda PLA 2" + #define MSG_PREHEAT_PLA2 "Preriscalda PLA 3" + #define MSG_PREHEAT_PLA012 "Preris. PLA Tutto" + #define MSG_PREHEAT_PLA_BEDONLY "Preri. PLA Piatto" #define MSG_PREHEAT_PLA_SETTINGS "Preris. PLA Conf" #define MSG_PREHEAT_ABS "Preriscalda ABS" + #define MSG_PREHEAT_ABS0 "Preriscalda ABS 1" + #define MSG_PREHEAT_ABS1 "Preriscalda ABS 2" + #define MSG_PREHEAT_ABS2 "Preriscalda ABS 3" + #define MSG_PREHEAT_ABS012 "Preris. ABS Tutto" + #define MSG_PREHEAT_ABS_BEDONLY "Preri. ABS Piatto" #define MSG_PREHEAT_ABS_SETTINGS "Preris. ABS Conf" #define MSG_COOLDOWN "Raffredda" #define MSG_SWITCH_PS_ON "Switch Power On" @@ -1058,6 +1306,15 @@ #define MSG_EXTRUDE "Estrudi" #define MSG_RETRACT "Ritrai" #define MSG_MOVE_AXIS "Muovi Asse" + #define MSG_MOVE_X "Move X" + #define MSG_MOVE_Y "Move Y" + #define MSG_MOVE_Z "Move Z" + #define MSG_MOVE_E "Extruder" + #define MSG_MOVE_E1 "Extruder2" + #define MSG_MOVE_E2 "Extruder3" + #define MSG_MOVE_01MM "Move 0.1mm" + #define MSG_MOVE_1MM "Move 1mm" + #define MSG_MOVE_10MM "Move 10mm" #define MSG_SPEED "Velcità" #define MSG_NOZZLE "Ugello" #define MSG_NOZZLE1 "Ugello2" @@ -1065,6 +1322,9 @@ #define MSG_BED "Piatto" #define MSG_FAN_SPEED "Ventola" #define MSG_FLOW "Flusso" + #define MSG_FLOW0 "Flusso 0" + #define MSG_FLOW1 "Flusso 1" + #define MSG_FLOW2 "Flusso 2" #define MSG_CONTROL "Controllo" #define MSG_MIN " \002 Min:" #define MSG_MAX " \002 Max:" @@ -1116,17 +1376,24 @@ #define MSG_KILLED "UCCISO. " #define MSG_STOPPED "ARRESTATO. " #define MSG_CONTROL_RETRACT "Ritrai mm" - #define MSG_CONTROL_RETRACTF "Ritrai F" + #define MSG_CONTROL_RETRACTF "Ritrai V" #define MSG_CONTROL_RETRACT_ZLIFT "Salta mm" #define MSG_CONTROL_RETRACT_RECOVER "UnRet +mm" - #define MSG_CONTROL_RETRACT_RECOVERF "UnRet F" + #define MSG_CONTROL_RETRACT_RECOVERF "UnRet V" #define MSG_AUTORETRACT "AutoArretramento" - #define MSG_SERIAL_ERROR_MENU_STRUCTURE "Qualcosa non va in MenuStructure." #define MSG_FILAMENTCHANGE "Cambia filamento" #define MSG_INIT_SDCARD "Iniz. SD-Card" #define MSG_CNG_SDCARD "Cambia SD-Card" + #define MSG_ZPROBE_OUT "Z probe out. bed" + #define MSG_POSITION_UNKNOWN "Home X/Y before Z" + #define MSG_ZPROBE_ZOFFSET "Z Offset" + #define MSG_BABYSTEP_X "Babystep X" + #define MSG_BABYSTEP_Y "Babystep Y" + #define MSG_BABYSTEP_Z "Babystep Z" + #define MSG_ENDSTOP_ABORT "Endstop abort" + #define MSG_CONTRAST "Contrast" - // Serial Console Messages +// Serial Console Messages #define MSG_Enqueing "accodamento \"" #define MSG_POWERUP "Accensione" @@ -1134,7 +1401,6 @@ #define MSG_BROWNOUT_RESET " Brown out Reset" #define MSG_WATCHDOG_RESET " Watchdog Reset" #define MSG_SOFTWARE_RESET " Software Reset" - #define MSG_MARLIN "Marlin " #define MSG_AUTHOR " | Autore: " #define MSG_CONFIGURATION_VER " Ultimo Aggiornamento: " #define MSG_FREE_MEMORY " Memoria Libera: " @@ -1150,14 +1416,16 @@ #define MSG_END_FILE_LIST "Fine Lista File" #define MSG_M104_INVALID_EXTRUDER "M104 Estrusore non valido " #define MSG_M105_INVALID_EXTRUDER "M105 Estrusore non valido " + #define MSG_M200_INVALID_EXTRUDER "M200 Estrusore non valido " #define MSG_M218_INVALID_EXTRUDER "M218 Estrusore non valido " + #define MSG_M221_INVALID_EXTRUDER "M221 Estrusore non valido " #define MSG_ERR_NO_THERMISTORS "Nessun Termistore - nessuna temperatura" #define MSG_M109_INVALID_EXTRUDER "M109 Estrusore non valido " #define MSG_HEATING "Riscaldamento..." #define MSG_HEATING_COMPLETE "Stampante Calda." #define MSG_BED_HEATING "Riscaldamento Piatto." #define MSG_BED_DONE "Piatto Pronto." - #define MSG_M115_REPORT "FIRMWARE_NAME:Marlin V1; Sprinter/grbl mashup for gen6 FIRMWARE_URL:" FIRMWARE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) "\n" + #define MSG_M115_REPORT "FIRMWARE_NAME:Marlin V1; Sprinter/grbl mashup for gen6 FIRMWARE_URL:" FIRMWARE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) " UUID:" MACHINE_UUID "\n" #define MSG_COUNT_X " Calcola X: " #define MSG_ERR_KILLED "Stampante Calda. kill() chiamata !!" #define MSG_ERR_STOPPED "Stampante fermata a causa di errori. Risolvi l'errore e usa M999 per ripartire!. (Reset temperatura. Impostala prima di ripartire)" @@ -1196,6 +1464,10 @@ #define MSG_ENDSTOPS_HIT "Raggiunto il fondo carrello: " #define MSG_ERR_COLD_EXTRUDE_STOP " prevenuta estrusione fredda" #define MSG_ERR_LONG_EXTRUDE_STOP " prevenuta estrusione troppo lunga" + #define MSG_BABYSTEPPING_X "Babystepping X" + #define MSG_BABYSTEPPING_Y "Babystepping Y" + #define MSG_BABYSTEPPING_Z "Babystepping Z" + #define MSG_SERIAL_ERROR_MENU_STRUCTURE "Qualcosa non va in MenuStructure." #endif @@ -1203,46 +1475,70 @@ #if LANGUAGE_CHOICE == 8 // LCD Menu Messages - #define WELCOME_MSG MACHINE_NAME " Pronta." - #define MSG_SD_INSERTED "Cartao SD inserido" - #define MSG_SD_REMOVED "Cartao SD removido" - #define MSG_MAIN " Menu Principal \003" - #define MSG_AUTOSTART " Autostart" - #define MSG_DISABLE_STEPPERS " Apagar Motores" - #define MSG_AUTO_HOME " Ir para Origen" - #define MSG_SET_ORIGIN " Estabelecer Origen" - #define MSG_PREHEAT_PLA " pre-aquecer PLA" - #define MSG_PREHEAT_PLA_SETTINGS " pre-aquecer PLA Setting" - #define MSG_PREHEAT_ABS " pre-aquecer ABS" - #define MSG_PREHEAT_ABS_SETTINGS " pre-aquecer ABS Setting" - #define MSG_COOLDOWN " Esfriar" +// Please note these are limited to 17 characters! + + #define WELCOME_MSG MACHINE_NAME " pronto." + #define MSG_SD_INSERTED "Cartao inserido" + #define MSG_SD_REMOVED "Cartao removido" + #define MSG_MAIN " Menu principal \003" + #define MSG_AUTOSTART "Autostart" + #define MSG_DISABLE_STEPPERS " Apagar motores" + #define MSG_AUTO_HOME "Ir para origen" + #define MSG_SET_ORIGIN "Estabelecer orig." + #define MSG_PREHEAT_PLA "Pre-aquecer PLA" + #define MSG_PREHEAT_PLA0 " pre-aquecer PLA 1" + #define MSG_PREHEAT_PLA1 " pre-aquecer PLA 2" + #define MSG_PREHEAT_PLA2 " pre-aquecer PLA 3" + #define MSG_PREHEAT_PLA012 " pre-aq. PLA Tudo" + #define MSG_PREHEAT_PLA_BEDONLY " pre-aq. PLA \002Base" + #define MSG_PREHEAT_PLA_SETTINGS "PLA setting" + #define MSG_PREHEAT_ABS "Pre-aquecer ABS" + #define MSG_PREHEAT_ABS0 " pre-aquecer ABS 1" + #define MSG_PREHEAT_ABS1 " pre-aquecer ABS 2" + #define MSG_PREHEAT_ABS2 " pre-aquecer ABS 3" + #define MSG_PREHEAT_ABS012 " pre-aq. ABS Tudo" + #define MSG_PREHEAT_ABS_BEDONLY " pre-aq. ABS \002Base" + #define MSG_PREHEAT_ABS_SETTINGS "ABS setting" + #define MSG_COOLDOWN "Esfriar" #define MSG_SWITCH_PS_ON "Switch Power On" #define MSG_SWITCH_PS_OFF "Switch Power Off" - #define MSG_EXTRUDE " Extrudar" - #define MSG_RETRACT " Retrair" - #define MSG_PREHEAT_PLA " pre-aquecer PLA" - #define MSG_PREHEAT_ABS " pre-aquecer ABS" - #define MSG_MOVE_AXIS " Mover eixo \x7E" - #define MSG_SPEED " Velocidade:" - #define MSG_NOZZLE " \002Nozzle:" - #define MSG_NOZZLE1 " \002Nozzle2:" - #define MSG_NOZZLE2 " \002Nozzle3:" - #define MSG_BED " \002Base:" - #define MSG_FAN_SPEED " Velocidade Ventoinha:" - #define MSG_FLOW " Fluxo:" - #define MSG_CONTROL " Controle \003" - #define MSG_MIN " \002 Min:" - #define MSG_MAX " \002 Max:" - #define MSG_FACTOR " \002 Fact:" - #define MSG_AUTOTEMP " Autotemp:" + #define MSG_EXTRUDE "Extrudar" + #define MSG_RETRACT "Retrair" + #define MSG_PREHEAT_PLA "Pre-aquecer PLA" + #define MSG_PREHEAT_ABS "Pre-aquecer ABS" + #define MSG_MOVE_AXIS "Mover eixo \x7E" + #define MSG_MOVE_X "Move X" + #define MSG_MOVE_Y "Move Y" + #define MSG_MOVE_Z "Move Z" + #define MSG_MOVE_E "Extruder" + #define MSG_MOVE_E1 "Extruder2" + #define MSG_MOVE_E2 "Extruder3" + #define MSG_MOVE_01MM "Move 0.1mm" + #define MSG_MOVE_1MM "Move 1mm" + #define MSG_MOVE_10MM "Move 10mm" + #define MSG_SPEED "Velocidade:" + #define MSG_NOZZLE "\002Nozzle:" + #define MSG_NOZZLE1 "\002Nozzle2:" + #define MSG_NOZZLE2 "\002Nozzle3:" + #define MSG_BED "\002Base:" + #define MSG_FAN_SPEED "Velocidade vento." + #define MSG_FLOW "Fluxo:" + #define MSG_FLOW0 "Fluxo0:" + #define MSG_FLOW1 "Fluxo1:" + #define MSG_FLOW2 "Fluxo2:" + #define MSG_CONTROL "Controle \003" + #define MSG_MIN "\002 Min:" + #define MSG_MAX "\002 Max:" + #define MSG_FACTOR "\002 Fact:" + #define MSG_AUTOTEMP "Autotemp:" #define MSG_ON "On " #define MSG_OFF "Off" - #define MSG_PID_P " PID-P: " - #define MSG_PID_I " PID-I: " - #define MSG_PID_D " PID-D: " - #define MSG_PID_C " PID-C: " - #define MSG_ACC " Acc:" - #define MSG_VXY_JERK " Vxy-jerk: " + #define MSG_PID_P "PID-P: " + #define MSG_PID_I "PID-I: " + #define MSG_PID_D "PID-D: " + #define MSG_PID_C "PID-C: " + #define MSG_ACC "Acc:" + #define MSG_VXY_JERK "Vxy-jerk: " #define MSG_VZ_JERK "Vz-jerk" #define MSG_VE_JERK "Ve-jerk" #define MSG_VMAX " Vmax " @@ -1250,51 +1546,57 @@ #define MSG_Y "y:" #define MSG_Z "z:" #define MSG_E "e:" - #define MSG_VMIN " Vmin:" - #define MSG_VTRAV_MIN " VTrav min:" - #define MSG_AMAX " Amax " - #define MSG_A_RETRACT " A-retract:" - #define MSG_XSTEPS " Xpasso/mm:" - #define MSG_YSTEPS " Ypasso/mm:" - #define MSG_ZSTEPS " Zpasso/mm:" - #define MSG_ESTEPS " Epasso/mm:" - #define MSG_MAIN_WIDE " Menu Principal \003" + #define MSG_VMIN "Vmin:" + #define MSG_VTRAV_MIN "VTrav min:" + #define MSG_AMAX "Amax " + #define MSG_A_RETRACT "A-retract:" + #define MSG_XSTEPS "Xpasso/mm:" + #define MSG_YSTEPS "Ypasso/mm:" + #define MSG_ZSTEPS "Zpasso/mm:" + #define MSG_ESTEPS "Epasso/mm:" + #define MSG_MAIN_WIDE "Menu Principal \003" #define MSG_RECTRACT "Retrair" #define MSG_TEMPERATURE "Temperatura" #define MSG_MOTION "Movimento" - #define MSG_STORE_EPROM " Guardar memoria" - #define MSG_LOAD_EPROM " Carregar memoria" - #define MSG_RESTORE_FAILSAFE " Rest. de emergencia" + #define MSG_STORE_EPROM "Guardar memoria" + #define MSG_LOAD_EPROM "Carregar memoria" + #define MSG_RESTORE_FAILSAFE "Rest. de emergen." #define MSG_REFRESH "\004Recarregar" - #define MSG_WATCH " Monitorar \003" - #define MSG_PREPARE " Preparar \x7E" - #define MSG_PREPARE_ALT " Preparar \003" - #define MSG_CONTROL_ARROW " Controle \x7E" - #define MSG_RETRACT_ARROW " Retrair \x7E" - #define MSG_TUNE " Tune \x7E" - #define MSG_PAUSE_PRINT " Pausar Impressao \x7E" - #define MSG_RESUME_PRINT " Resumir Impressao \x7E" - #define MSG_STOP_PRINT " Parar Impressao \x7E" - #define MSG_CARD_MENU " Menu cartao SD \x7E" - #define MSG_NO_CARD " Sem cartao SD" + #define MSG_WATCH "Monitorar \003" + #define MSG_PREPARE "Preparar \x7E" + #define MSG_PREPARE_ALT "Preparar \003" + #define MSG_CONTROL_ARROW "Controle \x7E" + #define MSG_RETRACT_ARROW "Retrair \x7E" + #define MSG_TUNE "Tune \x7E" + #define MSG_PAUSE_PRINT "Pausar impressao" + #define MSG_RESUME_PRINT "Resumir impressao" + #define MSG_STOP_PRINT "Parar impressao" + #define MSG_CARD_MENU "Menu cartao SD" + #define MSG_NO_CARD "Sem cartao SD" #define MSG_DWELL "Repouso..." - #define MSG_USERWAIT "Esperando Ordem..." + #define MSG_USERWAIT "Esperando ordem" #define MSG_RESUMING "Resuming print" - #define MSG_NO_MOVE "Sem movimento." - #define MSG_PART_RELEASE "Lancamento Parcial" - #define MSG_KILLED "PARADA DE EMERGENCIA. " + #define MSG_NO_MOVE "Sem movimento" + #define MSG_KILLED "PARADA DE EMERG." #define MSG_STOPPED "PARADA. " #define MSG_STEPPER_RELEASED "Lancado." #define MSG_CONTROL_RETRACT " Retrair mm:" - #define MSG_CONTROL_RETRACTF " Retrair F:" + #define MSG_CONTROL_RETRACTF " Retrair V:" #define MSG_CONTROL_RETRACT_ZLIFT " Levantar mm:" #define MSG_CONTROL_RETRACT_RECOVER " DesRet +mm:" - #define MSG_CONTROL_RETRACT_RECOVERF " DesRet F:" + #define MSG_CONTROL_RETRACT_RECOVERF " DesRet V:" #define MSG_AUTORETRACT " AutoRetr.:" - #define MSG_SERIAL_ERROR_MENU_STRUCTURE "Algo esta errado na estrutura do Menu." #define MSG_FILAMENTCHANGE "Change filament" - #define MSG_INIT_SDCARD "Init. SD-Card" + #define MSG_INIT_SDCARD "Init. SD-Card" #define MSG_CNG_SDCARD "Change SD-Card" + #define MSG_ZPROBE_OUT "Son. fora da mesa" + #define MSG_POSITION_UNKNOWN "XY antes de Z" + #define MSG_ZPROBE_ZOFFSET "Z Offset" + #define MSG_BABYSTEP_X "Babystep X" + #define MSG_BABYSTEP_Y "Babystep Y" + #define MSG_BABYSTEP_Z "Babystep Z" + #define MSG_ENDSTOP_ABORT "Endstop abort" + #define MSG_CONTRAST "Contrast" // Serial Console Messages @@ -1304,7 +1606,6 @@ #define MSG_BROWNOUT_RESET " Reset por voltagem incorreta" #define MSG_WATCHDOG_RESET " Reset por Bloqueio" #define MSG_SOFTWARE_RESET " Reset por Software" - #define MSG_MARLIN "Marlin " #define MSG_AUTHOR " | Author: " #define MSG_CONFIGURATION_VER " Ultima atualizacao: " #define MSG_FREE_MEMORY " memoria Livre: " @@ -1320,14 +1621,16 @@ #define MSG_END_FILE_LIST "Fim da lista de arquivos" #define MSG_M104_INVALID_EXTRUDER "M104 Extrusor inválido " #define MSG_M105_INVALID_EXTRUDER "M105 Extrusor inválido " + #define MSG_M200_INVALID_EXTRUDER "M200 Extrusor inválido " #define MSG_M218_INVALID_EXTRUDER "M218 Extrusor inválido " + #define MSG_M221_INVALID_EXTRUDER "M221 Extrusor inválido " #define MSG_ERR_NO_THERMISTORS "Nao ha termistor - no temp" #define MSG_M109_INVALID_EXTRUDER "M109 Extrusor inválido " #define MSG_HEATING "Aquecendo..." #define MSG_HEATING_COMPLETE "Aquecido." #define MSG_BED_HEATING "Aquecendo a Base." #define MSG_BED_DONE "Base quente." - #define MSG_M115_REPORT "FIRMWARE_NAME:Marlin V1; Sprinter/grbl mashup for gen6 FIRMWARE_URL:" FIRMWARE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) "\n" + #define MSG_M115_REPORT "FIRMWARE_NAME:Marlin V1; Sprinter/grbl mashup for gen6 FIRMWARE_URL:" FIRMWARE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) " UUID:" MACHINE_UUID "\n" #define MSG_COUNT_X " Conta X:" #define MSG_ERR_KILLED "Impressora parada com kill() !!" #define MSG_ERR_STOPPED "Impressora parada por erros. Coserte o erro e use M999 para recomeçar!. (Temperatura reiniciada. Ajuste antes de recomeçar)" @@ -1366,7 +1669,10 @@ #define MSG_ENDSTOPS_HIT "O ponto final foi tocado: " #define MSG_ERR_COLD_EXTRUDE_STOP " Extrusao a frio evitada" #define MSG_ERR_LONG_EXTRUDE_STOP " Extrusao muito larga evitada" - + #define MSG_BABYSTEPPING_X "Babystepping X" + #define MSG_BABYSTEPPING_Y "Babystepping Y" + #define MSG_BABYSTEPPING_Z "Babystepping Z" + #define MSG_SERIAL_ERROR_MENU_STRUCTURE "Algo esta errado na estrutura do Menu." #endif @@ -1374,10 +1680,10 @@ #if LANGUAGE_CHOICE == 9 -// Finnish - // LCD Menu Messages - #define WELCOME_MSG MACHINE_NAME " valmis" +// Please note these are limited to 17 characters! + + #define WELCOME_MSG MACHINE_NAME " valmis." #define MSG_SD_INSERTED "Kortti asetettu" #define MSG_SD_REMOVED "Kortti poistettu" #define MSG_MAIN "Palaa" @@ -1386,15 +1692,34 @@ #define MSG_AUTO_HOME "Aja referenssiin" #define MSG_SET_ORIGIN "Aseta origo" #define MSG_PREHEAT_PLA "Esilammita PLA" - #define MSG_PREHEAT_PLA_SETTINGS "Esilammita PLA konf" + #define MSG_PREHEAT_PLA0 "Esilammita PLA 1" + #define MSG_PREHEAT_PLA1 "Esilammita PLA 2" + #define MSG_PREHEAT_PLA2 "Esilammita PLA 3" + #define MSG_PREHEAT_PLA012 "Esila. PLA Kaikki" + #define MSG_PREHEAT_PLA_BEDONLY "Esila. PLA Alusta" + #define MSG_PREHEAT_PLA_SETTINGS "Esilamm. PLA konf" #define MSG_PREHEAT_ABS "Esilammita ABS" - #define MSG_PREHEAT_ABS_SETTINGS "Esilammita ABS konf" + #define MSG_PREHEAT_ABS0 "Esilammita ABS 1" + #define MSG_PREHEAT_ABS1 "Esilammita ABS 2" + #define MSG_PREHEAT_ABS2 "Esilammita ABS 3" + #define MSG_PREHEAT_ABS012 "Esila. ABS Kaikki" + #define MSG_PREHEAT_ABS_BEDONLY "Esila. ABS Alusta" + #define MSG_PREHEAT_ABS_SETTINGS "Esilamm. ABS konf" #define MSG_COOLDOWN "Jaahdyta" - #define MSG_SWITCH_PS_ON "Switch Power On" - #define MSG_SWITCH_PS_OFF "Switch Power Off" + #define MSG_SWITCH_PS_ON "Virta paalle" + #define MSG_SWITCH_PS_OFF "Virta pois" #define MSG_EXTRUDE "Pursota" #define MSG_RETRACT "Veda takaisin" #define MSG_MOVE_AXIS "Liikuta akseleita" + #define MSG_MOVE_X "Move X" + #define MSG_MOVE_Y "Move Y" + #define MSG_MOVE_Z "Move Z" + #define MSG_MOVE_E "Extruder" + #define MSG_MOVE_E1 "Extruder2" + #define MSG_MOVE_E2 "Extruder3" + #define MSG_MOVE_01MM "Move 0.1mm" + #define MSG_MOVE_1MM "Move 1mm" + #define MSG_MOVE_10MM "Move 10mm" #define MSG_SPEED "Nopeus" #define MSG_NOZZLE "Suutin" #define MSG_NOZZLE1 "Suutin2" @@ -1402,6 +1727,9 @@ #define MSG_BED "Alusta" #define MSG_FAN_SPEED "Tuul. nopeus" #define MSG_FLOW "Virtaus" + #define MSG_FLOW0 "Virtaus 0" + #define MSG_FLOW1 "Virtaus 1" + #define MSG_FLOW2 "Virtaus 2" #define MSG_CONTROL "Kontrolli" #define MSG_MIN " \002 Min" #define MSG_MAX " \002 Max" @@ -1447,20 +1775,27 @@ #define MSG_CARD_MENU "Korttivalikko" #define MSG_NO_CARD "Ei korttia" #define MSG_DWELL "Nukkumassa..." - #define MSG_USERWAIT "Odotetaan valintaa..." - #define MSG_RESUMING "Jatketaan tulostusta" + #define MSG_USERWAIT "Odotet. valintaa" + #define MSG_RESUMING "Jatke. tulostusta" #define MSG_NO_MOVE "Ei liiketta." #define MSG_KILLED "KILLED. " #define MSG_STOPPED "STOPPED. " #define MSG_CONTROL_RETRACT "Veda mm" - #define MSG_CONTROL_RETRACTF "Veda F" + #define MSG_CONTROL_RETRACTF "Veda V" #define MSG_CONTROL_RETRACT_ZLIFT "Z mm" #define MSG_CONTROL_RETRACT_RECOVER "UnRet +mm" - #define MSG_CONTROL_RETRACT_RECOVERF "UnRet F" + #define MSG_CONTROL_RETRACT_RECOVERF "UnRet V" #define MSG_AUTORETRACT "AutoVeto." #define MSG_FILAMENTCHANGE "Change filament" - #define MSG_INIT_SDCARD "Init. SD-Card" + #define MSG_INIT_SDCARD "Init. SD-Card" #define MSG_CNG_SDCARD "Change SD-Card" + #define MSG_ZPROBE_OUT "Z probe out. bed" + #define MSG_POSITION_UNKNOWN "Home X/Y before Z" + #define MSG_ZPROBE_ZOFFSET "Z Offset" + #define MSG_BABYSTEP_X "Babystep X" + #define MSG_BABYSTEP_Y "Babystep Y" + #define MSG_BABYSTEP_Z "Babystep Z" + #define MSG_ENDSTOP_ABORT "Endstop abort" // Serial Console Messages @@ -1470,7 +1805,6 @@ #define MSG_BROWNOUT_RESET " Alajannite Reset" #define MSG_WATCHDOG_RESET " Vahtikoira Reset" #define MSG_SOFTWARE_RESET " Ohjelmisto Reset" - #define MSG_MARLIN "Marlin " #define MSG_AUTHOR " | Author: " #define MSG_CONFIGURATION_VER " Paivitetty viimeksi: " #define MSG_FREE_MEMORY " Vapaata muistia: " @@ -1486,14 +1820,16 @@ #define MSG_END_FILE_LIST "Tiedostolistauksen loppu" #define MSG_M104_INVALID_EXTRUDER "M104 Virheellinen suutin " #define MSG_M105_INVALID_EXTRUDER "M105 Virheellinen suutin " + #define MSG_M200_INVALID_EXTRUDER "M200 Virheellinen suutin " #define MSG_M218_INVALID_EXTRUDER "M218 Virheellinen suutin " + #define MSG_M221_INVALID_EXTRUDER "M221 Virheellinen suutin " #define MSG_ERR_NO_THERMISTORS "Ei termistoreja - ei lampotiloja" #define MSG_M109_INVALID_EXTRUDER "M109 Virheellinen suutin " #define MSG_HEATING "Lammitan..." #define MSG_HEATING_COMPLETE "Lammitys valmis." #define MSG_BED_HEATING "Alusta lampiaa." #define MSG_BED_DONE "Alusta valmis." - #define MSG_M115_REPORT "FIRMWARE_NAME:Marlin V1; Sprinter/grbl mashup for gen6 FIRMWARE_URL:" FIRMWARE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) "\n" + #define MSG_M115_REPORT "FIRMWARE_NAME:Marlin V1; Sprinter/grbl mashup for gen6 FIRMWARE_URL:" FIRMWARE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) " UUID:" MACHINE_UUID "\n" #define MSG_COUNT_X " Laskuri X: " #define MSG_ERR_KILLED "Tulostin pysaytetty. kill():ia kutsuttu!" #define MSG_ERR_STOPPED "Tulostin pysaytetty virheiden vuoksi. Korjaa virheet ja kayta M999 kaynnistaaksesi uudelleen. (Lampotila nollattiin. Aseta lampotila sen jalkeen kun jatkat.)" @@ -1532,6 +1868,812 @@ #define MSG_ENDSTOPS_HIT "paatyrajat aktivoitu: " #define MSG_ERR_COLD_EXTRUDE_STOP " kylmana pursotus estetty" #define MSG_ERR_LONG_EXTRUDE_STOP " liian pitka pursotus estetty" + #define MSG_BABYSTEPPING_X "Babystepping X" + #define MSG_BABYSTEPPING_Y "Babystepping Y" + #define MSG_BABYSTEPPING_Z "Babystepping Z" + #define MSG_ENDSTOP_ABORT "Endstop abort" + #define MSG_CONTRAST "Kontrasti" + #define MSG_SERIAL_ERROR_MENU_STRUCTURE "Virhe valikon rakenteessa" #endif + +#if LANGUAGE_CHOICE == 10 + +// LCD Menu Messages +// Please note these are limited to 17 characters! + + #define WELCOME_MSG MACHINE_NAME " parada." + #define MSG_SD_INSERTED "Tarcheta colocada" + #define MSG_SD_REMOVED "Tarcheta retirada" + #define MSG_MAIN "Menu prencipal" + #define MSG_AUTOSTART " Autostart" + #define MSG_DISABLE_STEPPERS "Amortar motors" + #define MSG_AUTO_HOME "Levar a l'orichen" + #define MSG_SET_ORIGIN "Establir zero" + #define MSG_PREHEAT_PLA "Precalentar PLA" + #define MSG_PREHEAT_PLA0 "Precalentar PLA0" + #define MSG_PREHEAT_PLA1 "Precalentar PLA1" + #define MSG_PREHEAT_PLA2 "Precalentar PLA2" + #define MSG_PREHEAT_PLA012 "Precalentar PLA a" + #define MSG_PREHEAT_PLA_BEDONLY "Prec. PLA Base" + #define MSG_PREHEAT_PLA_SETTINGS "Achustar tem. PLA" + #define MSG_PREHEAT_ABS "Precalentar ABS" + #define MSG_PREHEAT_ABS0 "Precalentar ABS0" + #define MSG_PREHEAT_ABS1 "Precalentar ABS1" + #define MSG_PREHEAT_ABS2 "Precalentar ABS2" + #define MSG_PREHEAT_ABS012 "Precalentar ABS a" + #define MSG_PREHEAT_ABS_BEDONLY "Prec. ABS Base" + #define MSG_PREHEAT_ABS_SETTINGS "Achustar tem. ABS" + #define MSG_COOLDOWN "Enfriar" + #define MSG_SWITCH_PS_ON "Enchegar Fuent" + #define MSG_SWITCH_PS_OFF "Desenchegar Fuent" + #define MSG_EXTRUDE "Extruir" + #define MSG_RETRACT "Retraer" + #define MSG_MOVE_AXIS "Mover Eixes" + #define MSG_MOVE_X "Move X" + #define MSG_MOVE_Y "Move Y" + #define MSG_MOVE_Z "Move Z" + #define MSG_MOVE_E "Extruder" + #define MSG_MOVE_E1 "Extruder2" + #define MSG_MOVE_E2 "Extruder3" + #define MSG_MOVE_01MM "Move 0.1mm" + #define MSG_MOVE_1MM "Move 1mm" + #define MSG_MOVE_10MM "Move 10mm" + #define MSG_SPEED "Velocidat" + #define MSG_NOZZLE "Nozzle" + #define MSG_NOZZLE1 "Nozzle2" + #define MSG_NOZZLE2 "Nozzle3" + #define MSG_BED "Base" + #define MSG_FAN_SPEED "Ixoriador" + #define MSG_FLOW "Fluxo" + #define MSG_FLOW0 "Fluxo 0" + #define MSG_FLOW1 "Fluxo 1" + #define MSG_FLOW2 "Fluxo 2" + #define MSG_CONTROL "Control" + #define MSG_MIN "\002 Min" + #define MSG_MAX "\002 Max" + #define MSG_FACTOR "\002 Fact" + #define MSG_AUTOTEMP "Autotemp" + #define MSG_ON "On" + #define MSG_OFF "Off" + #define MSG_PID_P "PID-P" + #define MSG_PID_I "PID-I" + #define MSG_PID_D "PID-D" + #define MSG_PID_C "PID-C" + #define MSG_ACC "Acel" + #define MSG_VXY_JERK "Vxy-jerk" + #define MSG_VZ_JERK "Vz-jerk" + #define MSG_VE_JERK "Ves-jerk" + #define MSG_VMAX "Vmax" + #define MSG_X "x" + #define MSG_Y "y" + #define MSG_Z "z" + #define MSG_E "y" + #define MSG_VMIN "Vmin" + #define MSG_VTRAV_MIN "VTrav min" + #define MSG_AMAX "Amax" + #define MSG_A_RETRACT "A-retrac." + #define MSG_XSTEPS "X trangos/mm" + #define MSG_YSTEPS "Y trangos/mm" + #define MSG_ZSTEPS "Z trangos/mm" + #define MSG_ESTEPS "E trangos/mm" + #define MSG_RECTRACT "Retraer" + #define MSG_TEMPERATURE "Temperatura" + #define MSG_MOTION "Movimiento" + #define MSG_STORE_EPROM "Alzar Memoria" + #define MSG_LOAD_EPROM "Cargar Memoria" + #define MSG_RESTORE_FAILSAFE "Rest. d'emerchen." + #define MSG_REFRESH "Tornar a cargar" + #define MSG_WATCH "Monitorizar" + #define MSG_PREPARE "Preparar" + #define MSG_TUNE "Achustar" + #define MSG_PAUSE_PRINT "Pausar impresion" + #define MSG_RESUME_PRINT "Contin. impresion" + #define MSG_STOP_PRINT "Detener Impresion" + #define MSG_CARD_MENU "Menu de SD" + #define MSG_NO_CARD "No i hai tarcheta" + #define MSG_DWELL "Reposo..." + #define MSG_USERWAIT "Asperan. ordines" + #define MSG_RESUMING "Contin. impresion" + #define MSG_NO_MOVE "Sin movimiento" + #define MSG_KILLED "ATURADA D'EMERCH." + #define MSG_STOPPED "ATURADA." + #define MSG_CONTROL_RETRACT "Retraer mm" + #define MSG_CONTROL_RETRACTF "Retraer F" + #define MSG_CONTROL_RETRACT_ZLIFT "Devantar mm" + #define MSG_CONTROL_RETRACT_RECOVER "DesRet +mm" + #define MSG_CONTROL_RETRACT_RECOVERF "DesRet F" + #define MSG_AUTORETRACT "AutoRetr." + #define MSG_FILAMENTCHANGE "Cambear" + #define MSG_INIT_SDCARD "Encetan. tarcheta" + #define MSG_CNG_SDCARD "Cambiar tarcheta" + #define MSG_RECTRACT_WIDE "Retraer" + #define MSG_TEMPERATURE_WIDE "Temperatura" + #define MSG_TEMPERATURE_RTN "Temperatura" + #define MSG_MAIN_WIDE "Menu Prencipal" + #define MSG_MOTION_WIDE "Movimiento" + #define MSG_PREPARE_ALT "Preparar" + #define MSG_CONTROL_ARROW "Control" + #define MSG_RETRACT_ARROW "Retraer" + #define MSG_STEPPER_RELEASED "Desacoplada." + #define MSG_ZPROBE_OUT "Z probe out. bed" + #define MSG_POSITION_UNKNOWN "Home X/Y before Z" + #define MSG_ZPROBE_ZOFFSET "Z Offset" + #define MSG_BABYSTEP_X "Babystep X" + #define MSG_BABYSTEP_Y "Babystep Y" + #define MSG_BABYSTEP_Z "Babystep Z" + #define MSG_ENDSTOP_ABORT "Endstop abort" + #define MSG_CONTRAST "Contrast" + +// Serial Console Messages + + #define MSG_Enqueing "En coda \"" + #define MSG_POWERUP "PowerUp" + #define MSG_EXTERNAL_RESET " Reset Externo" + #define MSG_BROWNOUT_RESET " Reset por Voltaje Incorrecto" + #define MSG_WATCHDOG_RESET " Reset por Bloqueo" + #define MSG_SOFTWARE_RESET " Reset por Software" + #define MSG_AUTHOR " | Autor: " + #define MSG_CONFIGURATION_VER " Zaguer esvielle: " + #define MSG_FREE_MEMORY " Memoria libre: " + #define MSG_PLANNER_BUFFER_BYTES " PlannerBufferBytes: " + #define MSG_OK "ok" + #define MSG_FILE_SAVED "Guardau." + #define MSG_ERR_LINE_NO "O Numero de Linea no ye igual a l'Ultimo Numero de Linea+1, Ultima Linea:" + #define MSG_ERR_CHECKSUM_MISMATCH "o checksum no coincide, Ultima Linea:" + #define MSG_ERR_NO_CHECKSUM "No se podió trobar o Checksum con o numero de linea, Ultima Linea:" + #define MSG_ERR_NO_LINENUMBER_WITH_CHECKSUM "No se trobo o Numero de Linea con o Checksum, Ultima Linea:" + #define MSG_FILE_PRINTED "Impresion rematada" + #define MSG_BEGIN_FILE_LIST "Prencipio d'a lista de fichero" + #define MSG_END_FILE_LIST "Fin d'a lista de fichero" + #define MSG_M104_INVALID_EXTRUDER "M104 Extrusor Invalido " + #define MSG_M105_INVALID_EXTRUDER "M105 Extrusor Invalido " + #define MSG_M200_INVALID_EXTRUDER "M200 Extrusor Invalido " + #define MSG_M218_INVALID_EXTRUDER "M218 Extrusor Invalido " + #define MSG_M221_INVALID_EXTRUDER "M221 Extrusor Invalido " + #define MSG_ERR_NO_THERMISTORS "No i hai termistores - no temp" + #define MSG_M109_INVALID_EXTRUDER "M109 Extrusor Invalido " + #define MSG_HEATING "Calentando..." + #define MSG_HEATING_COMPLETE "Calentamiento Feito." + #define MSG_BED_HEATING "Calentando la base." + #define MSG_BED_DONE "Base Calient." + #define MSG_M115_REPORT "FIRMWARE_NAME:Marlin V1; Sprinter/grbl mashup for gen6 FIRMWARE_URL:" FIRMWARE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) " UUID:" MACHINE_UUID "\n" + #define MSG_COUNT_X " Cuenta X:" + #define MSG_ERR_KILLED "Impresora Aturada con kill()!!" + #define MSG_ERR_STOPPED "Impresora aturada por errors. Apanye a error y use M999 Ta reiniciar!. (a temperatura se reestablece. Ajustela antes de continar)" + #define MSG_RESEND "Reninviar:" + #define MSG_UNKNOWN_COMMAND "Comando Desconoixiu:\"" + #define MSG_ACTIVE_EXTRUDER "Extrusor Activo: " + #define MSG_INVALID_EXTRUDER "Extrusor Invalido" + #define MSG_X_MIN "x_min: " + #define MSG_X_MAX "x_max: " + #define MSG_Y_MIN "y_min: " + #define MSG_Y_MAX "y_max: " + #define MSG_Z_MIN "z_min: " + #define MSG_Z_MAX "z_max: " + #define MSG_M119_REPORT "Comprobando fins de corrida." + #define MSG_ENDSTOP_HIT "PULSAU" + #define MSG_ENDSTOP_OPEN "ubierto" + #define MSG_HOTEND_OFFSET "Hotend offsets:" + #define MSG_SD_CANT_OPEN_SUBDIR "No se podió ubrir a subcarpeta." + #define MSG_SD_INIT_FAIL "Fallo en encetar a SD" + #define MSG_SD_VOL_INIT_FAIL "Fallo en amontar o volumen" + #define MSG_SD_OPENROOT_FAIL "Fallo en ubrir a carpeta raiz" + #define MSG_SD_CARD_OK "Tarcheta SD OK" + #define MSG_SD_WORKDIR_FAIL "Fallo en ubrir a carpeta de treballo" + #define MSG_SD_OPEN_FILE_FAIL "Error en ubrir, Fichero: " + #define MSG_SD_FILE_OPENED "Fichero ubierto:" + #define MSG_SD_SIZE " Grandaria:" + #define MSG_SD_FILE_SELECTED "Fichero Seleccionau" + #define MSG_SD_WRITE_TO_FILE "Escribindo en o fichero: " + #define MSG_SD_PRINTING_BYTE "SD imprentando o byte " + #define MSG_SD_NOT_PRINTING "No se ye imprentando con SD" + #define MSG_SD_ERR_WRITE_TO_FILE "Error en escribir en o fichero" + #define MSG_SD_CANT_ENTER_SUBDIR "No se puede ubrir a carpeta:" + + #define MSG_STEPPER_TOO_HIGH "Steprate masiau alto : " + #define MSG_ENDSTOPS_HIT "S'ha tocau a fin de carril: " + #define MSG_ERR_COLD_EXTRUDE_STOP " extrusion fria privada" + #define MSG_ERR_LONG_EXTRUDE_STOP " extrusion masiau larga privada" + #define MSG_BABYSTEPPING_X "Babystepping X" + #define MSG_BABYSTEPPING_Y "Babystepping Y" + #define MSG_BABYSTEPPING_Z "Babystepping Z" + #define MSG_SERIAL_ERROR_MENU_STRUCTURE "Error in menu structure" + +#endif + +#if LANGUAGE_CHOICE == 11 //Dutch + +// LCD Menu Messages +// Please note these are limited to 17 characters! + + #define WELCOME_MSG MACHINE_NAME " gereed." + #define MSG_SD_INSERTED "Kaart ingestoken" + #define MSG_SD_REMOVED "Kaart verwijderd" + #define MSG_MAIN "Main" + #define MSG_AUTOSTART "Autostart" + #define MSG_DISABLE_STEPPERS "Motoren uit" + #define MSG_AUTO_HOME "Auto home" + #define MSG_SET_ORIGIN "Nulpunt instellen" + #define MSG_PREHEAT_PLA "PLA voorverwarmen" + #define MSG_PREHEAT_PLA0 "PLA voorverw. 0" + #define MSG_PREHEAT_PLA1 "PLA voorverw. 1" + #define MSG_PREHEAT_PLA2 "PLA voorverw. 2" + #define MSG_PREHEAT_PLA012 "PLA voorverw. aan" + #define MSG_PREHEAT_PLA_BEDONLY "PLA voorverw. Bed" + #define MSG_PREHEAT_PLA_SETTINGS "PLA verw. conf" + #define MSG_PREHEAT_ABS "ABS voorverwarmen" + #define MSG_PREHEAT_ABS0 "ABS voorverw. 0" + #define MSG_PREHEAT_ABS1 "ABS voorverw. 1" + #define MSG_PREHEAT_ABS2 "ABS voorverw. 2" + #define MSG_PREHEAT_ABS012 "ABS voorverw. aan" + #define MSG_PREHEAT_ABS_BEDONLY "ABS voorverw. Bed" + #define MSG_PREHEAT_ABS_SETTINGS "ABS verw. conf" + #define MSG_COOLDOWN "Afkoelen" + #define MSG_SWITCH_PS_ON "Stroom aan" + #define MSG_SWITCH_PS_OFF "Stroom uit" + #define MSG_EXTRUDE "Extrude" + #define MSG_RETRACT "Retract" + #define MSG_MOVE_AXIS "As verplaatsen" + #define MSG_MOVE_X "Verplaats X" + #define MSG_MOVE_Y "Verplaats Y" + #define MSG_MOVE_Z "Verplaats Z" + #define MSG_MOVE_E "Extruder" + #define MSG_MOVE_E1 "Extruder2" + #define MSG_MOVE_E2 "Extruder3" + #define MSG_MOVE_01MM "Verplaats 0.1mm" + #define MSG_MOVE_1MM "Verplaats 1mm" + #define MSG_MOVE_10MM "Verplaats 10mm" + #define MSG_SPEED "Snelheid" + #define MSG_NOZZLE "Nozzle" + #define MSG_NOZZLE1 "Nozzle2" + #define MSG_NOZZLE2 "Nozzle3" + #define MSG_BED "Bed" + #define MSG_FAN_SPEED "Fan snelheid" + #define MSG_FLOW "Flow" + #define MSG_FLOW0 "Flow 0" + #define MSG_FLOW1 "Flow 1" + #define MSG_FLOW2 "Flow 2" + #define MSG_CONTROL "Control" + #define MSG_MIN " \002 Min" + #define MSG_MAX " \002 Max" + #define MSG_FACTOR " \002 Fact" + #define MSG_AUTOTEMP "Autotemp" + #define MSG_ON "Aan " + #define MSG_OFF "Uit" + #define MSG_PID_P "PID-P" + #define MSG_PID_I "PID-I" + #define MSG_PID_D "PID-D" + #define MSG_PID_C "PID-C" + #define MSG_ACC "Versn" + #define MSG_VXY_JERK "Vxy-jerk" + #define MSG_VZ_JERK "Vz-jerk" + #define MSG_VE_JERK "Ve-jerk" + #define MSG_VMAX "Vmax " + #define MSG_X "x" + #define MSG_Y "y" + #define MSG_Z "z" + #define MSG_E "e" + #define MSG_VMIN "Vmin" + #define MSG_VTRAV_MIN "VTrav min" + #define MSG_AMAX "Amax " + #define MSG_A_RETRACT "A-retract" + #define MSG_XSTEPS "Xsteps/mm" + #define MSG_YSTEPS "Ysteps/mm" + #define MSG_ZSTEPS "Zsteps/mm" + #define MSG_ESTEPS "Esteps/mm" + #define MSG_RECTRACT "Terugtrekken" + #define MSG_TEMPERATURE "Temperatuur" + #define MSG_MOTION "Beweging" + #define MSG_CONTRAST "LCD contrast" + #define MSG_STORE_EPROM "Geheugen opslaan" + #define MSG_LOAD_EPROM "Geheugen laden" + #define MSG_RESTORE_FAILSAFE "Noodstop reset" + #define MSG_REFRESH "Ververs" + #define MSG_WATCH "Info scherm" + #define MSG_PREPARE "Voorbereiden" + #define MSG_TUNE "Afstellen" + #define MSG_PAUSE_PRINT "Print pauzeren" + #define MSG_RESUME_PRINT "Print hervatten" + #define MSG_STOP_PRINT "Print stoppen" + #define MSG_CARD_MENU "Print van SD" + #define MSG_NO_CARD "Geen SD kaart" + #define MSG_DWELL "Slapen..." + #define MSG_USERWAIT "Wachten..." + #define MSG_RESUMING "Print hervatten" + #define MSG_NO_MOVE "Geen beweging." + #define MSG_KILLED "AFGEBROKEN. " + #define MSG_STOPPED "GESTOPT. " + #define MSG_CONTROL_RETRACT "Retract mm" + #define MSG_CONTROL_RETRACTF "Retract F" + #define MSG_CONTROL_RETRACT_ZLIFT "Hop mm" + #define MSG_CONTROL_RETRACT_RECOVER "UnRet +mm" + #define MSG_CONTROL_RETRACT_RECOVERF "UnRet F" + #define MSG_AUTORETRACT "AutoRetr." + #define MSG_FILAMENTCHANGE "Verv. Filament" + #define MSG_INIT_SDCARD "Init. SD kaart" + #define MSG_CNG_SDCARD "Verv. SD card" + #define MSG_ZPROBE_OUT "Z probe uit. bed" + #define MSG_POSITION_UNKNOWN "Home X/Y voor Z" + #define MSG_ZPROBE_ZOFFSET "Z Offset" + #define MSG_BABYSTEP_X "Babystap X" + #define MSG_BABYSTEP_Y "Babystap Y" + #define MSG_BABYSTEP_Z "Babystap Z" + #define MSG_ENDSTOP_ABORT "Endstop afbr." + +// Serial Console Messages + + #define MSG_Enqueing "enqueing \"" + #define MSG_POWERUP "Opstarten" + #define MSG_EXTERNAL_RESET " Externe Reset" + #define MSG_BROWNOUT_RESET " Lage voedingsspanning Reset" + #define MSG_WATCHDOG_RESET " Watchdog Reset" + #define MSG_SOFTWARE_RESET " Software Reset" + #define MSG_AUTHOR " | Auteur: " + #define MSG_CONFIGURATION_VER " Laatst bijgewerkt: " + #define MSG_FREE_MEMORY " Vrij Geheugen: " + #define MSG_PLANNER_BUFFER_BYTES " PlannerBufferBytes: " + #define MSG_OK "ok" + #define MSG_FILE_SAVED "Bestand opslaan voltooid." + #define MSG_ERR_LINE_NO "Regelnummer is niet het laatste regelnummer+1, Laatste regel: " + #define MSG_ERR_CHECKSUM_MISMATCH "Checksum fout, Laatste regel: " + #define MSG_ERR_NO_CHECKSUM "Regel zonder checksum, Laatste regel: " + #define MSG_ERR_NO_LINENUMBER_WITH_CHECKSUM "Geen regelnummer met checksum, Laatste regel: " + #define MSG_FILE_PRINTED "Bestand afdrukken klaar" + #define MSG_BEGIN_FILE_LIST "Begin bestandslijst" + #define MSG_END_FILE_LIST "Einde bestandslijst" + #define MSG_M104_INVALID_EXTRUDER "M104 Ongeldige extruder " + #define MSG_M105_INVALID_EXTRUDER "M105 Ongeldige extruder " + #define MSG_M200_INVALID_EXTRUDER "M200 Ongeldige extruder " + #define MSG_M218_INVALID_EXTRUDER "M218 Ongeldige extruder " + #define MSG_M221_INVALID_EXTRUDER "M221 Ongeldige extruder " + #define MSG_ERR_NO_THERMISTORS "Geen thermistors - geen temperatuur" + #define MSG_M109_INVALID_EXTRUDER "M109 Ongeldige extruder " + #define MSG_HEATING "Opwarmen..." + #define MSG_HEATING_COMPLETE "Opwarmen klaar." + #define MSG_BED_HEATING "Bed opwarmen." + #define MSG_BED_DONE "Bed klaar." + #define MSG_M115_REPORT "FIRMWARE_NAME:Marlin V1; Sprinter/grbl mashup voor gen6 FIRMWARE_URL:" FIRMWARE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) " UUID:" MACHINE_UUID "\n" + #define MSG_COUNT_X " Aantal X: " + #define MSG_ERR_KILLED "Printer stopgezet. kill() aangeroepen!" + #define MSG_ERR_STOPPED "Printer gestopt vanwege fouten. Los de fout op en gebruik M999 om opnieuw te starten. (Temperatuur is gereset, stel deze opnieuw in na herstart)" + #define MSG_RESEND "Opnieuw sturen: " + #define MSG_UNKNOWN_COMMAND "Onbekend commando: \"" + #define MSG_ACTIVE_EXTRUDER "Actieve Extruder: " + #define MSG_INVALID_EXTRUDER "Ongeldige extruder" + #define MSG_X_MIN "x_min: " + #define MSG_X_MAX "x_max: " + #define MSG_Y_MIN "y_min: " + #define MSG_Y_MAX "y_max: " + #define MSG_Z_MIN "z_min: " + #define MSG_Z_MAX "z_max: " + #define MSG_M119_REPORT "Eindstop statusrapportage:" + #define MSG_ENDSTOP_HIT "GERAAKT" + #define MSG_ENDSTOP_OPEN "open" + #define MSG_HOTEND_OFFSET "Hotend afwijking:" + + #define MSG_SD_CANT_OPEN_SUBDIR "Kan subdirectory niet openen" + #define MSG_SD_INIT_FAIL "SD initialiseren mislukt" + #define MSG_SD_VOL_INIT_FAIL "volume.init mislukt" + #define MSG_SD_OPENROOT_FAIL "openRoot mislukt" + #define MSG_SD_CARD_OK "SD kaart ok" + #define MSG_SD_WORKDIR_FAIL "workDir openen mislukt" + #define MSG_SD_OPEN_FILE_FAIL "Openen mislukt, bestand: " + #define MSG_SD_FILE_OPENED "Bestand geopend: " + #define MSG_SD_SIZE " Grootte: " + #define MSG_SD_FILE_SELECTED "Bestanden geselecteerd:" + #define MSG_SD_WRITE_TO_FILE "Schrijven naar bestand: " + #define MSG_SD_PRINTING_BYTE "SD printen byte: " + #define MSG_SD_NOT_PRINTING "Niet SD printen" + #define MSG_SD_ERR_WRITE_TO_FILE "Fout tijdens het schrijven naar bestand:" + #define MSG_SD_CANT_ENTER_SUBDIR "Kan subdirectory niet in: " + + #define MSG_STEPPER_TOO_HIGH "stapsnelheid te hoog:" + #define MSG_ENDSTOPS_HIT "endstops geraakt: " + #define MSG_ERR_COLD_EXTRUDE_STOP " Koude extrusie voorkomen" + #define MSG_ERR_LONG_EXTRUDE_STOP " te lange extrusie voorkomen" + #define MSG_BABYSTEPPING_X "Babystepping X" + #define MSG_BABYSTEPPING_Y "Babystepping Y" + #define MSG_BABYSTEPPING_Z "Babystepping Z" + #define MSG_SERIAL_ERROR_MENU_STRUCTURE "Fout in menustructuur" + +#endif + + +#if LANGUAGE_CHOICE == 12 + +// LCD Menu Messages + +// Please note these are limited to 17 characters! + + #define WELCOME_MSG MACHINE_NAME " preparada." + #define MSG_SD_INSERTED "SD detectada." + #define MSG_SD_REMOVED "SD expulsada." + #define MSG_MAIN "Menu principal" + #define MSG_AUTOSTART "Inici automatic" + #define MSG_DISABLE_STEPPERS "Apagar motors" + #define MSG_AUTO_HOME "Home global" + #define MSG_SET_ORIGIN "Establir origen" + #define MSG_PREHEAT_PLA "Preescalfar PLA" + #define MSG_PREHEAT_PLA0 "Preescalfar PLA 1" + #define MSG_PREHEAT_PLA1 "Preescalfar PLA 2" + #define MSG_PREHEAT_PLA2 "Preescalfar PLA 3" + #define MSG_PREHEAT_PLA012 "Preesc. tot PLA" + #define MSG_PREHEAT_PLA_BEDONLY "Preesc. llit PLA" + #define MSG_PREHEAT_PLA_SETTINGS "Configuració PLA" + #define MSG_PREHEAT_ABS "Preescalfar ABS" + #define MSG_PREHEAT_ABS0 "Preescalfar ABS 1" + #define MSG_PREHEAT_ABS1 "Preescalfar ABS 2" + #define MSG_PREHEAT_ABS2 "Preescalfar ABS 3" + #define MSG_PREHEAT_ABS012 "Preesc. tot ABS" + #define MSG_PREHEAT_ABS_BEDONLY "Preesc. llit ABS" + #define MSG_PREHEAT_ABS_SETTINGS "Configuració ABS" + #define MSG_COOLDOWN "Refredar" + #define MSG_SWITCH_PS_ON "Switch power on" + #define MSG_SWITCH_PS_OFF "Switch power off" + #define MSG_EXTRUDE "Extruir" + #define MSG_RETRACT "Refredar" + #define MSG_MOVE_AXIS "Moure eixos" + #define MSG_MOVE_X "Moure X" + #define MSG_MOVE_Y "Moure Y" + #define MSG_MOVE_Z "Moure Z" + #define MSG_MOVE_E "Extrusor" + #define MSG_MOVE_E1 "Extruder2" + #define MSG_MOVE_E2 "Extruder3" + #define MSG_MOVE_01MM "Moure 0.1mm" + #define MSG_MOVE_1MM "Moure 1mm" + #define MSG_MOVE_10MM "Moure 10mm" + #define MSG_SPEED "Velocitat" + #define MSG_NOZZLE "Nozzle" + #define MSG_NOZZLE1 "Nozzle2" + #define MSG_NOZZLE2 "Nozzle3" + #define MSG_BED "Llit" + #define MSG_FAN_SPEED "Vel. Ventilador" + #define MSG_FLOW "Fluxe" + #define MSG_FLOW0 "Fluxe 0" + #define MSG_FLOW1 "Fluxe 1" + #define MSG_FLOW2 "Fluxe 2" + #define MSG_CONTROL "Control" + #define MSG_MIN " \002 Min" + #define MSG_MAX " \002 Max" + #define MSG_FACTOR " \002 Fact" + #define MSG_AUTOTEMP "Autotemp" + #define MSG_ON "On " + #define MSG_OFF "Off" + #define MSG_PID_P "PID-P" + #define MSG_PID_I "PID-I" + #define MSG_PID_D "PID-D" + #define MSG_PID_C "PID-C" + #define MSG_ACC "Accel" + #define MSG_VXY_JERK "Vxy-jerk" + #define MSG_VZ_JERK "Vz-jerk" + #define MSG_VE_JERK "Ve-jerk" + #define MSG_VMAX "Vmax " + #define MSG_X "x" + #define MSG_Y "y" + #define MSG_Z "z" + #define MSG_E "e" + #define MSG_VMIN "Vmin" + #define MSG_VTRAV_MIN "VTrav min" + #define MSG_AMAX "Amax " + #define MSG_A_RETRACT "A-retract" + #define MSG_XSTEPS "Xpassos/mm" + #define MSG_YSTEPS "Ypassos/mm" + #define MSG_ZSTEPS "Zpassos/mm" + #define MSG_ESTEPS "Epassos/mm" + #define MSG_RECTRACT "Retreure" + #define MSG_TEMPERATURE "Temperatura" + #define MSG_MOTION "Moviment" + #define MSG_CONTRAST "Contrast de LCD" + #define MSG_STORE_EPROM "Desar a memoria" + #define MSG_LOAD_EPROM "Carregar de mem." + #define MSG_RESTORE_FAILSAFE "Rest. emergencia" + #define MSG_REFRESH "Refrescar" + #define MSG_WATCH "Pantalla Info." + #define MSG_PREPARE "Preparar" + #define MSG_TUNE "Calibrar" + #define MSG_PAUSE_PRINT "Pausa imp." + #define MSG_RESUME_PRINT "Reprendre imp." + #define MSG_STOP_PRINT "Parar inp." + #define MSG_CARD_MENU "Imprimir de SD" + #define MSG_NO_CARD "-Sense targeta SD" + #define MSG_DWELL "Repos..." + #define MSG_USERWAIT "Esperant usuari.." + #define MSG_RESUMING "Reprenent imp." + #define MSG_NO_MOVE "Sense moviment." + #define MSG_KILLED "PARADA DE EMERG. " + #define MSG_STOPPED "ATURAT. " + #define MSG_CONTROL_RETRACT "Retreure mm" + #define MSG_CONTROL_RETRACTF "Retreure F" + #define MSG_CONTROL_RETRACT_ZLIFT "Aixecar mm" + #define MSG_CONTROL_RETRACT_RECOVER "DesRet +mm" + #define MSG_CONTROL_RETRACT_RECOVERF "DesRet F" + #define MSG_AUTORETRACT "AutoRetr." + #define MSG_FILAMENTCHANGE "Canviar filament" + #define MSG_INIT_SDCARD "Iniciant SD" + #define MSG_CNG_SDCARD "Canviar SD" + #define MSG_ZPROBE_OUT "Z probe out. bed" + #define MSG_POSITION_UNKNOWN "Home X/Y abans Z" + #define MSG_ZPROBE_ZOFFSET "Z Offset" + #define MSG_BABYSTEP_X "Babystep X" + #define MSG_BABYSTEP_Y "Babystep Y" + #define MSG_BABYSTEP_Z "Babystep Z" + #define MSG_ENDSTOP_ABORT "Endstop abort" + +// Serial Console Messages + + #define MSG_Enqueing "en cua \"" + #define MSG_POWERUP "PowerUp" + #define MSG_EXTERNAL_RESET " Reset Extern" + #define MSG_BROWNOUT_RESET " Reset per Voltatge Incorrecte" + #define MSG_WATCHDOG_RESET " Reset per Bloqueix" + #define MSG_SOFTWARE_RESET " Reset per Software" + #define MSG_AUTHOR " | Author: " + #define MSG_CONFIGURATION_VER "Ultima actualitzacio: " + #define MSG_FREE_MEMORY " Memoria lliure: " + #define MSG_PLANNER_BUFFER_BYTES " PlannerBufferBytes: " + #define MSG_OK "ok" + #define MSG_FILE_SAVED "Fitxer desat." + #define MSG_ERR_LINE_NO "El Numero de la Linia no es igual al Ultimo Numero de Linia+1, Ultima Linia:" + #define MSG_ERR_CHECKSUM_MISMATCH "el checksum no coincideix, Ultima Linia:" + #define MSG_ERR_NO_CHECKSUM "No s'ha trobat el Checksum amb el numero de linea, Ultima Linea:" + #define MSG_ERR_NO_LINENUMBER_WITH_CHECKSUM "No s'ha trobat Numero de Linea amb el Checksum, Ultima Linea:" + #define MSG_FILE_PRINTED "Impresio acabada" + #define MSG_BEGIN_FILE_LIST "Inici de la llista d'arxius" + #define MSG_END_FILE_LIST "Fi de la llista d'arxius" + #define MSG_M104_INVALID_EXTRUDER "M104 Extrusor Invalid " + #define MSG_M105_INVALID_EXTRUDER "M105 Extrusor Invalid " + #define MSG_M200_INVALID_EXTRUDER "M200 Extrusor Invalid " + #define MSG_M218_INVALID_EXTRUDER "M218 Extrusor Invalid " + #define MSG_M221_INVALID_EXTRUDER "M221 Extrusor Invalid " + #define MSG_ERR_NO_THERMISTORS "No hi ha termistors - sense temperatura" + #define MSG_M109_INVALID_EXTRUDER "M109 Extrusor Invalid " + #define MSG_HEATING "Escalfant..." + #define MSG_HEATING_COMPLETE "Escalfament acabat." + #define MSG_BED_HEATING "Escalfant llit." + #define MSG_BED_DONE "Llit Calent." + #define MSG_M115_REPORT "FIRMWARE_NAME:Marlin V1; Sprinter/grbl mashup for gen6 FIRMWARE_URL:" FIRMWARE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) " UUID:" MACHINE_UUID "\n" + #define MSG_COUNT_X " Count X: " + #define MSG_ERR_KILLED "Impressora Parada per kill()!" + #define MSG_ERR_STOPPED "Impressora Parada per errors. Repara l'error i utilitza M999 per reiniciar!. (Hi ha un reset de temperatura, cal ajustarla abans de continuuar)" + #define MSG_RESEND "Reenviar: " + #define MSG_UNKNOWN_COMMAND "Comanda Desconeguda: \"" + #define MSG_ACTIVE_EXTRUDER "Extrusor Actiu: " + #define MSG_INVALID_EXTRUDER "Extrusor Invalid" + #define MSG_X_MIN "x_min: " + #define MSG_X_MAX "x_max: " + #define MSG_Y_MIN "y_min: " + #define MSG_Y_MAX "y_max: " + #define MSG_Z_MIN "z_min: " + #define MSG_Z_MAX "z_max: " + #define MSG_M119_REPORT "Comprobant finals de carrera." + #define MSG_ENDSTOP_HIT "Activat" + #define MSG_ENDSTOP_OPEN "obert" + #define MSG_HOTEND_OFFSET "Hotend offsets:" + + #define MSG_SD_CANT_OPEN_SUBDIR "No s'ha pogut obrir la carpeta" + #define MSG_SD_INIT_FAIL "Error al iniciar la SD" + #define MSG_SD_VOL_INIT_FAIL "Error al montar el volum" + #define MSG_SD_OPENROOT_FAIL "Error al obrir la carpeta arrel" + #define MSG_SD_CARD_OK "Targeta SD OK" + #define MSG_SD_WORKDIR_FAIL "Error al obrir la carpeta de treball" + #define MSG_SD_OPEN_FILE_FAIL "Error al obrir, Fitxer: " + #define MSG_SD_FILE_OPENED "Fitxer obert:" + #define MSG_SD_SIZE " Mida: " + #define MSG_SD_FILE_SELECTED "Fitxer Seleccionat" + #define MSG_SD_WRITE_TO_FILE "Desant al fitxer: " + #define MSG_SD_PRINTING_BYTE "SD imprimint el byte " + #define MSG_SD_NOT_PRINTING "No s'està imprimint amb SD" + #define MSG_SD_ERR_WRITE_TO_FILE "Error al esciure al fitxer" + #define MSG_SD_CANT_ENTER_SUBDIR "No es pot obrir la carpeta: " + + #define MSG_STEPPER_TOO_HIGH "Steprate massa alt: " + #define MSG_ENDSTOPS_HIT "S'ha tocat el final de carrera: " + #define MSG_ERR_COLD_EXTRUDE_STOP " extrusio freda evitada" + #define MSG_ERR_LONG_EXTRUDE_STOP " extrusio massa llarga evitada" + #define MSG_BABYSTEPPING_X "Babystepping X" + #define MSG_BABYSTEPPING_Y "Babystepping Y" + #define MSG_BABYSTEPPING_Z "Babystepping Z" + #define MSG_SERIAL_ERROR_MENU_STRUCTURE "Error a l'estructura dels menus" + +#endif + +//Basque-Euskera +#if LANGUAGE_CHOICE == 13 + +// LCD Menu Messages +// Please note these are limited to 17 characters! + + #define WELCOME_MSG MACHINE_NAME " prest." + #define MSG_SD_INSERTED "Txartela sartuta" + #define MSG_SD_REMOVED "Txartela kenduta" + #define MSG_MAIN "Menu nagusia" + #define MSG_AUTOSTART "Auto hasiera" + #define MSG_DISABLE_STEPPERS "Itzali motoreak" + #define MSG_AUTO_HOME "Hasierara joan" + #define MSG_SET_ORIGIN "Hasiera ipini" + #define MSG_PREHEAT_PLA "Aurreberotu PLA" + #define MSG_PREHEAT_PLA0 "Aurreberotu PLA1" + #define MSG_PREHEAT_PLA1 "Aurreberotu PLA2" + #define MSG_PREHEAT_PLA2 "Aurreberotu PLA3" + #define MSG_PREHEAT_PLA012 "Berotu PLA Guztia" + #define MSG_PREHEAT_PLA_BEDONLY "Berotu PLA Ohea" + #define MSG_PREHEAT_PLA_SETTINGS "Berotu PLA Konfig" + #define MSG_PREHEAT_ABS "Aurreberotu ABS" + #define MSG_PREHEAT_ABS0 "Aurreberotu ABS 1" + #define MSG_PREHEAT_ABS1 "Aurreberotu ABS 2" + #define MSG_PREHEAT_ABS2 "Aurreberotu ABS 3" + #define MSG_PREHEAT_ABS012 "Berotu ABS Guztia" + #define MSG_PREHEAT_ABS_BEDONLY "Berotu ABS Ohea" + #define MSG_PREHEAT_ABS_SETTINGS "Berotu ABS Konfig" + #define MSG_COOLDOWN "Hoztu" + #define MSG_SWITCH_PS_ON "Energia piztu" + #define MSG_SWITCH_PS_OFF "Energia itzali" + #define MSG_EXTRUDE "Estruitu" + #define MSG_RETRACT "Atzera eragin" + #define MSG_MOVE_AXIS "Ardatzak mugitu" + #define MSG_MOVE_X "Mugitu X" + #define MSG_MOVE_Y "Mugitu Y" + #define MSG_MOVE_Z "Mugitu Z" + #define MSG_MOVE_E "Estrusorea" + #define MSG_MOVE_E1 "Estrusorea2" + #define MSG_MOVE_E2 "Estrusorea3" + #define MSG_MOVE_01MM "Mugitu 0.1mm" + #define MSG_MOVE_1MM "Mugitu 1mm" + #define MSG_MOVE_10MM "Mugitu 10mm" + #define MSG_SPEED "Abiadura" + #define MSG_NOZZLE "Pita" + #define MSG_NOZZLE1 "Pita2" + #define MSG_NOZZLE2 "Pita3" + #define MSG_BED "Ohea" + #define MSG_FAN_SPEED "Haizagailua" + #define MSG_FLOW "Fluxua" + #define MSG_FLOW0 "Fluxua 0" + #define MSG_FLOW1 "Fluxua 1" + #define MSG_FLOW2 "Fluxua 2" + #define MSG_CONTROL "Kontrola" + #define MSG_MIN " \002 Min" + #define MSG_MAX " \002 Max" + #define MSG_FACTOR " \002 Faktorea" + #define MSG_AUTOTEMP "Auto tenperatura" + #define MSG_ON "On " + #define MSG_OFF "Off" + #define MSG_PID_P "PID-P" + #define MSG_PID_I "PID-I" + #define MSG_PID_D "PID-D" + #define MSG_PID_C "PID-C" + #define MSG_ACC "Azelerazioa" + #define MSG_VXY_JERK "Vxy-astindua" + #define MSG_VZ_JERK "Vz-astindua" + #define MSG_VE_JERK "Ve-astindua" + #define MSG_VMAX "Vmax " + #define MSG_X "x" + #define MSG_Y "y" + #define MSG_Z "z" + #define MSG_E "e" + #define MSG_VMIN "Vmin" + #define MSG_VTRAV_MIN "VTrav min" + #define MSG_AMAX "Amax " + #define MSG_A_RETRACT "A-retrakt" + #define MSG_XSTEPS "X pausoak/mm" + #define MSG_YSTEPS "Y pausoak/mm" + #define MSG_ZSTEPS "Z pausoak/mm" + #define MSG_ESTEPS "E pausoak/mm" + #define MSG_RECTRACT "Atzera eragin" + #define MSG_TEMPERATURE "Tenperatura" + #define MSG_MOTION "Mugimendua" + #define MSG_CONTRAST "LCD kontrastea" + #define MSG_STORE_EPROM "Gorde memoria" + #define MSG_LOAD_EPROM "Kargatu memoria" + #define MSG_RESTORE_FAILSAFE "Larri. berriz." + #define MSG_REFRESH "Berriz kargatu" + #define MSG_WATCH "Pantaila info" + #define MSG_PREPARE "Prestatu" + #define MSG_TUNE "Doitu" + #define MSG_PAUSE_PRINT "Pausatu inprimak." + #define MSG_RESUME_PRINT "Jarraitu inprima." + #define MSG_STOP_PRINT "Gelditu inprima." + #define MSG_CARD_MENU "SD-tik inprimatu" + #define MSG_NO_CARD "Ez dago txartelik" + #define MSG_DWELL "Lo egin..." + #define MSG_USERWAIT "Aginduak zain..." + #define MSG_RESUMING "Jarraitzen inpri." + #define MSG_NO_MOVE "Mugimendu gabe" + #define MSG_KILLED "LARRIALDI GELDIA" + #define MSG_STOPPED "GELDITUTA. " + #define MSG_CONTROL_RETRACT "Atzera egin mm" + #define MSG_CONTROL_RETRACTF "Atzera egin V" + #define MSG_CONTROL_RETRACT_ZLIFT "Igo mm" + #define MSG_CONTROL_RETRACT_RECOVER "Atzera egin +mm" + #define MSG_CONTROL_RETRACT_RECOVERF "Atzera egin V" + #define MSG_AUTORETRACT "Atzera egin" + #define MSG_FILAMENTCHANGE "Aldatu filament." + #define MSG_INIT_SDCARD "Hasieratu txartela" + #define MSG_CNG_SDCARD "Aldatu txartela" + #define MSG_ZPROBE_OUT "Z ohe hasiera" + #define MSG_POSITION_UNKNOWN "Posizio ezezaguna" + #define MSG_ZPROBE_ZOFFSET "Z konpentsatu" + #define MSG_BABYSTEP_X "Babystep X" + #define MSG_BABYSTEP_Y "Babystep Y" + #define MSG_BABYSTEP_Z "Babystep Z" + #define MSG_ENDSTOP_ABORT "Endstop deuseztat" + +// Serial Console Messages + + #define MSG_Enqueing "Zerrendan \"" + #define MSG_POWERUP "Pizketa" + #define MSG_EXTERNAL_RESET " Kanpoko Reset" + #define MSG_BROWNOUT_RESET " Tentsio Okerra Reset" + #define MSG_WATCHDOG_RESET " Reset Blokeoa" + #define MSG_SOFTWARE_RESET " Software Reset" + #define MSG_AUTHOR " | Egilea: " + #define MSG_CONFIGURATION_VER " Azken Aktualizazio: " + #define MSG_FREE_MEMORY " Aske Memoria: " + #define MSG_PLANNER_BUFFER_BYTES " PlannerBufferBytes: " + #define MSG_OK "ok" + #define MSG_FILE_SAVED "Gordetuta." + #define MSG_ERR_LINE_NO "Lerro zenbakia ez da azken zenbakia+1 berdina, Azken Lerroa: " + #define MSG_ERR_CHECKSUM_MISMATCH "checksum-ak ez du aldiberekotasuna, Azken Lerroa: " + #define MSG_ERR_NO_CHECKSUM "Ez da checksum-ik aurkitu lerro zenbakian, Azken Lerroa: " + #define MSG_ERR_NO_LINENUMBER_WITH_CHECKSUM "Ez da lerro zenbakia aurkitu checksum-arekin, Azken Lerroa: " + #define MSG_FILE_PRINTED "Inprimaketa bukatua" + #define MSG_BEGIN_FILE_LIST "Hasi artxibo zerrenda" + #define MSG_END_FILE_LIST "Amaitu artxibo zerrenda" + #define MSG_M104_INVALID_EXTRUDER "M104 Balio gabeko Estrusorea " + #define MSG_M105_INVALID_EXTRUDER "M105 Balio gabeko Estrusorea " + #define MSG_M200_INVALID_EXTRUDER "M200 Balio gabeko Estrusorea " + #define MSG_M218_INVALID_EXTRUDER "M218 Balio gabeko Estrusorea " + #define MSG_M221_INVALID_EXTRUDER "M221 Balio gabeko Estrusorea " + #define MSG_ERR_NO_THERMISTORS "Termistorerik ez dago - Tenperaturarik gabe" + #define MSG_M109_INVALID_EXTRUDER "M109 Balio gabeko Estrusorea " + #define MSG_HEATING "Berotzen..." + #define MSG_HEATING_COMPLETE "berotuta." + #define MSG_BED_HEATING "Ohea berotzen." + #define MSG_BED_DONE "Ohea berotuta." + #define MSG_M115_REPORT "FIRMWARE_NAME:Marlin V1; Sprinter/grbl mashup for gen6 FIRMWARE_URL:" FIRMWARE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) " UUID:" MACHINE_UUID "\n" + #define MSG_COUNT_X " X Kontu: " + #define MSG_ERR_KILLED "Inprimagailua geldituta. kill() called!" + #define MSG_ERR_STOPPED "Akatsen eraginez inprimagailua geldituta. Errorea konpondu eta M999 erabili berrabiarazteko. (Tenperatura galdu egin da. Berriro ipini)" + #define MSG_RESEND "Bidali berriro: " + #define MSG_UNKNOWN_COMMAND "Agindu ezezaguna: \"" + #define MSG_ACTIVE_EXTRUDER "Estrusore Aktiboa: " + #define MSG_INVALID_EXTRUDER "Balio gabeko Estrusorea" + #define MSG_X_MIN "x_min: " + #define MSG_X_MAX "x_max: " + #define MSG_Y_MIN "y_min: " + #define MSG_Y_MAX "y_max: " + #define MSG_Z_MIN "z_min: " + #define MSG_Z_MAX "z_max: " + #define MSG_M119_REPORT "Bide amaiera egiaztatzen" + #define MSG_ENDSTOP_HIT "Sakatuta" + #define MSG_ENDSTOP_OPEN "irekia" + #define MSG_HOTEND_OFFSET "Hotend offsets:" + + #define MSG_SD_CANT_OPEN_SUBDIR "Azpidirektorio ezin da ireki" + #define MSG_SD_INIT_FAIL "Akatsa txartela hasterakoan" + #define MSG_SD_VOL_INIT_FAIL "Akatsa partizioa hasterakoan" + #define MSG_SD_OPENROOT_FAIL "Akatsa direktorio nagusian" + #define MSG_SD_CARD_OK "SD card ok" + #define MSG_SD_WORKDIR_FAIL "Akatsa lan direktorioan" + #define MSG_SD_OPEN_FILE_FAIL "Akatsa irekitzean, File: " + #define MSG_SD_FILE_OPENED "Artxiboa irekita: " + #define MSG_SD_SIZE " Tamaina: " + #define MSG_SD_FILE_SELECTED "Artxiboa aukeratuta" + #define MSG_SD_WRITE_TO_FILE "Artxiboa idazten: " + #define MSG_SD_PRINTING_BYTE "SD byte idazten " + #define MSG_SD_NOT_PRINTING "Ez dago SD-tik inprimatzen" + #define MSG_SD_ERR_WRITE_TO_FILE "Akatsak artxiboa idazten" + #define MSG_SD_CANT_ENTER_SUBDIR "Azpidirektorio ezin da ireki: " + + #define MSG_STEPPER_TOO_HIGH "Motorra oso goi dago: " + #define MSG_ENDSTOPS_HIT "Bide amaiera ukitu da: " + #define MSG_ERR_COLD_EXTRUDE_STOP " estrusio hotza saihestua" + #define MSG_ERR_LONG_EXTRUDE_STOP " estrusio oso luzea saihestua" + #define MSG_BABYSTEPPING_X "Babystepping X" + #define MSG_BABYSTEPPING_Y "Babystepping Y" + #define MSG_BABYSTEPPING_Z "Babystepping Z" + #define MSG_SERIAL_ERROR_MENU_STRUCTURE "Akatsak menu-an" + +#endif + #endif // ifndef LANGUAGE_H diff --git a/Marlin/pins.h b/Marlin/pins.h index 60235800a..c3644a086 100644 --- a/Marlin/pins.h +++ b/Marlin/pins.h @@ -1,6 +1,7 @@ #ifndef PINS_H #define PINS_H +#if MOTHERBOARD != 88 #define X_MS1_PIN -1 #define X_MS2_PIN -1 #define Y_MS1_PIN -1 @@ -12,6 +13,91 @@ #define E1_MS1_PIN -1 #define E1_MS2_PIN -1 #define DIGIPOTSS_PIN -1 +#endif + +/**************************************************************************************** +* 5DPrint D8 Driver board +* https://bitbucket.org/makible/5dprint-d8-controller-board +****************************************************************************************/ + +#if MOTHERBOARD == 88 + +#define KNOWN_BOARD 1 +#define AT90USB 1286 // Disable MarlinSerial etc. + +#ifndef __AVR_AT90USB1286__ +#error Oops! Make sure you have 'Teensy++ 2.0' selected from the 'Tools -> Boards' menu. +#endif + +#define LARGE_FLASH true + +#define X_STEP_PIN 0 +#define X_DIR_PIN 1 +#define X_ENABLE_PIN 23 +#define X_STOP_PIN 37 + +#define Y_STEP_PIN 2 +#define Y_DIR_PIN 3 +#define Y_ENABLE_PIN 19 +#define Y_STOP_PIN 36 + +#define Z_STEP_PIN 4 +#define Z_DIR_PIN 5 +#define Z_ENABLE_PIN 18 +#define Z_STOP_PIN 39 + +#define E0_STEP_PIN 6 +#define E0_DIR_PIN 7 +#define E0_ENABLE_PIN 17 + +#define HEATER_0_PIN 21 // Extruder +#define HEATER_1_PIN -1 +#define HEATER_2_PIN -1 +#define HEATER_BED_PIN 20 // Bed +// You may need to change FAN_PIN to 16 because Marlin isn't using fastio.h +// for the fan and Teensyduino uses a different pin mapping. +#define FAN_PIN 16 // Fan + +#define TEMP_0_PIN 1 // Extruder / Analog pin numbering +#define TEMP_BED_PIN 0 // Bed / Analog pin numbering + +#define TEMP_1_PIN -1 +#define TEMP_2_PIN -1 + +#define SDPOWER -1 +#define LED_PIN -1 +#define PS_ON_PIN -1 +#define KILL_PIN -1 +#define ALARM_PIN -1 + +// The SDSS pin uses a different pin mapping from file Sd2PinMap.h +#define SDSS 20 + +#ifndef SDSUPPORT +// these pins are defined in the SD library if building with SD support + #define SCK_PIN 9 + #define MISO_PIN 11 + #define MOSI_PIN 10 +#endif + +// Microstepping pins +// Note that the pin mapping is not from fastio.h +// See Sd2PinMap.h for the pin configurations +#define X_MS1_PIN 25 +#define X_MS2_PIN 26 +#define Y_MS1_PIN 9 +#define Y_MS2_PIN 8 +#define Z_MS1_PIN 7 +#define Z_MS2_PIN 6 +#define E0_MS1_PIN 5 +#define E0_MS2_PIN 4 + +#endif /* 88 */ + +/**************************************************************************************** +* +* +****************************************************************************************/ #if MOTHERBOARD == 99 #define KNOWN_BOARD 1 @@ -53,6 +139,83 @@ #endif /* 99 */ +/**************************************************************************************** +* Sethi 3D_1 pin assignment - www.sethi3d.com.br +* +****************************************************************************************/ + +#if MOTHERBOARD == 20 +#define KNOWN_BOARD + +#if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega644__) && !defined(__AVR_ATmega1284P__) +#error Oops! Make sure you have 'Sethi 3D' selected from the 'Tools -> Boards' menu. + +#endif + +#ifndef GEN7_VERSION +#define GEN7_VERSION 12 // v1.x +#endif + +//x axis pins +#define X_STEP_PIN 19 +#define X_DIR_PIN 18 +#define X_ENABLE_PIN 24 +#define X_STOP_PIN 2 + +//y axis pins +#define Y_STEP_PIN 23 +#define Y_DIR_PIN 22 +#define Y_ENABLE_PIN 24 +#define Y_STOP_PIN 0 + +//z axis pins +#define Z_STEP_PIN 26 +#define Z_DIR_PIN 25 +#define Z_ENABLE_PIN 24 +#define Z_MIN_PIN 1 +#define Z_MAX_PIN 0 + +//extruder pins +#define E0_STEP_PIN 28 +#define E0_DIR_PIN 27 +#define E0_ENABLE_PIN 24 + +#define TEMP_0_PIN 1 +#define TEMP_1_PIN -1 +#define TEMP_2_PIN -1 +#define TEMP_BED_PIN 2 + +#define HEATER_0_PIN 4 +#define HEATER_1_PIN -1 +#define HEATER_2_PIN -1 +#define HEATER_BED_PIN 3 + +#define KILL_PIN -1 + +#define SDPOWER -1 +#define SDSS -1 // SCL pin of I2C header +#define LED_PIN -1 + +#if (GEN7_VERSION >= 13) +// Gen7 v1.3 removed the fan pin +#define FAN_PIN -1 +#else +#define FAN_PIN 31 +#endif +#define PS_ON_PIN 15 + +//All these generations of Gen7 supply thermistor power +//via PS_ON, so ignore bad thermistor readings +#define BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE + +//our pin for debugging. +#define DEBUG_PIN 0 + +//our RS485 pins +#define TX_ENABLE_PIN 12 +#define RX_ENABLE_PIN 13 + +#endif /**************************************************************************************** * Gen7 v1.1, v1.2, v1.3 pin assignment @@ -298,7 +461,7 @@ * Arduino Mega pin assignment * ****************************************************************************************/ -#if MOTHERBOARD == 3 || MOTHERBOARD == 33 || MOTHERBOARD == 34 || MOTHERBOARD == 35 || MOTHERBOARD == 77 +#if MOTHERBOARD == 3 || MOTHERBOARD == 33 || MOTHERBOARD == 34 || MOTHERBOARD == 35 || MOTHERBOARD == 77 || MOTHERBOARD == 67 || MOTHERBOARD == 68 #define KNOWN_BOARD 1 //////////////////FIX THIS////////////// @@ -314,10 +477,10 @@ // #define RAMPS_V_1_0 -#if MOTHERBOARD == 33 || MOTHERBOARD == 34 || MOTHERBOARD == 35 || MOTHERBOARD == 77 +#if MOTHERBOARD == 33 || MOTHERBOARD == 34 || MOTHERBOARD == 35 || MOTHERBOARD == 77 || MOTHERBOARD == 67 || MOTHERBOARD == 68 #define LARGE_FLASH true - + #if MOTHERBOARD == 77 #define X_STEP_PIN 54 #define X_DIR_PIN 55 @@ -337,6 +500,10 @@ #define Z_MIN_PIN 18 #define Z_MAX_PIN -1 + #define Y2_STEP_PIN 36 + #define Y2_DIR_PIN 34 + #define Y2_ENABLE_PIN 30 + #define Z2_STEP_PIN 36 #define Z2_DIR_PIN 34 #define Z2_ENABLE_PIN 30 @@ -353,7 +520,7 @@ #define SDSS 25//53 #define LED_PIN 13 - #define BEEPER 33 + #define BEEPER 33 #else @@ -375,6 +542,10 @@ #define Z_MIN_PIN 18 #define Z_MAX_PIN 19 + #define Y2_STEP_PIN 36 + #define Y2_DIR_PIN 34 + #define Y2_ENABLE_PIN 30 + #define Z2_STEP_PIN 36 #define Z2_DIR_PIN 34 #define Z2_ENABLE_PIN 30 @@ -387,23 +558,37 @@ #define E1_DIR_PIN 34 #define E1_ENABLE_PIN 30 + #if MOTHERBOARD == 68 + #define E2_STEP_PIN 23 + #define E2_DIR_PIN 25 + #define E2_ENABLE_PIN 40 + + #define E3_STEP_PIN 27 + #define E3_DIR_PIN 29 + #define E3_ENABLE_PIN 41 + + #define E4_STEP_PIN 43 + #define E4_DIR_PIN 37 + #define E4_ENABLE_PIN 42 + #endif + #define SDPOWER -1 #define SDSS 53 #define LED_PIN 13 #endif - #if MOTHERBOARD == 33 || MOTHERBOARD == 35 + #if MOTHERBOARD == 33 || MOTHERBOARD == 35 || MOTHERBOARD == 67 || MOTHERBOARD == 68 #define FAN_PIN 9 // (Sprinter config) #else #define FAN_PIN 4 // IO pin. Buffer needed #endif #if MOTHERBOARD == 77 - #define FAN_PIN 8 + #define FAN_PIN 8 #endif - + #if MOTHERBOARD == 35 - #define CONTROLLERFAN_PIN 10 //Pin used for the fan to cool controller + #define CONTROLLERFAN_PIN -1 //Pin used for the fan to cool controller #endif #define PS_ON_PIN 12 @@ -420,23 +605,39 @@ #define HEATER_0_PIN 10 // EXTRUDER 1 #endif - #if MOTHERBOARD == 33 + #if MOTHERBOARD == 33 || MOTHERBOARD == 67 #define HEATER_1_PIN -1 #else #define HEATER_1_PIN 9 // EXTRUDER 2 (FAN On Sprinter) #endif - #define HEATER_2_PIN -1 #if MOTHERBOARD == 77 - #define HEATER_0_PIN 10 - #define HEATER_1_PIN 12 - #define HEATER_2_PIN 6 + #define HEATER_0_PIN 10 + #define HEATER_1_PIN 12 + #define HEATER_2_PIN 6 + #elif MOTHERBOARD == 68 + #define HEATER_2_PIN 16 + #define HEATER_3_PIN 17 + #define HEATER_4_PIN 4 + #define HEATER_5_PIN 5 + #define HEATER_6_PIN 6 + #define HEATER_7_PIN 11 + #else + #define HEATER_2_PIN -1 #endif #define TEMP_0_PIN 13 // ANALOG NUMBERING #define TEMP_1_PIN 15 // ANALOG NUMBERING - #define TEMP_2_PIN -1 // ANALOG NUMBERING + #if MOTHERBOARD == 68 + #define TEMP_2_PIN 12 // ANALOG NUMBERING + #define TEMP_3_PIN 11 // ANALOG NUMBERING + #define TEMP_4_PIN 10 // ANALOG NUMBERING + #define TC1 4 // ANALOG NUMBERING Thermo couple on Azteeg X3Pro + #define TC2 5 // ANALOG NUMBERING Thermo couple on Azteeg X3Pro + #else + #define TEMP_2_PIN -1 // ANALOG NUMBERING + #endif #if MOTHERBOARD == 35 #define HEATER_BED_PIN -1 // NO BED @@ -447,9 +648,8 @@ #define HEATER_BED_PIN 8 // BED #endif #endif - #define TEMP_BED_PIN 14 // ANALOG NUMBERING - + #define TEMP_BED_PIN 14 // ANALOG NUMBERING #ifdef NUM_SERVOS #define SERVO0_PIN 11 @@ -467,13 +667,24 @@ #endif #endif + #if MOTHERBOARD == 68 + #define BEEPER 33 + #endif + + #ifdef TEMP_STAT_LEDS + #if MOTHERBOARD == 67 + #define STAT_LED_RED 6 + #define STAT_LED_BLUE 11 + #endif + #endif + #ifdef ULTRA_LCD #ifdef NEWPANEL - #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 @@ -484,6 +695,19 @@ #define BTN_EN2 33 #define BTN_ENC 35 + #define SDCARDDETECT 49 + #elif defined(LCD_I2C_PANELOLU2) + #define BTN_EN1 47 //reverse if the encoder turns the wrong way. + #define BTN_EN2 43 + #define BTN_ENC 32 + #define SDSS 53 + #define SDCARDDETECT -1 + #define KILL_PIN 41 + #elif defined(LCD_I2C_VIKI) + #define BTN_EN1 22 //reverse if the encoder turns the wrong way. + #define BTN_EN2 7 + #define BTN_ENC -1 + #define SDSS 53 #define SDCARDDETECT 49 #else //arduino pin which triggers an piezzo beeper @@ -508,25 +732,25 @@ #else #define SDCARDDETECT -1 // Ramps does not use this port #endif - + #endif - - #if MOTHERBOARD == 77 - #define BEEPER -1 - - #define LCD_PINS_RS 27 - #define LCD_PINS_ENABLE 29 - #define LCD_PINS_D4 37 - #define LCD_PINS_D5 35 - #define LCD_PINS_D6 33 - #define LCD_PINS_D7 31 - - //buttons - #define BTN_EN1 16 - #define BTN_EN2 17 - #define BTN_ENC 23 //the click - - #endif + + #if MOTHERBOARD == 77 + #define BEEPER -1 + + #define LCD_PINS_RS 27 + #define LCD_PINS_ENABLE 29 + #define LCD_PINS_D4 37 + #define LCD_PINS_D5 35 + #define LCD_PINS_D6 33 + #define LCD_PINS_D7 31 + + //buttons + #define BTN_EN1 16 + #define BTN_EN2 17 + #define BTN_ENC 23 //the click + + #endif #else //old style panel with shift register //arduino pin witch triggers an piezzo beeper #define BEEPER 33 //No Beeper added @@ -537,14 +761,14 @@ //#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 - #endif + #endif #endif //ULTRA_LCD #else // RAMPS_V_1_1 or RAMPS_V_1_2 as default (MOTHERBOARD == 3) @@ -589,16 +813,16 @@ #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 || MOTHERBOARD == 35 || MOTHERBOARD == 77 -// 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 @@ -732,17 +956,17 @@ #define BTN_EN1 14 #define BTN_EN2 39 #define BTN_ENC 15 //the click - + #define BLEN_C 2 #define BLEN_B 1 #define BLEN_A 0 - + //encoder rotation values #define encrot0 0 #define encrot1 2 #define encrot2 3 #define encrot3 1 - + #endif //RA_CONTROL_PANEL #ifdef RA_DISCO @@ -756,7 +980,7 @@ //This currently only works with the RA Board. #define TLC_CLOCK_BIT 3 //bit 3 on port A #define TLC_CLOCK_PORT &PORTA //bit 3 on port A - + #define TLC_BLANK_BIT 1 //bit 1 on port A #define TLC_BLANK_PORT &PORTA //bit 1 on port A @@ -766,12 +990,12 @@ #define TLC_XLAT_BIT 0 //bit 0 on port A #define TLC_XLAT_PORT &PORTA //bit 0 on port A - //change this to match your situation. Lots of TLCs takes up the arduino SRAM very quickly, so be careful + //change this to match your situation. Lots of TLCs takes up the arduino SRAM very quickly, so be careful //Leave it at at least 1 if you have enabled RA_LIGHTING //The number of TLC5947 boards chained together for use with the animation, additional ones will repeat the animation on them, but are not individually addressable and mimic those before them. You can leave the default at 2 even if you only have 1 TLC5947 module. - #define NUM_TLCS 2 + #define NUM_TLCS 2 - //These TRANS_ARRAY values let you change the order the LEDs on the lighting modules will animate for chase functions. + //These TRANS_ARRAY values let you change the order the LEDs on the lighting modules will animate for chase functions. //Modify them according to your specific situation. //NOTE: the array should be 8 long for every TLC you have. These defaults assume (2) TLCs. #define TRANS_ARRAY {0, 1, 2, 3, 4, 5, 6, 7, 15, 14, 13, 12, 11, 10, 9, 8} //forwards @@ -866,6 +1090,10 @@ #undef MOTHERBOARD #define MOTHERBOARD 6 #define SANGUINOLOLU_V_1_2 + +#if defined(__AVR_ATmega1284P__) + #define LARGE_FLASH true +#endif #endif #if MOTHERBOARD == 6 #define KNOWN_BOARD 1 @@ -893,23 +1121,39 @@ #define LED_PIN -1 #define FAN_PIN -1 -#if FAN_PIN == 12 || FAN_PIN ==13 -#define FAN_SOFT_PWM + #if FAN_PIN == 12 || FAN_PIN ==13 + #define FAN_SOFT_PWM #endif #ifdef MELZI -#define LED_PIN 27 /* On some broken versions of the Sanguino libraries the pin definitions are wrong, which then needs LED_PIN as pin 28. But you better upgrade your Sanguino libraries! See #368. */ -#define FAN_PIN 4 + #define LED_PIN 27 /* On some broken versions of the Sanguino libraries the pin definitions are wrong, which then needs LED_PIN as pin 28. But you better upgrade your Sanguino libraries! See #368. */ + #define FAN_PIN 4 // Works for Panelolu2 too #endif #ifdef STB -#define FAN_PIN 4 + #define FAN_PIN 4 // Uncomment this if you have the first generation (V1.10) of STBs board -#define LCD_PIN_BL 17 // LCD backlight LED + #define LCD_PIN_BL 17 // LCD backlight LED #endif #ifdef AZTEEG_X1 -#define FAN_PIN 4 + #define FAN_PIN 4 +#endif + +#ifdef NUM_SERVOS + #define SERVO0_PIN -1 + + #if NUM_SERVOS > 1 + #define SERVO1_PIN -1 + #endif + + #if NUM_SERVOS > 2 + #define SERVO2_PIN -1 + #endif + + #if NUM_SERVOS > 3 + #define SERVO3_PIN -1 + #endif #endif #define PS_ON_PIN -1 @@ -921,19 +1165,23 @@ #ifdef SANGUINOLOLU_V_1_2 -#define HEATER_BED_PIN 12 // (bed) -#define X_ENABLE_PIN 14 -#define Y_ENABLE_PIN 14 -#define Z_ENABLE_PIN 26 -#define E0_ENABLE_PIN 14 + #define HEATER_BED_PIN 12 // (bed) + #define X_ENABLE_PIN 14 + #define Y_ENABLE_PIN 14 + #define Z_ENABLE_PIN 26 + #define E0_ENABLE_PIN 14 + + #ifdef LCD_I2C_PANELOLU2 + #define FAN_PIN 4 // Uses Transistor1 (PWM) on Panelolu2's Sanguino Adapter Board to drive the fan + #endif #else -#define HEATER_BED_PIN 14 // (bed) +#define HEATER_BED_PIN 14 // (bed) #define X_ENABLE_PIN -1 #define Y_ENABLE_PIN -1 #define Z_ENABLE_PIN -1 -#define E0_ENABLE_PIN -1 +#define E0_ENABLE_PIN -1 #endif @@ -972,8 +1220,8 @@ #define LCD_PINS_D7 27 #endif //The encoder and click button - #define BTN_EN1 11 - #define BTN_EN2 10 + #define BTN_EN1 11 + #define BTN_EN2 10 #ifdef LCD_I2C_PANELOLU2 #ifdef MELZI #define BTN_ENC 29 //the click switch @@ -985,8 +1233,8 @@ #define BTN_ENC 16 //the click switch #endif //Panelolu2 //not connected to a pin - #define SDCARDDETECT -1 - + #define SDCARDDETECT -1 + #endif //Newpanel #endif //Ultipanel @@ -1008,7 +1256,7 @@ #define BTN_EN2 10 #define BTN_ENC 16 //the click switch //not connected to a pin - #define SDCARDDETECT -1 + #define SDCARDDETECT -1 #endif //Makrpanel #endif @@ -1091,9 +1339,9 @@ #define BTN_EN1 40 #define BTN_EN2 42 #define BTN_ENC 19 //the click - + #define SDCARDDETECT 38 - + #else //old style panel with shift register //arduino pin witch triggers an piezzo beeper #define BEEPER 18 @@ -1110,9 +1358,9 @@ #define LCD_PINS_D5 21 #define LCD_PINS_D6 20 #define LCD_PINS_D7 19 - + #define SDCARDDETECT -1 - #endif + #endif #endif //ULTRA_LCD #endif @@ -1186,6 +1434,90 @@ #endif +#if MOTHERBOARD == 72 +#define KNOWN_BOARD +/***************************************************************** +* Ultiboard v2.0 pin assignment +******************************************************************/ + +#ifndef __AVR_ATmega2560__ + #error Oops! Make sure you have 'Arduino Mega 2560' selected from the 'Tools -> Boards' menu. +#endif + +#define X_STEP_PIN 25 +#define X_DIR_PIN 23 +#define X_STOP_PIN 22 +#define X_ENABLE_PIN 27 + +#define Y_STEP_PIN 32 +#define Y_DIR_PIN 33 +#define Y_STOP_PIN 26 +#define Y_ENABLE_PIN 31 + +#define Z_STEP_PIN 35 +#define Z_DIR_PIN 36 +#define Z_STOP_PIN 29 +#define Z_ENABLE_PIN 34 + +#define HEATER_BED_PIN 4 +#define TEMP_BED_PIN 10 + +#define HEATER_0_PIN 2 +#define TEMP_0_PIN 8 + +#define HEATER_1_PIN 3 +#define TEMP_1_PIN 9 + +#define HEATER_2_PIN -1 +#define TEMP_2_PIN -1 + +#define E0_STEP_PIN 42 +#define E0_DIR_PIN 43 +#define E0_ENABLE_PIN 37 + +#define E1_STEP_PIN 49 +#define E1_DIR_PIN 47 +#define E1_ENABLE_PIN 48 + +#define SDPOWER -1 +#define SDSS 53 +#define LED_PIN 8 +#define FAN_PIN 7 +#define PS_ON_PIN -1 +#define KILL_PIN -1 +#define SUICIDE_PIN -1 //PIN that has to be turned on right after start, to keep power flowing. +#define SAFETY_TRIGGERED_PIN 28 //PIN to detect the safety circuit has triggered +#define MAIN_VOLTAGE_MEASURE_PIN 14 //Analogue PIN to measure the main voltage, with a 100k - 4k7 resitor divider. + +#define MOTOR_CURRENT_PWM_XY_PIN 44 +#define MOTOR_CURRENT_PWM_Z_PIN 45 +#define MOTOR_CURRENT_PWM_E_PIN 46 +//Motor current PWM conversion, PWM value = MotorCurrentSetting * 255 / range +#define MOTOR_CURRENT_PWM_RANGE 2000 +#define DEFAULT_PWM_MOTOR_CURRENT {1300, 1300, 1250} + +//arduino pin witch triggers an piezzo beeper +#define BEEPER 18 + +#define LCD_PINS_RS 20 +#define LCD_PINS_ENABLE 15 +#define LCD_PINS_D4 14 +#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 41 +#define BTN_ENC 19 //the click + +#define BLEN_C 2 +#define BLEN_B 1 +#define BLEN_A 0 + +#define SDCARDDETECT 39 + +#endif//MOTHERBOARD == 72 /**************************************************************************************** * RUMBA pin assignment @@ -1246,7 +1578,7 @@ #else #define TEMP_0_PIN 15 // ANALOG NUMBERING - default connector for thermistor *T0* on rumba board is used #endif -#endif +#endif #if (TEMP_SENSOR_1==0) #define TEMP_1_PIN -1 @@ -1318,6 +1650,10 @@ #error Oops! Make sure you have 'Teensy++ 2.0' selected from the 'Tools -> Boards' menu. #endif +#ifdef AT90USBxx_TEENSYPP_ASSIGNMENTS // use Teensyduino Teensy++2.0 pin assignments instead of Marlin traditional. +#error These Teensylu/Printrboard assignments depend on traditional Marlin assignments, not AT90USBxx_TEENSYPP_ASSIGNMENTS in fastio.h +#endif + #define LARGE_FLASH true #define X_STEP_PIN 0 @@ -1440,6 +1776,213 @@ #endif // MOTHERBOARD == 82 (Brainwave) +// +// SAV Mk-I +// ----------------------------------------------------------------------------------- +/**************************************************************************************** +* SAV MkI pin assignments (AT90USB1286) +* Requires the Teensyduino software with Teensy++ 2.0 selected in Arduino IDE! + http://www.pjrc.com/teensy/teensyduino.html + RepRap Clone Wars project board. +****************************************************************************************/ +#if MOTHERBOARD == 83 // SAV Mk-I +#define KNOWN_BOARD 1 +#define AT90USB 1286 // Disable MarlinSerial etc. + +#ifndef __AVR_AT90USB1286__ +#error Oops! Make sure you have 'Teensy++ 2.0' selected from the 'Tools -> Boards' menu. +#endif + +#define LARGE_FLASH true + + +#define X_STEP_PIN 0 +#define X_DIR_PIN 1 +#define X_ENABLE_PIN 39 + +#define Y_STEP_PIN 2 +#define Y_DIR_PIN 3 +#define Y_ENABLE_PIN 38 + +#define Z_STEP_PIN 4 +#define Z_DIR_PIN 5 +#define Z_ENABLE_PIN 23 + +#define E0_STEP_PIN 6 +#define E0_DIR_PIN 7 +#define E0_ENABLE_PIN 19 + +#define HEATER_0_PIN 21 // Extruder +#define HEATER_1_PIN -1 +#define HEATER_2_PIN -1 +#define HEATER_BED_PIN 20 // Bed +#define FAN_PIN 16 // Fan -- from Teensyduino environment. + // For the fan and Teensyduino uses a different pin mapping. + + #define X_STOP_PIN 13 + #define Y_STOP_PIN 14 + #define Z_STOP_PIN 15 + #define TEMP_0_PIN 7 // Extruder / Analog pin numbering + #define TEMP_BED_PIN 6 // Bed / Analog pin numbering + +#define TEMP_1_PIN -1 +#define TEMP_2_PIN -1 + +#define SDPOWER -1 +#define SDSS 20 // PB0 - 8 in marlin env. +#define LED_PIN -1 +#define PS_ON_PIN -1 +#define KILL_PIN -1 +#define ALARM_PIN -1 +#define SDCARDDETECT -1 + + +#ifndef SDSUPPORT + // these pins are defined in the SD library if building with SD support + #define SCK_PIN 9 + #define MISO_PIN 11 + #define MOSI_PIN 10 +#endif + +#define BEEPER -1 +#define LCD_PINS_RS -1 +#define LCD_PINS_ENABLE -1 +#define LCD_PINS_D4 -1 +#define LCD_PINS_D5 -1 +#define LCD_PINS_D6 -1 +#define LCD_PINS_D7 -1 +#define BTN_EN1 -1 +#define BTN_EN2 -1 +#define BTN_ENC -1 + +// For LCD SHIFT register LCD +#define SR_DATA_PIN 0 +#define SR_CLK_PIN 1 + +#endif // MOTHERBOARD == 83 + +/**************************************************************************************** +* Teensy++ 2.0 Breadboard pin assignments (AT90USB1286) +* Requires the Teensyduino software with Teensy++ 2.0 selected in Arduino IDE! + http://www.pjrc.com/teensy/teensyduino.html +* See http://reprap.org/wiki/Printrboard for more info +* CLI build: DEFINES=AT90USBxx_TEENSYPP_ASSIGNMENTS HARDWARE_MOTHERBOARD=84 make +* +****************************************************************************************/ +#if MOTHERBOARD == 84 +#define KNOWN_BOARD 1 +#define AT90USB 1286 // Disable MarlinSerial etc. + +#ifndef __AVR_AT90USB1286__ +#error Oops! Make sure you have 'Teensy++ 2.0' selected from the 'Tools -> Boards' menu. +#endif + +#define LARGE_FLASH true + +/* +DaveX plan for Teensylu/printrboard-type pinouts (ref teensylu & sprinter) for a TeensyBreadboard: + + USB + GND GND |-----#####-----| +5V ATX +5SB + ATX PS_ON PWM 27 |b7 ##### b6| 26 PWM* Stepper Enable + PWM 0 |d0 b5| 25 PWM* + PWM 1 |d1 b4| 24 PWM + X_MIN 2 |d2 b3| 23 MISO_PIN + Y_MIN 3 |d3 b2| 22 MOSI_PIN + Z_MIN 4 |d4 * * b1| 21 SCK_PIN + 5 |d5 e e b0| 20 SDSS + LED 6 |d6 5 4 e7| 19 + 7 |d7 e6| 18 + LCD RS 8 |e0 | GND + LCD EN 9 |e1 a4 a0 R| AREF + LCD D4 10 |c0 a5 a1 f0| 38 A0 ENC_1 + LCD D5 11 |c1 a6 a2 f1| 39 A1 ENC_2 + LCD D6 12 |c2 a7 a3 f2| 40 A2 ENC_CLK + LCD D6 13 |c3 f3| 41 A3 + Bed Heat PWM 14 |c4 V G R f4| 42 A4 + Extruder Heat PWM 15 |c5 c n S f5| 43 A5 + Fan PWM 16 |c6 c d T f6| 44 A6 Bed TC + 17 |c7 * * * f7| 45 A7 Extruder TC * 4.7k * +5 + ----------------- + + Interior E4: 36, INT4 + Interior E5: 37, INT5 + Interior PA0-7: 28-35 -- Printrboard and Teensylu use these pins for step & direction: + T++ PA Signal Marlin + + Z STEP 32 a4 a0 28 X STEP + Z DIR 33 a5 a1 29 X DIR + E STEP 34 a6 a2 30 Y STEP + E DIR 35 a7 a3 31 Y DIR + +*/ + +#ifndef AT90USBxx_TEENSYPP_ASSIGNMENTS // use Teensyduino Teensy++2.0 pin assignments instead of Marlin alphabetical. + #error Uncomment #define AT90USBxx_TEENSYPP_ASSIGNMENTS in fastio.h for this config + // or build from command line with: DEFINES=AT90USBxx_TEENSYPP_ASSIGNMENTS HARDWARE_MOTHERBOARD=84 make +#endif + +#define X_STEP_PIN 28 // 0 Marlin +#define X_DIR_PIN 29 // 1 Marlin +#define X_ENABLE_PIN 26 + +#define Y_STEP_PIN 30 // 2 Marlin +#define Y_DIR_PIN 31 // 3 +#define Y_ENABLE_PIN 26 // Shared w/x + +#define Z_STEP_PIN 32 // 4 +#define Z_DIR_PIN 33 // 5 +#define Z_ENABLE_PIN 26 // Shared w/x + +#define E0_STEP_PIN 34 // 6 +#define E0_DIR_PIN 35 // 7 +#define E0_ENABLE_PIN 26 // Shared w/x + +#define HEATER_0_PIN 15 // 21 // Extruder +#define HEATER_1_PIN -1 +#define HEATER_2_PIN -1 +#define HEATER_BED_PIN 14 // 20 // Bed +#define FAN_PIN 16 // 22 // Fan + +#define X_STOP_PIN 2 +#define Y_STOP_PIN 3 +#define Z_STOP_PIN 4 + +#define TEMP_0_PIN 7 // Extruder / Analog pin numbering +#define TEMP_BED_PIN 6 // Bed / Analog pin numbering +#define TEMP_1_PIN -1 +#define TEMP_2_PIN -1 + +#define SDPOWER -1 +#define SDCARDDETECT -1 +#define SDSS 20 // 8 +#define LED_PIN 6 +#define PS_ON_PIN 27 +#define KILL_PIN -1 +#define ALARM_PIN -1 + +#ifndef SDSUPPORT +// these pins are defined in the SD library if building with SD support + #define SCK_PIN 21 // 9 + #define MISO_PIN 23 // 11 + #define MOSI_PIN 22 // 10 +#endif + +#ifdef ULTIPANEL +#define LCD_PINS_RS 8 +#define LCD_PINS_ENABLE 9 +#define LCD_PINS_D4 10 +#define LCD_PINS_D5 11 +#define LCD_PINS_D6 12 +#define LCD_PINS_D7 13 +#define BTN_EN1 38 +#define BTN_EN2 39 +#define BTN_ENC 40 +#endif + +#endif // MOTHERBOARD == 84 (Teensy++2.0 Breadboard) + + /**************************************************************************************** * Gen3+ pin assignment * @@ -1465,8 +2008,8 @@ #define Z_DIR_PIN 28 #define Z_STOP_PIN 30 -#define E_STEP_PIN 17 -#define E_DIR_PIN 21 +#define E0_STEP_PIN 17 +#define E0_DIR_PIN 21 #define LED_PIN -1 @@ -1477,15 +2020,16 @@ #define HEATER_0_PIN 12 // (extruder) -#define HEATER_1_PIN 16 // (bed) +#define HEATER_BED_PIN 16 // (bed) #define X_ENABLE_PIN 19 #define Y_ENABLE_PIN 24 #define Z_ENABLE_PIN 29 -#define E_ENABLE_PIN 13 +#define E0_ENABLE_PIN 13 #define TEMP_0_PIN 0 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!! (pin 33 extruder) -#define TEMP_1_PIN 5 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!! (pin 34 bed) +#define TEMP_1_PIN -1 #define TEMP_2_PIN -1 +#define TEMP_BED_PIN 5 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!! (pin 34 bed) #define SDPOWER -1 #define SDSS 4 #define HEATER_2_PIN -1 @@ -1715,9 +2259,74 @@ #define LED_PIN 13 #define FAN_PIN 8 #define PS_ON_PIN 4 -#define KILL_PIN -1 +#define KILL_PIN -1 //80 with Smart Controller LCD #define SUICIDE_PIN -1 //PIN that has to be turned on right after start, to keep power flowing. +#ifdef ULTRA_LCD + #define KILL_PIN 80 + #ifdef NEWPANEL + //arduino pin which triggers an piezzo beeper + #define BEEPER 79 // Beeper on AUX-4 + #define LCD_PINS_RS 70 + #define LCD_PINS_ENABLE 71 + #define LCD_PINS_D4 72 + #define LCD_PINS_D5 73 + #define LCD_PINS_D6 74 + #define LCD_PINS_D7 75 + + //buttons are directly attached using AUX-2 + #define BTN_EN1 76 + #define BTN_EN2 77 + #define BTN_ENC 78 //the click + + #define BLEN_C 2 + #define BLEN_B 1 + #define BLEN_A 0 + + #define SDCARDDETECT 81 // Ramps does not use this port + + //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 33 No Beeper added + //buttons are attached to a shift register + // Not wired this yet + // #define SHIFT_CLK 38 + // #define SHIFT_LD 42 + // #define SHIFT_OUT 40 + // #define SHIFT_EN 17 + + #define LCD_PINS_RS 75 + #define LCD_PINS_ENABLE 17 + #define LCD_PINS_D4 23 + #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 + + #endif /**************************************************************************************** @@ -1805,13 +2414,13 @@ #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 @@ -1828,102 +2437,102 @@ ****************************************************************************************/ #if MOTHERBOARD == 701 #define KNOWN_BOARD 1 - - + + #ifndef __AVR_ATmega2560__ #error Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu. #endif - + #define LARGE_FLASH true - + #define X_STEP_PIN 26 #define X_DIR_PIN 27 #define X_ENABLE_PIN 25 #define X_MIN_PIN 37 #define X_MAX_PIN 40 //2 //Max endstops default to disabled "-1", set to commented value to enable. - + #define Y_STEP_PIN 4 // A6 #define Y_DIR_PIN 54 // A0 #define Y_ENABLE_PIN 5 #define Y_MIN_PIN 41 #define Y_MAX_PIN 38 //15 - + #define Z_STEP_PIN 56 // A2 #define Z_DIR_PIN 60 // A6 #define Z_ENABLE_PIN 55 // A1 #define Z_MIN_PIN 18 #define Z_MAX_PIN 19 - + #define E0_STEP_PIN 35 #define E0_DIR_PIN 36 #define E0_ENABLE_PIN 34 - + #define E1_STEP_PIN 29 #define E1_DIR_PIN 39 #define E1_ENABLE_PIN 28 - + #define E2_STEP_PIN 23 #define E2_DIR_PIN 24 #define E2_ENABLE_PIN 22 - + #define SDPOWER -1 #define SDSS 53 #define LED_PIN 13 - + #define FAN_PIN 7 #define FAN2_PIN 6 #define PS_ON_PIN 12 #define KILL_PIN -1 - + #define HEATER_0_PIN 9 // EXTRUDER 1 #define HEATER_1_PIN 8 // EXTRUDER 2 #define HEATER_2_PIN -1 - + #if TEMP_SENSOR_0 == -1 #define TEMP_0_PIN 4 // ANALOG NUMBERING #else #define TEMP_0_PIN 13 // ANALOG NUMBERING #endif - - + + #if TEMP_SENSOR_1 == -1 #define TEMP_1_PIN 8 // ANALOG NUMBERING #else #define TEMP_1_PIN 15 // ANALOG NUMBERING #endif - + #define TEMP_2_PIN -1 // ANALOG NUMBERING - + #define HEATER_BED_PIN 10 // BED - + #if TEMP_SENSOR_BED == -1 #define TEMP_BED_PIN 8 // ANALOG NUMBERING - #else + #else #define TEMP_BED_PIN 14 // ANALOG NUMBERING #endif - - #define BEEPER 64 - - + + #define BEEPER 64 + + #define LCD_PINS_RS 14 #define LCD_PINS_ENABLE 15 #define LCD_PINS_D4 30 #define LCD_PINS_D5 31 #define LCD_PINS_D6 32 #define LCD_PINS_D7 33 - - + + //buttons are directly attached using keypad #define BTN_EN1 61 #define BTN_EN2 59 #define BTN_ENC 43 //the click - + #define BLEN_C 2 #define BLEN_B 1 #define BLEN_A 0 - + #define SDCARDDETECT -1 // Megatronics does not use this port - + //encoder rotation values #define encrot0 0 #define encrot1 2 @@ -1939,87 +2548,87 @@ ****************************************************************************************/ #if MOTHERBOARD == 702 #define KNOWN_BOARD 1 - - + + #ifndef __AVR_ATmega1281__ #error Oops! Make sure you have 'Minitronics ' selected from the 'Tools -> Boards' menu. #endif - + #define LARGE_FLASH true - + #define X_STEP_PIN 48 #define X_DIR_PIN 47 #define X_ENABLE_PIN 49 #define X_MIN_PIN 5 #define X_MAX_PIN -1 //2 //Max endstops default to disabled "-1", set to commented value to enable. - + #define Y_STEP_PIN 39 // A6 #define Y_DIR_PIN 40 // A0 #define Y_ENABLE_PIN 38 #define Y_MIN_PIN 2 #define Y_MAX_PIN -1 //15 - + #define Z_STEP_PIN 42 // A2 #define Z_DIR_PIN 43 // A6 #define Z_ENABLE_PIN 41 // A1 #define Z_MIN_PIN 6 #define Z_MAX_PIN -1 - + #define E0_STEP_PIN 45 #define E0_DIR_PIN 44 #define E0_ENABLE_PIN 27 - + #define E1_STEP_PIN 36 #define E1_DIR_PIN 35 #define E1_ENABLE_PIN 37 - + #define E2_STEP_PIN -1 #define E2_DIR_PIN -1 #define E2_ENABLE_PIN -1 - + #define SDPOWER -1 #define SDSS 16 #define LED_PIN 46 - + #define FAN_PIN 9 #define FAN2_PIN -1 #define PS_ON_PIN -1 #define KILL_PIN -1 - + #define HEATER_0_PIN 7 // EXTRUDER 1 #define HEATER_1_PIN 8 // EXTRUDER 2 #define HEATER_2_PIN -1 - + #define TEMP_0_PIN 7 // ANALOG NUMBERING #define TEMP_1_PIN 6 // ANALOG NUMBERING #define TEMP_2_PIN -1 // ANALOG NUMBERING - + #define HEATER_BED_PIN 3 // BED #define TEMP_BED_PIN 6 // ANALOG NUMBERING - - #define BEEPER -1 - - + + #define BEEPER -1 + + #define LCD_PINS_RS -1 #define LCD_PINS_ENABLE -1 #define LCD_PINS_D4 -1 #define LCD_PINS_D5 -1 #define LCD_PINS_D6 -1 #define LCD_PINS_D7 -1 - - + + //buttons are directly attached using keypad #define BTN_EN1 -1 #define BTN_EN2 -1 #define BTN_ENC -1 //the click - + #define BLEN_C 2 #define BLEN_B 1 #define BLEN_A 0 - + #define SDCARDDETECT -1 // Megatronics does not use this port - + //encoder rotation values #define encrot0 0 #define encrot1 2 @@ -2028,6 +2637,107 @@ #endif +/**************************************************************************************** +* Cheaptronic v1.0 +* +****************************************************************************************/ +#if MOTHERBOARD == 2 + #define KNOWN_BOARD 1 + + #ifndef __AVR_ATmega2560__ + #error Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu. + #endif + + #define LARGE_FLASH true + + //X motor stepper + #define X_STEP_PIN 14 + #define X_DIR_PIN 15 + #define X_ENABLE_PIN 24 + + //X endstop + #define X_MIN_PIN 3 + #define X_MAX_PIN -1 + + //Y motor stepper + #define Y_STEP_PIN 35 + #define Y_DIR_PIN 36 + #define Y_ENABLE_PIN 31 + + //Y endstop + #define Y_MIN_PIN 2 + #define Y_MAX_PIN -1 + + //Z motor stepper + #define Z_STEP_PIN 40 + #define Z_DIR_PIN 41 + #define Z_ENABLE_PIN 37 + + //Z endstop + #define Z_MIN_PIN 5 + #define Z_MAX_PIN -1 + + //Extruder 0 stepper + #define E0_STEP_PIN 26 + #define E0_DIR_PIN 28 + #define E0_ENABLE_PIN 25 + + //Extruder 1 stepper + #define E1_STEP_PIN 33 + #define E1_DIR_PIN 34 + #define E1_ENABLE_PIN 30 + + #define SDPOWER -1 + #define SDSS -1 + #define LED_PIN -1 + + //FAN + #define FAN_PIN -1 + + #define PS_ON_PIN -1 + #define KILL_PIN -1 + + #define HEATER_0_PIN 19 // EXTRUDER 1 + #define HEATER_1_PIN 23 // EXTRUDER 2 + //HeatedBad + #define HEATER_BED_PIN 22 + //Cheaptronic v1.0 hasent EXTRUDER 3 + #define HEATER_2_PIN -1 + + //Temperature sensors + #define TEMP_0_PIN 15 + #define TEMP_1_PIN 14 + #define TEMP_2_PIN -1 + #define TEMP_BED_PIN 13 + + //Cheaptronic v1.0 dont support LCD + #define LCD_PINS_RS -1 + #define LCD_PINS_ENABLE -1 + #define LCD_PINS_D4 -1 + #define LCD_PINS_D5 -1 + #define LCD_PINS_D6 -1 + #define LCD_PINS_D7 -1 + + //Cheaptronic v1.0 dont support keypad + #define BTN_EN1 -1 + #define BTN_EN2 -1 + #define BTN_ENC -1 + + #define BLEN_C 2 + #define BLEN_B 1 + #define BLEN_A 0 + + //Cheaptronic v1.0 does not use this port + #define SDCARDDETECT -1 + + //encoder rotation values + #define encrot0 0 + #define encrot1 2 + #define encrot2 3 + #define encrot3 1 + +#endif + #ifndef KNOWN_BOARD diff --git a/Marlin/planner.cpp b/Marlin/planner.cpp index 8eff19175..5b20f86f9 100644 --- a/Marlin/planner.cpp +++ b/Marlin/planner.cpp @@ -75,6 +75,15 @@ float max_e_jerk; float mintravelfeedrate; unsigned long axis_steps_per_sqr_second[NUM_AXIS]; +#ifdef ENABLE_AUTO_BED_LEVELING +// this holds the required transform to compensate for bed level +matrix_3x3 plan_bed_level_matrix = { + 1.0, 0.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 0.0, 1.0, +}; +#endif // #ifdef ENABLE_AUTO_BED_LEVELING + // The current position of the tool in absolute steps long position[4]; //rescaled from extern when axis_steps_per_unit are changed by gcode static float previous_speed[4]; // Speed of previous path line segment @@ -177,9 +186,9 @@ void calculate_trapezoid_for_block(block_t *block, float entry_factor, float exi long acceleration = block->acceleration_st; int32_t accelerate_steps = - ceil(estimate_acceleration_distance(block->initial_rate, block->nominal_rate, acceleration)); + ceil(estimate_acceleration_distance(initial_rate, block->nominal_rate, acceleration)); int32_t decelerate_steps = - floor(estimate_acceleration_distance(block->nominal_rate, block->final_rate, -acceleration)); + floor(estimate_acceleration_distance(block->nominal_rate, final_rate, -acceleration)); // Calculate the size of Plateau of Nominal Rate. int32_t plateau_steps = block->step_event_count-accelerate_steps-decelerate_steps; @@ -188,7 +197,7 @@ void calculate_trapezoid_for_block(block_t *block, float entry_factor, float exi // have to use intersection_distance() to calculate when to abort acceleration and start braking // in order to reach the final_rate exactly at the end of this block. if (plateau_steps < 0) { - accelerate_steps = ceil(intersection_distance(block->initial_rate, block->final_rate, acceleration, block->step_event_count)); + accelerate_steps = ceil(intersection_distance(initial_rate, final_rate, acceleration, block->step_event_count)); accelerate_steps = max(accelerate_steps,0); // Check limits due to numerical round-off accelerate_steps = min((uint32_t)accelerate_steps,block->step_event_count);//(We can cast here to unsigned, because the above line ensures that we are above zero) plateau_steps = 0; @@ -513,7 +522,11 @@ float junction_deviation = 0.1; // Add a new linear movement to the buffer. steps_x, _y and _z is the absolute position in // mm. Microseconds specify how many microseconds the move should take to perform. To aid acceleration // calculation the caller must also provide the physical length of the line in millimeters. +#ifdef ENABLE_AUTO_BED_LEVELING +void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate, const uint8_t &extruder) +#else void plan_buffer_line(const float &x, const float &y, const float &z, const float &e, float feed_rate, const uint8_t &extruder) +#endif //ENABLE_AUTO_BED_LEVELING { // Calculate the buffer head after we push this byte int next_buffer_head = next_block_index(block_buffer_head); @@ -527,6 +540,10 @@ void plan_buffer_line(const float &x, const float &y, const float &z, const floa lcd_update(); } +#ifdef ENABLE_AUTO_BED_LEVELING + apply_rotation_xyz(plan_bed_level_matrix, x, y, z); +#endif // ENABLE_AUTO_BED_LEVELING + // The target position of the tool in absolute steps // Calculate target position in absolute steps //this should be done after the wait, because otherwise a M92 code within the gcode disrupts this calculation somehow @@ -576,6 +593,7 @@ block->steps_y = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-positi #endif block->steps_z = labs(target[Z_AXIS]-position[Z_AXIS]); block->steps_e = labs(target[E_AXIS]-position[E_AXIS]); + block->steps_e *= volumetric_multiplier[active_extruder]; block->steps_e *= extrudemultiply; block->steps_e /= 100; block->step_event_count = max(block->steps_x, max(block->steps_y, max(block->steps_z, block->steps_e))); @@ -639,12 +657,24 @@ block->steps_y = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-positi if(block->steps_z != 0) enable_z(); #endif - // Enable all + // Enable extruder(s) if(block->steps_e != 0) { - enable_e0(); - enable_e1(); - enable_e2(); + if (DISABLE_INACTIVE_EXTRUDER) //enable only selected extruder + { + switch(extruder) + { + case 0: enable_e0(); disable_e1(); disable_e2(); break; + case 1: disable_e0(); enable_e1(); disable_e2(); break; + case 2: disable_e0(); disable_e1(); enable_e2(); break; + } + } + else //enable all + { + enable_e0(); + enable_e1(); + enable_e2(); + } } if (block->steps_e == 0) @@ -665,7 +695,7 @@ block->steps_y = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-positi delta_mm[Y_AXIS] = ((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-position[Y_AXIS]))/axis_steps_per_unit[Y_AXIS]; #endif delta_mm[Z_AXIS] = (target[Z_AXIS]-position[Z_AXIS])/axis_steps_per_unit[Z_AXIS]; - delta_mm[E_AXIS] = ((target[E_AXIS]-position[E_AXIS])/axis_steps_per_unit[E_AXIS])*extrudemultiply/100.0; + delta_mm[E_AXIS] = ((target[E_AXIS]-position[E_AXIS])/axis_steps_per_unit[E_AXIS])*volumetric_multiplier[active_extruder]*extrudemultiply/100.0; if ( block->steps_x <=dropsegments && block->steps_y <=dropsegments && block->steps_z <=dropsegments ) { block->millimeters = fabs(delta_mm[E_AXIS]); @@ -919,8 +949,30 @@ block->steps_y = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-positi st_wake_up(); } +#ifdef ENABLE_AUTO_BED_LEVELING +vector_3 plan_get_position() { + vector_3 position = vector_3(st_get_position_mm(X_AXIS), st_get_position_mm(Y_AXIS), st_get_position_mm(Z_AXIS)); + + //position.debug("in plan_get position"); + //plan_bed_level_matrix.debug("in plan_get bed_level"); + matrix_3x3 inverse = matrix_3x3::transpose(plan_bed_level_matrix); + //inverse.debug("in plan_get inverse"); + position.apply_rotation(inverse); + //position.debug("after rotation"); + + return position; +} +#endif // ENABLE_AUTO_BED_LEVELING + +#ifdef ENABLE_AUTO_BED_LEVELING +void plan_set_position(float x, float y, float z, const float &e) +{ + apply_rotation_xyz(plan_bed_level_matrix, x, y, z); +#else void plan_set_position(const float &x, const float &y, const float &z, const float &e) { +#endif // ENABLE_AUTO_BED_LEVELING + position[X_AXIS] = lround(x*axis_steps_per_unit[X_AXIS]); position[Y_AXIS] = lround(y*axis_steps_per_unit[Y_AXIS]); position[Z_AXIS] = lround(z*axis_steps_per_unit[Z_AXIS]); diff --git a/Marlin/planner.h b/Marlin/planner.h index 597eeb1c0..837199eb7 100644 --- a/Marlin/planner.h +++ b/Marlin/planner.h @@ -26,6 +26,10 @@ #include "Marlin.h" +#ifdef ENABLE_AUTO_BED_LEVELING +#include "vector_3.h" +#endif // ENABLE_AUTO_BED_LEVELING + // This struct is used when buffering the setup for each linear movement "nominal" values are as specified in // the source g-code and may never actually be reached if acceleration management is active. typedef struct { @@ -67,15 +71,33 @@ typedef struct { volatile char busy; } block_t; +#ifdef ENABLE_AUTO_BED_LEVELING +// this holds the required transform to compensate for bed level +extern matrix_3x3 plan_bed_level_matrix; +#endif // #ifdef ENABLE_AUTO_BED_LEVELING + // Initialize the motion plan subsystem void plan_init(); // Add a new linear movement to the buffer. x, y and z is the signed, absolute target position in // millimaters. Feed rate specifies the speed of the motion. + +#ifdef ENABLE_AUTO_BED_LEVELING +void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate, const uint8_t &extruder); + +// Get the position applying the bed level matrix if enabled +vector_3 plan_get_position(); +#else void plan_buffer_line(const float &x, const float &y, const float &z, const float &e, float feed_rate, const uint8_t &extruder); +#endif // ENABLE_AUTO_BED_LEVELING // Set position. Used for G92 instructions. +#ifdef ENABLE_AUTO_BED_LEVELING +void plan_set_position(float x, float y, float z, const float &e); +#else void plan_set_position(const float &x, const float &y, const float &z, const float &e); +#endif // ENABLE_AUTO_BED_LEVELING + void plan_set_e_position(const float &e); @@ -129,7 +151,7 @@ FORCE_INLINE block_t *plan_get_current_block() return(block); } -// Gets the current block. Returns NULL if buffer empty +// Returns true if the buffer has a queued block, false otherwise FORCE_INLINE bool blocks_queued() { if (block_buffer_head == block_buffer_tail) { diff --git a/Marlin/qr_solve.cpp b/Marlin/qr_solve.cpp new file mode 100644 index 000000000..f19d989d4 --- /dev/null +++ b/Marlin/qr_solve.cpp @@ -0,0 +1,1930 @@ +#include "qr_solve.h" + +#ifdef AUTO_BED_LEVELING_GRID + +#include +#include + +//# include "r8lib.h" + +int i4_min ( int i1, int i2 ) + +/******************************************************************************/ +/* + Purpose: + + I4_MIN returns the smaller of two I4's. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 29 August 2006 + + Author: + + John Burkardt + + Parameters: + + Input, int I1, I2, two integers to be compared. + + Output, int I4_MIN, the smaller of I1 and I2. +*/ +{ + int value; + + if ( i1 < i2 ) + { + value = i1; + } + else + { + value = i2; + } + return value; +} + +double r8_epsilon ( void ) + +/******************************************************************************/ +/* + Purpose: + + R8_EPSILON returns the R8 round off unit. + + Discussion: + + R8_EPSILON is a number R which is a power of 2 with the property that, + to the precision of the computer's arithmetic, + 1 < 1 + R + but + 1 = ( 1 + R / 2 ) + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 01 September 2012 + + Author: + + John Burkardt + + Parameters: + + Output, double R8_EPSILON, the R8 round-off unit. +*/ +{ + const double value = 2.220446049250313E-016; + + return value; +} + +double r8_max ( double x, double y ) + +/******************************************************************************/ +/* + Purpose: + + R8_MAX returns the maximum of two R8's. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 07 May 2006 + + Author: + + John Burkardt + + Parameters: + + Input, double X, Y, the quantities to compare. + + Output, double R8_MAX, the maximum of X and Y. +*/ +{ + double value; + + if ( y < x ) + { + value = x; + } + else + { + value = y; + } + return value; +} + +double r8_abs ( double x ) + +/******************************************************************************/ +/* + Purpose: + + R8_ABS returns the absolute value of an R8. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 07 May 2006 + + Author: + + John Burkardt + + Parameters: + + Input, double X, the quantity whose absolute value is desired. + + Output, double R8_ABS, the absolute value of X. +*/ +{ + double value; + + if ( 0.0 <= x ) + { + value = + x; + } + else + { + value = - x; + } + return value; +} + +double r8_sign ( double x ) + +/******************************************************************************/ +/* + Purpose: + + R8_SIGN returns the sign of an R8. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 08 May 2006 + + Author: + + John Burkardt + + Parameters: + + Input, double X, the number whose sign is desired. + + Output, double R8_SIGN, the sign of X. +*/ +{ + double value; + + if ( x < 0.0 ) + { + value = - 1.0; + } + else + { + value = + 1.0; + } + return value; +} + +double r8mat_amax ( int m, int n, double a[] ) + +/******************************************************************************/ +/* + Purpose: + + R8MAT_AMAX returns the maximum absolute value entry of an R8MAT. + + Discussion: + + An R8MAT is a doubly dimensioned array of R8 values, stored as a vector + in column-major order. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 07 September 2012 + + Author: + + John Burkardt + + Parameters: + + Input, int M, the number of rows in A. + + Input, int N, the number of columns in A. + + Input, double A[M*N], the M by N matrix. + + Output, double R8MAT_AMAX, the maximum absolute value entry of A. +*/ +{ + int i; + int j; + double value; + + value = r8_abs ( a[0+0*m] ); + + for ( j = 0; j < n; j++ ) + { + for ( i = 0; i < m; i++ ) + { + if ( value < r8_abs ( a[i+j*m] ) ) + { + value = r8_abs ( a[i+j*m] ); + } + } + } + return value; +} + +double *r8mat_copy_new ( int m, int n, double a1[] ) + +/******************************************************************************/ +/* + Purpose: + + R8MAT_COPY_NEW copies one R8MAT to a "new" R8MAT. + + Discussion: + + An R8MAT is a doubly dimensioned array of R8 values, stored as a vector + in column-major order. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 26 July 2008 + + Author: + + John Burkardt + + Parameters: + + Input, int M, N, the number of rows and columns. + + Input, double A1[M*N], the matrix to be copied. + + Output, double R8MAT_COPY_NEW[M*N], the copy of A1. +*/ +{ + double *a2; + int i; + int j; + + a2 = ( double * ) malloc ( m * n * sizeof ( double ) ); + + for ( j = 0; j < n; j++ ) + { + for ( i = 0; i < m; i++ ) + { + a2[i+j*m] = a1[i+j*m]; + } + } + + return a2; +} + +/******************************************************************************/ + +void daxpy ( int n, double da, double dx[], int incx, double dy[], int incy ) + +/******************************************************************************/ +/* + Purpose: + + DAXPY computes constant times a vector plus a vector. + + Discussion: + + This routine uses unrolled loops for increments equal to one. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 30 March 2007 + + Author: + + C version by John Burkardt + + Reference: + + Jack Dongarra, Cleve Moler, Jim Bunch, Pete Stewart, + LINPACK User's Guide, + SIAM, 1979. + + Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh, + Basic Linear Algebra Subprograms for Fortran Usage, + Algorithm 539, + ACM Transactions on Mathematical Software, + Volume 5, Number 3, September 1979, pages 308-323. + + Parameters: + + Input, int N, the number of elements in DX and DY. + + Input, double DA, the multiplier of DX. + + Input, double DX[*], the first vector. + + Input, int INCX, the increment between successive entries of DX. + + Input/output, double DY[*], the second vector. + On output, DY[*] has been replaced by DY[*] + DA * DX[*]. + + Input, int INCY, the increment between successive entries of DY. +*/ +{ + int i; + int ix; + int iy; + int m; + + if ( n <= 0 ) + { + return; + } + + if ( da == 0.0 ) + { + return; + } +/* + Code for unequal increments or equal increments + not equal to 1. +*/ + if ( incx != 1 || incy != 1 ) + { + if ( 0 <= incx ) + { + ix = 0; + } + else + { + ix = ( - n + 1 ) * incx; + } + + if ( 0 <= incy ) + { + iy = 0; + } + else + { + iy = ( - n + 1 ) * incy; + } + + for ( i = 0; i < n; i++ ) + { + dy[iy] = dy[iy] + da * dx[ix]; + ix = ix + incx; + iy = iy + incy; + } + } +/* + Code for both increments equal to 1. +*/ + else + { + m = n % 4; + + for ( i = 0; i < m; i++ ) + { + dy[i] = dy[i] + da * dx[i]; + } + + for ( i = m; i < n; i = i + 4 ) + { + dy[i ] = dy[i ] + da * dx[i ]; + dy[i+1] = dy[i+1] + da * dx[i+1]; + dy[i+2] = dy[i+2] + da * dx[i+2]; + dy[i+3] = dy[i+3] + da * dx[i+3]; + } + } + return; +} +/******************************************************************************/ + +double ddot ( int n, double dx[], int incx, double dy[], int incy ) + +/******************************************************************************/ +/* + Purpose: + + DDOT forms the dot product of two vectors. + + Discussion: + + This routine uses unrolled loops for increments equal to one. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 30 March 2007 + + Author: + + C version by John Burkardt + + Reference: + + Jack Dongarra, Cleve Moler, Jim Bunch, Pete Stewart, + LINPACK User's Guide, + SIAM, 1979. + + Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh, + Basic Linear Algebra Subprograms for Fortran Usage, + Algorithm 539, + ACM Transactions on Mathematical Software, + Volume 5, Number 3, September 1979, pages 308-323. + + Parameters: + + Input, int N, the number of entries in the vectors. + + Input, double DX[*], the first vector. + + Input, int INCX, the increment between successive entries in DX. + + Input, double DY[*], the second vector. + + Input, int INCY, the increment between successive entries in DY. + + Output, double DDOT, the sum of the product of the corresponding + entries of DX and DY. +*/ +{ + double dtemp; + int i; + int ix; + int iy; + int m; + + dtemp = 0.0; + + if ( n <= 0 ) + { + return dtemp; + } +/* + Code for unequal increments or equal increments + not equal to 1. +*/ + if ( incx != 1 || incy != 1 ) + { + if ( 0 <= incx ) + { + ix = 0; + } + else + { + ix = ( - n + 1 ) * incx; + } + + if ( 0 <= incy ) + { + iy = 0; + } + else + { + iy = ( - n + 1 ) * incy; + } + + for ( i = 0; i < n; i++ ) + { + dtemp = dtemp + dx[ix] * dy[iy]; + ix = ix + incx; + iy = iy + incy; + } + } +/* + Code for both increments equal to 1. +*/ + else + { + m = n % 5; + + for ( i = 0; i < m; i++ ) + { + dtemp = dtemp + dx[i] * dy[i]; + } + + for ( i = m; i < n; i = i + 5 ) + { + dtemp = dtemp + dx[i ] * dy[i ] + + dx[i+1] * dy[i+1] + + dx[i+2] * dy[i+2] + + dx[i+3] * dy[i+3] + + dx[i+4] * dy[i+4]; + } + } + return dtemp; +} +/******************************************************************************/ + +double dnrm2 ( int n, double x[], int incx ) + +/******************************************************************************/ +/* + Purpose: + + DNRM2 returns the euclidean norm of a vector. + + Discussion: + + DNRM2 ( X ) = sqrt ( X' * X ) + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 30 March 2007 + + Author: + + C version by John Burkardt + + Reference: + + Jack Dongarra, Cleve Moler, Jim Bunch, Pete Stewart, + LINPACK User's Guide, + SIAM, 1979. + + Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh, + Basic Linear Algebra Subprograms for Fortran Usage, + Algorithm 539, + ACM Transactions on Mathematical Software, + Volume 5, Number 3, September 1979, pages 308-323. + + Parameters: + + Input, int N, the number of entries in the vector. + + Input, double X[*], the vector whose norm is to be computed. + + Input, int INCX, the increment between successive entries of X. + + Output, double DNRM2, the Euclidean norm of X. +*/ +{ + double absxi; + int i; + int ix; + double norm; + double scale; + double ssq; + double value; + + if ( n < 1 || incx < 1 ) + { + norm = 0.0; + } + else if ( n == 1 ) + { + norm = r8_abs ( x[0] ); + } + else + { + scale = 0.0; + ssq = 1.0; + ix = 0; + + for ( i = 0; i < n; i++ ) + { + if ( x[ix] != 0.0 ) + { + absxi = r8_abs ( x[ix] ); + if ( scale < absxi ) + { + ssq = 1.0 + ssq * ( scale / absxi ) * ( scale / absxi ); + scale = absxi; + } + else + { + ssq = ssq + ( absxi / scale ) * ( absxi / scale ); + } + } + ix = ix + incx; + } + + norm = scale * sqrt ( ssq ); + } + + return norm; +} +/******************************************************************************/ + +void dqrank ( double a[], int lda, int m, int n, double tol, int *kr, + int jpvt[], double qraux[] ) + +/******************************************************************************/ +/* + Purpose: + + DQRANK computes the QR factorization of a rectangular matrix. + + Discussion: + + This routine is used in conjunction with DQRLSS to solve + overdetermined, underdetermined and singular linear systems + in a least squares sense. + + DQRANK uses the LINPACK subroutine DQRDC to compute the QR + factorization, with column pivoting, of an M by N matrix A. + The numerical rank is determined using the tolerance TOL. + + Note that on output, ABS ( A(1,1) ) / ABS ( A(KR,KR) ) is an estimate + of the condition number of the matrix of independent columns, + and of R. This estimate will be <= 1/TOL. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 21 April 2012 + + Author: + + C version by John Burkardt. + + Reference: + + Jack Dongarra, Cleve Moler, Jim Bunch, Pete Stewart, + LINPACK User's Guide, + SIAM, 1979, + ISBN13: 978-0-898711-72-1, + LC: QA214.L56. + + Parameters: + + Input/output, double A[LDA*N]. On input, the matrix whose + decomposition is to be computed. On output, the information from DQRDC. + The triangular matrix R of the QR factorization is contained in the + upper triangle and information needed to recover the orthogonal + matrix Q is stored below the diagonal in A and in the vector QRAUX. + + Input, int LDA, the leading dimension of A, which must + be at least M. + + Input, int M, the number of rows of A. + + Input, int N, the number of columns of A. + + Input, double TOL, a relative tolerance used to determine the + numerical rank. The problem should be scaled so that all the elements + of A have roughly the same absolute accuracy, EPS. Then a reasonable + value for TOL is roughly EPS divided by the magnitude of the largest + element. + + Output, int *KR, the numerical rank. + + Output, int JPVT[N], the pivot information from DQRDC. + Columns JPVT(1), ..., JPVT(KR) of the original matrix are linearly + independent to within the tolerance TOL and the remaining columns + are linearly dependent. + + Output, double QRAUX[N], will contain extra information defining + the QR factorization. +*/ +{ + int i; + int j; + int job; + int k; + double *work; + + for ( i = 0; i < n; i++ ) + { + jpvt[i] = 0; + } + + work = ( double * ) malloc ( n * sizeof ( double ) ); + job = 1; + + dqrdc ( a, lda, m, n, qraux, jpvt, work, job ); + + *kr = 0; + k = i4_min ( m, n ); + + for ( j = 0; j < k; j++ ) + { + if ( r8_abs ( a[j+j*lda] ) <= tol * r8_abs ( a[0+0*lda] ) ) + { + return; + } + *kr = j + 1; + } + + free ( work ); + + return; +} +/******************************************************************************/ + +void dqrdc ( double a[], int lda, int n, int p, double qraux[], int jpvt[], + double work[], int job ) + +/******************************************************************************/ +/* + Purpose: + + DQRDC computes the QR factorization of a real rectangular matrix. + + Discussion: + + DQRDC uses Householder transformations. + + Column pivoting based on the 2-norms of the reduced columns may be + performed at the user's option. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 07 June 2005 + + Author: + + C version by John Burkardt. + + Reference: + + Jack Dongarra, Cleve Moler, Jim Bunch and Pete Stewart, + LINPACK User's Guide, + SIAM, (Society for Industrial and Applied Mathematics), + 3600 University City Science Center, + Philadelphia, PA, 19104-2688. + ISBN 0-89871-172-X + + Parameters: + + Input/output, double A(LDA,P). On input, the N by P matrix + whose decomposition is to be computed. On output, A contains in + its upper triangle the upper triangular matrix R of the QR + factorization. Below its diagonal A contains information from + which the orthogonal part of the decomposition can be recovered. + Note that if pivoting has been requested, the decomposition is not that + of the original matrix A but that of A with its columns permuted + as described by JPVT. + + Input, int LDA, the leading dimension of the array A. LDA must + be at least N. + + Input, int N, the number of rows of the matrix A. + + Input, int P, the number of columns of the matrix A. + + Output, double QRAUX[P], contains further information required + to recover the orthogonal part of the decomposition. + + Input/output, integer JPVT[P]. On input, JPVT contains integers that + control the selection of the pivot columns. The K-th column A(*,K) of A + is placed in one of three classes according to the value of JPVT(K). + > 0, then A(K) is an initial column. + = 0, then A(K) is a free column. + < 0, then A(K) is a final column. + Before the decomposition is computed, initial columns are moved to + the beginning of the array A and final columns to the end. Both + initial and final columns are frozen in place during the computation + and only free columns are moved. At the K-th stage of the + reduction, if A(*,K) is occupied by a free column it is interchanged + with the free column of largest reduced norm. JPVT is not referenced + if JOB == 0. On output, JPVT(K) contains the index of the column of the + original matrix that has been interchanged into the K-th column, if + pivoting was requested. + + Workspace, double WORK[P]. WORK is not referenced if JOB == 0. + + Input, int JOB, initiates column pivoting. + 0, no pivoting is done. + nonzero, pivoting is done. +*/ +{ + int j; + int jp; + int l; + int lup; + int maxj; + double maxnrm; + double nrmxl; + int pl; + int pu; + int swapj; + double t; + double tt; + + pl = 1; + pu = 0; +/* + If pivoting is requested, rearrange the columns. +*/ + if ( job != 0 ) + { + for ( j = 1; j <= p; j++ ) + { + swapj = ( 0 < jpvt[j-1] ); + + if ( jpvt[j-1] < 0 ) + { + jpvt[j-1] = -j; + } + else + { + jpvt[j-1] = j; + } + + if ( swapj ) + { + if ( j != pl ) + { + dswap ( n, a+0+(pl-1)*lda, 1, a+0+(j-1), 1 ); + } + jpvt[j-1] = jpvt[pl-1]; + jpvt[pl-1] = j; + pl = pl + 1; + } + } + pu = p; + + for ( j = p; 1 <= j; j-- ) + { + if ( jpvt[j-1] < 0 ) + { + jpvt[j-1] = -jpvt[j-1]; + + if ( j != pu ) + { + dswap ( n, a+0+(pu-1)*lda, 1, a+0+(j-1)*lda, 1 ); + jp = jpvt[pu-1]; + jpvt[pu-1] = jpvt[j-1]; + jpvt[j-1] = jp; + } + pu = pu - 1; + } + } + } +/* + Compute the norms of the free columns. +*/ + for ( j = pl; j <= pu; j++ ) + { + qraux[j-1] = dnrm2 ( n, a+0+(j-1)*lda, 1 ); + } + + for ( j = pl; j <= pu; j++ ) + { + work[j-1] = qraux[j-1]; + } +/* + Perform the Householder reduction of A. +*/ + lup = i4_min ( n, p ); + + for ( l = 1; l <= lup; l++ ) + { +/* + Bring the column of largest norm into the pivot position. +*/ + if ( pl <= l && l < pu ) + { + maxnrm = 0.0; + maxj = l; + for ( j = l; j <= pu; j++ ) + { + if ( maxnrm < qraux[j-1] ) + { + maxnrm = qraux[j-1]; + maxj = j; + } + } + + if ( maxj != l ) + { + dswap ( n, a+0+(l-1)*lda, 1, a+0+(maxj-1)*lda, 1 ); + qraux[maxj-1] = qraux[l-1]; + work[maxj-1] = work[l-1]; + jp = jpvt[maxj-1]; + jpvt[maxj-1] = jpvt[l-1]; + jpvt[l-1] = jp; + } + } +/* + Compute the Householder transformation for column L. +*/ + qraux[l-1] = 0.0; + + if ( l != n ) + { + nrmxl = dnrm2 ( n-l+1, a+l-1+(l-1)*lda, 1 ); + + if ( nrmxl != 0.0 ) + { + if ( a[l-1+(l-1)*lda] != 0.0 ) + { + nrmxl = nrmxl * r8_sign ( a[l-1+(l-1)*lda] ); + } + + dscal ( n-l+1, 1.0 / nrmxl, a+l-1+(l-1)*lda, 1 ); + a[l-1+(l-1)*lda] = 1.0 + a[l-1+(l-1)*lda]; +/* + Apply the transformation to the remaining columns, updating the norms. +*/ + for ( j = l + 1; j <= p; j++ ) + { + t = -ddot ( n-l+1, a+l-1+(l-1)*lda, 1, a+l-1+(j-1)*lda, 1 ) + / a[l-1+(l-1)*lda]; + daxpy ( n-l+1, t, a+l-1+(l-1)*lda, 1, a+l-1+(j-1)*lda, 1 ); + + if ( pl <= j && j <= pu ) + { + if ( qraux[j-1] != 0.0 ) + { + tt = 1.0 - pow ( r8_abs ( a[l-1+(j-1)*lda] ) / qraux[j-1], 2 ); + tt = r8_max ( tt, 0.0 ); + t = tt; + tt = 1.0 + 0.05 * tt * pow ( qraux[j-1] / work[j-1], 2 ); + + if ( tt != 1.0 ) + { + qraux[j-1] = qraux[j-1] * sqrt ( t ); + } + else + { + qraux[j-1] = dnrm2 ( n-l, a+l+(j-1)*lda, 1 ); + work[j-1] = qraux[j-1]; + } + } + } + } +/* + Save the transformation. +*/ + qraux[l-1] = a[l-1+(l-1)*lda]; + a[l-1+(l-1)*lda] = -nrmxl; + } + } + } + return; +} +/******************************************************************************/ + +int dqrls ( double a[], int lda, int m, int n, double tol, int *kr, double b[], + double x[], double rsd[], int jpvt[], double qraux[], int itask ) + +/******************************************************************************/ +/* + Purpose: + + DQRLS factors and solves a linear system in the least squares sense. + + Discussion: + + The linear system may be overdetermined, underdetermined or singular. + The solution is obtained using a QR factorization of the + coefficient matrix. + + DQRLS can be efficiently used to solve several least squares + problems with the same matrix A. The first system is solved + with ITASK = 1. The subsequent systems are solved with + ITASK = 2, to avoid the recomputation of the matrix factors. + The parameters KR, JPVT, and QRAUX must not be modified + between calls to DQRLS. + + DQRLS is used to solve in a least squares sense + overdetermined, underdetermined and singular linear systems. + The system is A*X approximates B where A is M by N. + B is a given M-vector, and X is the N-vector to be computed. + A solution X is found which minimimzes the sum of squares (2-norm) + of the residual, A*X - B. + + The numerical rank of A is determined using the tolerance TOL. + + DQRLS uses the LINPACK subroutine DQRDC to compute the QR + factorization, with column pivoting, of an M by N matrix A. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 10 September 2012 + + Author: + + C version by John Burkardt. + + Reference: + + David Kahaner, Cleve Moler, Steven Nash, + Numerical Methods and Software, + Prentice Hall, 1989, + ISBN: 0-13-627258-4, + LC: TA345.K34. + + Parameters: + + Input/output, double A[LDA*N], an M by N matrix. + On input, the matrix whose decomposition is to be computed. + In a least squares data fitting problem, A(I,J) is the + value of the J-th basis (model) function at the I-th data point. + On output, A contains the output from DQRDC. The triangular matrix R + of the QR factorization is contained in the upper triangle and + information needed to recover the orthogonal matrix Q is stored + below the diagonal in A and in the vector QRAUX. + + Input, int LDA, the leading dimension of A. + + Input, int M, the number of rows of A. + + Input, int N, the number of columns of A. + + Input, double TOL, a relative tolerance used to determine the + numerical rank. The problem should be scaled so that all the elements + of A have roughly the same absolute accuracy EPS. Then a reasonable + value for TOL is roughly EPS divided by the magnitude of the largest + element. + + Output, int *KR, the numerical rank. + + Input, double B[M], the right hand side of the linear system. + + Output, double X[N], a least squares solution to the linear + system. + + Output, double RSD[M], the residual, B - A*X. RSD may + overwrite B. + + Workspace, int JPVT[N], required if ITASK = 1. + Columns JPVT(1), ..., JPVT(KR) of the original matrix are linearly + independent to within the tolerance TOL and the remaining columns + are linearly dependent. ABS ( A(1,1) ) / ABS ( A(KR,KR) ) is an estimate + of the condition number of the matrix of independent columns, + and of R. This estimate will be <= 1/TOL. + + Workspace, double QRAUX[N], required if ITASK = 1. + + Input, int ITASK. + 1, DQRLS factors the matrix A and solves the least squares problem. + 2, DQRLS assumes that the matrix A was factored with an earlier + call to DQRLS, and only solves the least squares problem. + + Output, int DQRLS, error code. + 0: no error + -1: LDA < M (fatal error) + -2: N < 1 (fatal error) + -3: ITASK < 1 (fatal error) +*/ +{ + int ind; + + if ( lda < m ) + { + /*fprintf ( stderr, "\n" ); + fprintf ( stderr, "DQRLS - Fatal error!\n" ); + fprintf ( stderr, " LDA < M.\n" );*/ + ind = -1; + return ind; + } + + if ( n <= 0 ) + { + /*fprintf ( stderr, "\n" ); + fprintf ( stderr, "DQRLS - Fatal error!\n" ); + fprintf ( stderr, " N <= 0.\n" );*/ + ind = -2; + return ind; + } + + if ( itask < 1 ) + { + /*fprintf ( stderr, "\n" ); + fprintf ( stderr, "DQRLS - Fatal error!\n" ); + fprintf ( stderr, " ITASK < 1.\n" );*/ + ind = -3; + return ind; + } + + ind = 0; +/* + Factor the matrix. +*/ + if ( itask == 1 ) + { + dqrank ( a, lda, m, n, tol, kr, jpvt, qraux ); + } +/* + Solve the least-squares problem. +*/ + dqrlss ( a, lda, m, n, *kr, b, x, rsd, jpvt, qraux ); + + return ind; +} +/******************************************************************************/ + +void dqrlss ( double a[], int lda, int m, int n, int kr, double b[], double x[], + double rsd[], int jpvt[], double qraux[] ) + +/******************************************************************************/ +/* + Purpose: + + DQRLSS solves a linear system in a least squares sense. + + Discussion: + + DQRLSS must be preceded by a call to DQRANK. + + The system is to be solved is + A * X = B + where + A is an M by N matrix with rank KR, as determined by DQRANK, + B is a given M-vector, + X is the N-vector to be computed. + + A solution X, with at most KR nonzero components, is found which + minimizes the 2-norm of the residual (A*X-B). + + Once the matrix A has been formed, DQRANK should be + called once to decompose it. Then, for each right hand + side B, DQRLSS should be called once to obtain the + solution and residual. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 10 September 2012 + + Author: + + C version by John Burkardt + + Parameters: + + Input, double A[LDA*N], the QR factorization information + from DQRANK. The triangular matrix R of the QR factorization is + contained in the upper triangle and information needed to recover + the orthogonal matrix Q is stored below the diagonal in A and in + the vector QRAUX. + + Input, int LDA, the leading dimension of A, which must + be at least M. + + Input, int M, the number of rows of A. + + Input, int N, the number of columns of A. + + Input, int KR, the rank of the matrix, as estimated by DQRANK. + + Input, double B[M], the right hand side of the linear system. + + Output, double X[N], a least squares solution to the + linear system. + + Output, double RSD[M], the residual, B - A*X. RSD may + overwrite B. + + Input, int JPVT[N], the pivot information from DQRANK. + Columns JPVT[0], ..., JPVT[KR-1] of the original matrix are linearly + independent to within the tolerance TOL and the remaining columns + are linearly dependent. + + Input, double QRAUX[N], auxiliary information from DQRANK + defining the QR factorization. +*/ +{ + int i; + int info; + int j; + int job; + int k; + double t; + + if ( kr != 0 ) + { + job = 110; + info = dqrsl ( a, lda, m, kr, qraux, b, rsd, rsd, x, rsd, rsd, job ); + } + + for ( i = 0; i < n; i++ ) + { + jpvt[i] = - jpvt[i]; + } + + for ( i = kr; i < n; i++ ) + { + x[i] = 0.0; + } + + for ( j = 1; j <= n; j++ ) + { + if ( jpvt[j-1] <= 0 ) + { + k = - jpvt[j-1]; + jpvt[j-1] = k; + + while ( k != j ) + { + t = x[j-1]; + x[j-1] = x[k-1]; + x[k-1] = t; + jpvt[k-1] = -jpvt[k-1]; + k = jpvt[k-1]; + } + } + } + return; +} +/******************************************************************************/ + +int dqrsl ( double a[], int lda, int n, int k, double qraux[], double y[], + double qy[], double qty[], double b[], double rsd[], double ab[], int job ) + +/******************************************************************************/ +/* + Purpose: + + DQRSL computes transformations, projections, and least squares solutions. + + Discussion: + + DQRSL requires the output of DQRDC. + + For K <= min(N,P), let AK be the matrix + + AK = ( A(JPVT[0]), A(JPVT(2)), ..., A(JPVT(K)) ) + + formed from columns JPVT[0], ..., JPVT(K) of the original + N by P matrix A that was input to DQRDC. If no pivoting was + done, AK consists of the first K columns of A in their + original order. DQRDC produces a factored orthogonal matrix Q + and an upper triangular matrix R such that + + AK = Q * (R) + (0) + + This information is contained in coded form in the arrays + A and QRAUX. + + The parameters QY, QTY, B, RSD, and AB are not referenced + if their computation is not requested and in this case + can be replaced by dummy variables in the calling program. + To save storage, the user may in some cases use the same + array for different parameters in the calling sequence. A + frequently occurring example is when one wishes to compute + any of B, RSD, or AB and does not need Y or QTY. In this + case one may identify Y, QTY, and one of B, RSD, or AB, while + providing separate arrays for anything else that is to be + computed. + + Thus the calling sequence + + dqrsl ( a, lda, n, k, qraux, y, dum, y, b, y, dum, 110, info ) + + will result in the computation of B and RSD, with RSD + overwriting Y. More generally, each item in the following + list contains groups of permissible identifications for + a single calling sequence. + + 1. (Y,QTY,B) (RSD) (AB) (QY) + + 2. (Y,QTY,RSD) (B) (AB) (QY) + + 3. (Y,QTY,AB) (B) (RSD) (QY) + + 4. (Y,QY) (QTY,B) (RSD) (AB) + + 5. (Y,QY) (QTY,RSD) (B) (AB) + + 6. (Y,QY) (QTY,AB) (B) (RSD) + + In any group the value returned in the array allocated to + the group corresponds to the last member of the group. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 07 June 2005 + + Author: + + C version by John Burkardt. + + Reference: + + Jack Dongarra, Cleve Moler, Jim Bunch and Pete Stewart, + LINPACK User's Guide, + SIAM, (Society for Industrial and Applied Mathematics), + 3600 University City Science Center, + Philadelphia, PA, 19104-2688. + ISBN 0-89871-172-X + + Parameters: + + Input, double A[LDA*P], contains the output of DQRDC. + + Input, int LDA, the leading dimension of the array A. + + Input, int N, the number of rows of the matrix AK. It must + have the same value as N in DQRDC. + + Input, int K, the number of columns of the matrix AK. K + must not be greater than min(N,P), where P is the same as in the + calling sequence to DQRDC. + + Input, double QRAUX[P], the auxiliary output from DQRDC. + + Input, double Y[N], a vector to be manipulated by DQRSL. + + Output, double QY[N], contains Q * Y, if requested. + + Output, double QTY[N], contains Q' * Y, if requested. + + Output, double B[K], the solution of the least squares problem + minimize norm2 ( Y - AK * B), + if its computation has been requested. Note that if pivoting was + requested in DQRDC, the J-th component of B will be associated with + column JPVT(J) of the original matrix A that was input into DQRDC. + + Output, double RSD[N], the least squares residual Y - AK * B, + if its computation has been requested. RSD is also the orthogonal + projection of Y onto the orthogonal complement of the column space + of AK. + + Output, double AB[N], the least squares approximation Ak * B, + if its computation has been requested. AB is also the orthogonal + projection of Y onto the column space of A. + + Input, integer JOB, specifies what is to be computed. JOB has + the decimal expansion ABCDE, with the following meaning: + + if A != 0, compute QY. + if B != 0, compute QTY. + if C != 0, compute QTY and B. + if D != 0, compute QTY and RSD. + if E != 0, compute QTY and AB. + + Note that a request to compute B, RSD, or AB automatically triggers + the computation of QTY, for which an array must be provided in the + calling sequence. + + Output, int DQRSL, is zero unless the computation of B has + been requested and R is exactly singular. In this case, INFO is the + index of the first zero diagonal element of R, and B is left unaltered. +*/ +{ + int cab; + int cb; + int cqty; + int cqy; + int cr; + int i; + int info; + int j; + int jj; + int ju; + double t; + double temp; +/* + Set INFO flag. +*/ + info = 0; +/* + Determine what is to be computed. +*/ + cqy = ( job / 10000 != 0 ); + cqty = ( ( job % 10000 ) != 0 ); + cb = ( ( job % 1000 ) / 100 != 0 ); + cr = ( ( job % 100 ) / 10 != 0 ); + cab = ( ( job % 10 ) != 0 ); + + ju = i4_min ( k, n-1 ); +/* + Special action when N = 1. +*/ + if ( ju == 0 ) + { + if ( cqy ) + { + qy[0] = y[0]; + } + + if ( cqty ) + { + qty[0] = y[0]; + } + + if ( cab ) + { + ab[0] = y[0]; + } + + if ( cb ) + { + if ( a[0+0*lda] == 0.0 ) + { + info = 1; + } + else + { + b[0] = y[0] / a[0+0*lda]; + } + } + + if ( cr ) + { + rsd[0] = 0.0; + } + return info; + } +/* + Set up to compute QY or QTY. +*/ + if ( cqy ) + { + for ( i = 1; i <= n; i++ ) + { + qy[i-1] = y[i-1]; + } + } + + if ( cqty ) + { + for ( i = 1; i <= n; i++ ) + { + qty[i-1] = y[i-1]; + } + } +/* + Compute QY. +*/ + if ( cqy ) + { + for ( jj = 1; jj <= ju; jj++ ) + { + j = ju - jj + 1; + + if ( qraux[j-1] != 0.0 ) + { + temp = a[j-1+(j-1)*lda]; + a[j-1+(j-1)*lda] = qraux[j-1]; + t = -ddot ( n-j+1, a+j-1+(j-1)*lda, 1, qy+j-1, 1 ) / a[j-1+(j-1)*lda]; + daxpy ( n-j+1, t, a+j-1+(j-1)*lda, 1, qy+j-1, 1 ); + a[j-1+(j-1)*lda] = temp; + } + } + } +/* + Compute Q'*Y. +*/ + if ( cqty ) + { + for ( j = 1; j <= ju; j++ ) + { + if ( qraux[j-1] != 0.0 ) + { + temp = a[j-1+(j-1)*lda]; + a[j-1+(j-1)*lda] = qraux[j-1]; + t = -ddot ( n-j+1, a+j-1+(j-1)*lda, 1, qty+j-1, 1 ) / a[j-1+(j-1)*lda]; + daxpy ( n-j+1, t, a+j-1+(j-1)*lda, 1, qty+j-1, 1 ); + a[j-1+(j-1)*lda] = temp; + } + } + } +/* + Set up to compute B, RSD, or AB. +*/ + if ( cb ) + { + for ( i = 1; i <= k; i++ ) + { + b[i-1] = qty[i-1]; + } + } + + if ( cab ) + { + for ( i = 1; i <= k; i++ ) + { + ab[i-1] = qty[i-1]; + } + } + + if ( cr && k < n ) + { + for ( i = k+1; i <= n; i++ ) + { + rsd[i-1] = qty[i-1]; + } + } + + if ( cab && k+1 <= n ) + { + for ( i = k+1; i <= n; i++ ) + { + ab[i-1] = 0.0; + } + } + + if ( cr ) + { + for ( i = 1; i <= k; i++ ) + { + rsd[i-1] = 0.0; + } + } +/* + Compute B. +*/ + if ( cb ) + { + for ( jj = 1; jj <= k; jj++ ) + { + j = k - jj + 1; + + if ( a[j-1+(j-1)*lda] == 0.0 ) + { + info = j; + break; + } + + b[j-1] = b[j-1] / a[j-1+(j-1)*lda]; + + if ( j != 1 ) + { + t = -b[j-1]; + daxpy ( j-1, t, a+0+(j-1)*lda, 1, b, 1 ); + } + } + } +/* + Compute RSD or AB as required. +*/ + if ( cr || cab ) + { + for ( jj = 1; jj <= ju; jj++ ) + { + j = ju - jj + 1; + + if ( qraux[j-1] != 0.0 ) + { + temp = a[j-1+(j-1)*lda]; + a[j-1+(j-1)*lda] = qraux[j-1]; + + if ( cr ) + { + t = -ddot ( n-j+1, a+j-1+(j-1)*lda, 1, rsd+j-1, 1 ) + / a[j-1+(j-1)*lda]; + daxpy ( n-j+1, t, a+j-1+(j-1)*lda, 1, rsd+j-1, 1 ); + } + + if ( cab ) + { + t = -ddot ( n-j+1, a+j-1+(j-1)*lda, 1, ab+j-1, 1 ) + / a[j-1+(j-1)*lda]; + daxpy ( n-j+1, t, a+j-1+(j-1)*lda, 1, ab+j-1, 1 ); + } + a[j-1+(j-1)*lda] = temp; + } + } + } + + return info; +} +/******************************************************************************/ + +/******************************************************************************/ + +void dscal ( int n, double sa, double x[], int incx ) + +/******************************************************************************/ +/* + Purpose: + + DSCAL scales a vector by a constant. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 30 March 2007 + + Author: + + C version by John Burkardt + + Reference: + + Jack Dongarra, Cleve Moler, Jim Bunch, Pete Stewart, + LINPACK User's Guide, + SIAM, 1979. + + Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh, + Basic Linear Algebra Subprograms for Fortran Usage, + Algorithm 539, + ACM Transactions on Mathematical Software, + Volume 5, Number 3, September 1979, pages 308-323. + + Parameters: + + Input, int N, the number of entries in the vector. + + Input, double SA, the multiplier. + + Input/output, double X[*], the vector to be scaled. + + Input, int INCX, the increment between successive entries of X. +*/ +{ + int i; + int ix; + int m; + + if ( n <= 0 ) + { + } + else if ( incx == 1 ) + { + m = n % 5; + + for ( i = 0; i < m; i++ ) + { + x[i] = sa * x[i]; + } + + for ( i = m; i < n; i = i + 5 ) + { + x[i] = sa * x[i]; + x[i+1] = sa * x[i+1]; + x[i+2] = sa * x[i+2]; + x[i+3] = sa * x[i+3]; + x[i+4] = sa * x[i+4]; + } + } + else + { + if ( 0 <= incx ) + { + ix = 0; + } + else + { + ix = ( - n + 1 ) * incx; + } + + for ( i = 0; i < n; i++ ) + { + x[ix] = sa * x[ix]; + ix = ix + incx; + } + } + return; +} +/******************************************************************************/ + + +void dswap ( int n, double x[], int incx, double y[], int incy ) + +/******************************************************************************/ +/* + Purpose: + + DSWAP interchanges two vectors. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 30 March 2007 + + Author: + + C version by John Burkardt + + Reference: + + Jack Dongarra, Cleve Moler, Jim Bunch, Pete Stewart, + LINPACK User's Guide, + SIAM, 1979. + + Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh, + Basic Linear Algebra Subprograms for Fortran Usage, + Algorithm 539, + ACM Transactions on Mathematical Software, + Volume 5, Number 3, September 1979, pages 308-323. + + Parameters: + + Input, int N, the number of entries in the vectors. + + Input/output, double X[*], one of the vectors to swap. + + Input, int INCX, the increment between successive entries of X. + + Input/output, double Y[*], one of the vectors to swap. + + Input, int INCY, the increment between successive elements of Y. +*/ +{ + int i; + int ix; + int iy; + int m; + double temp; + + if ( n <= 0 ) + { + } + else if ( incx == 1 && incy == 1 ) + { + m = n % 3; + + for ( i = 0; i < m; i++ ) + { + temp = x[i]; + x[i] = y[i]; + y[i] = temp; + } + + for ( i = m; i < n; i = i + 3 ) + { + temp = x[i]; + x[i] = y[i]; + y[i] = temp; + + temp = x[i+1]; + x[i+1] = y[i+1]; + y[i+1] = temp; + + temp = x[i+2]; + x[i+2] = y[i+2]; + y[i+2] = temp; + } + } + else + { + if ( 0 <= incx ) + { + ix = 0; + } + else + { + ix = ( - n + 1 ) * incx; + } + + if ( 0 <= incy ) + { + iy = 0; + } + else + { + iy = ( - n + 1 ) * incy; + } + + for ( i = 0; i < n; i++ ) + { + temp = x[ix]; + x[ix] = y[iy]; + y[iy] = temp; + ix = ix + incx; + iy = iy + incy; + } + + } + + return; +} +/******************************************************************************/ + +/******************************************************************************/ + +double *qr_solve ( int m, int n, double a[], double b[] ) + +/******************************************************************************/ +/* + Purpose: + + QR_SOLVE solves a linear system in the least squares sense. + + Discussion: + + If the matrix A has full column rank, then the solution X should be the + unique vector that minimizes the Euclidean norm of the residual. + + If the matrix A does not have full column rank, then the solution is + not unique; the vector X will minimize the residual norm, but so will + various other vectors. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 11 September 2012 + + Author: + + John Burkardt + + Reference: + + David Kahaner, Cleve Moler, Steven Nash, + Numerical Methods and Software, + Prentice Hall, 1989, + ISBN: 0-13-627258-4, + LC: TA345.K34. + + Parameters: + + Input, int M, the number of rows of A. + + Input, int N, the number of columns of A. + + Input, double A[M*N], the matrix. + + Input, double B[M], the right hand side. + + Output, double QR_SOLVE[N], the least squares solution. +*/ +{ + double *a_qr; + int ind; + int itask; + int *jpvt; + int kr; + int lda; + double *qraux; + double *r; + double tol; + double *x; + + a_qr = r8mat_copy_new ( m, n, a ); + lda = m; + tol = r8_epsilon ( ) / r8mat_amax ( m, n, a_qr ); + x = ( double * ) malloc ( n * sizeof ( double ) ); + jpvt = ( int * ) malloc ( n * sizeof ( int ) ); + qraux = ( double * ) malloc ( n * sizeof ( double ) ); + r = ( double * ) malloc ( m * sizeof ( double ) ); + itask = 1; + + ind = dqrls ( a_qr, lda, m, n, tol, &kr, b, x, r, jpvt, qraux, itask ); + + free ( a_qr ); + free ( jpvt ); + free ( qraux ); + free ( r ); + + return x; +} +/******************************************************************************/ + +#endif diff --git a/Marlin/qr_solve.h b/Marlin/qr_solve.h new file mode 100644 index 000000000..b38086aad --- /dev/null +++ b/Marlin/qr_solve.h @@ -0,0 +1,22 @@ +#include "Configuration.h" + +#ifdef AUTO_BED_LEVELING_GRID + +void daxpy ( int n, double da, double dx[], int incx, double dy[], int incy ); +double ddot ( int n, double dx[], int incx, double dy[], int incy ); +double dnrm2 ( int n, double x[], int incx ); +void dqrank ( double a[], int lda, int m, int n, double tol, int *kr, + int jpvt[], double qraux[] ); +void dqrdc ( double a[], int lda, int n, int p, double qraux[], int jpvt[], + double work[], int job ); +int dqrls ( double a[], int lda, int m, int n, double tol, int *kr, double b[], + double x[], double rsd[], int jpvt[], double qraux[], int itask ); +void dqrlss ( double a[], int lda, int m, int n, int kr, double b[], double x[], + double rsd[], int jpvt[], double qraux[] ); +int dqrsl ( double a[], int lda, int n, int k, double qraux[], double y[], + double qy[], double qty[], double b[], double rsd[], double ab[], int job ); +void dscal ( int n, double sa, double x[], int incx ); +void dswap ( int n, double x[], int incx, double y[], int incy ); +double *qr_solve ( int m, int n, double a[], double b[] ); + +#endif diff --git a/Marlin/stepper.cpp b/Marlin/stepper.cpp index 2f1d91260..9bc8eb839 100644 --- a/Marlin/stepper.cpp +++ b/Marlin/stepper.cpp @@ -48,8 +48,8 @@ block_t *current_block; // A pointer to the block currently being traced // Variables used by The Stepper Driver Interrupt static unsigned char out_bits; // The next stepping-bits to be output static long counter_x, // Counter variables for the bresenham line tracer - counter_y, - counter_z, + counter_y, + counter_z, counter_e; volatile static unsigned long step_events_completed; // The number of step events executed in the current block #ifdef ADVANCE @@ -72,6 +72,9 @@ static volatile bool endstop_z_hit=false; #ifdef ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED bool abort_on_endstop_hit = false; #endif +#ifdef MOTOR_CURRENT_PWM_XY_PIN + int motor_current_setting[3] = DEFAULT_PWM_MOTOR_CURRENT; +#endif static bool old_x_min_endstop=false; static bool old_x_max_endstop=false; @@ -188,7 +191,7 @@ void checkHitEndstops() endstop_x_hit=false; endstop_y_hit=false; endstop_z_hit=false; -#ifdef ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED +#if defined(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) && defined(SDSUPPORT) if (abort_on_endstop_hit) { card.sdprinting = false; @@ -224,27 +227,27 @@ void enable_endstops(bool check) // | BLOCK 1 | BLOCK 2 | d // // time -----> -// -// The trapezoid is the shape the speed curve over time. It starts at block->initial_rate, accelerates -// first block->accelerate_until step_events_completed, then keeps going at constant speed until +// +// The trapezoid is the shape the speed curve over time. It starts at block->initial_rate, accelerates +// first block->accelerate_until step_events_completed, then keeps going at constant speed until // step_events_completed reaches block->decelerate_after after which it decelerates until the trapezoid generator is reset. // The slope of acceleration is calculated with the leib ramp alghorithm. void st_wake_up() { // TCNT1 = 0; - ENABLE_STEPPER_DRIVER_INTERRUPT(); + ENABLE_STEPPER_DRIVER_INTERRUPT(); } void step_wait(){ for(int8_t i=0; i < 6; i++){ } } - + FORCE_INLINE unsigned short calc_timer(unsigned short step_rate) { unsigned short timer; if(step_rate > MAX_STEP_FREQUENCY) step_rate = MAX_STEP_FREQUENCY; - + if(step_rate > 20000) { // If steprate > 20kHz >> step 4 times step_rate = (step_rate >> 2)&0x3fff; step_loops = 4; @@ -255,11 +258,11 @@ FORCE_INLINE unsigned short calc_timer(unsigned short step_rate) { } else { step_loops = 1; - } - + } + if(step_rate < (F_CPU/500000)) step_rate = (F_CPU/500000); step_rate -= (F_CPU/500000); // Correct for minimal speed - if(step_rate >= (8*256)){ // higher step rate + if(step_rate >= (8*256)){ // higher step rate unsigned short table_address = (unsigned short)&speed_lookuptable_fast[(unsigned char)(step_rate>>8)][0]; unsigned char tmp_step_rate = (step_rate & 0x00ff); unsigned short gain = (unsigned short)pgm_read_word_near(table_address+2); @@ -276,7 +279,7 @@ FORCE_INLINE unsigned short calc_timer(unsigned short step_rate) { return timer; } -// Initializes the trapezoid generator from the current block. Called whenever a new +// Initializes the trapezoid generator from the current block. Called whenever a new // block begins. FORCE_INLINE void trapezoid_generator_reset() { #ifdef ADVANCE @@ -284,7 +287,7 @@ FORCE_INLINE void trapezoid_generator_reset() { final_advance = current_block->final_advance; // Do E steps + advance steps e_steps[current_block->active_extruder] += ((advance >>8) - old_advance); - old_advance = advance >>8; + old_advance = advance >>8; #endif deceleration_time = 0; // step_rate to timer interval @@ -294,7 +297,7 @@ FORCE_INLINE void trapezoid_generator_reset() { acc_step_rate = current_block->initial_rate; acceleration_time = calc_timer(acc_step_rate); OCR1A = acceleration_time; - + // SERIAL_ECHO_START; // SERIAL_ECHOPGM("advance :"); // SERIAL_ECHO(current_block->advance/256.0); @@ -304,13 +307,13 @@ FORCE_INLINE void trapezoid_generator_reset() { // SERIAL_ECHO(current_block->initial_advance/256.0); // SERIAL_ECHOPGM("final advance :"); // SERIAL_ECHOLN(current_block->final_advance/256.0); - + } -// "The Stepper Driver Interrupt" - This timer interrupt is the workhorse. -// It pops blocks from the block_buffer and executes them by pulsing the stepper pins appropriately. +// "The Stepper Driver Interrupt" - This timer interrupt is the workhorse. +// It pops blocks from the block_buffer and executes them by pulsing the stepper pins appropriately. ISR(TIMER1_COMPA_vect) -{ +{ // If there is no current block, attempt to pop one from the buffer if (current_block == NULL) { // Anything in the buffer? @@ -322,24 +325,24 @@ ISR(TIMER1_COMPA_vect) counter_y = counter_x; counter_z = counter_x; counter_e = counter_x; - step_events_completed = 0; - - #ifdef Z_LATE_ENABLE + step_events_completed = 0; + + #ifdef Z_LATE_ENABLE if(current_block->steps_z > 0) { enable_z(); OCR1A = 2000; //1ms wait return; } #endif - + // #ifdef ADVANCE // e_steps[current_block->active_extruder] = 0; // #endif - } + } else { OCR1A=2000; // 1kHz. - } - } + } + } if (current_block != NULL) { // Set directions TO DO This should be done once during init of trapezoid. Endstops -> interrupt @@ -349,31 +352,57 @@ ISR(TIMER1_COMPA_vect) // Set the direction bits (X_AXIS=A_AXIS and Y_AXIS=B_AXIS for COREXY) if((out_bits & (1<active_extruder != 0) + WRITE(X2_DIR_PIN, INVERT_X_DIR); + else + WRITE(X_DIR_PIN, INVERT_X_DIR); + } + #else WRITE(X_DIR_PIN, INVERT_X_DIR); + #endif count_direction[X_AXIS]=-1; } else{ #ifdef DUAL_X_CARRIAGE - if (active_extruder != 0) - WRITE(X2_DIR_PIN,!INVERT_X_DIR); - else - #endif + if (extruder_duplication_enabled){ + WRITE(X_DIR_PIN, !INVERT_X_DIR); + WRITE(X2_DIR_PIN, !INVERT_X_DIR); + } + else{ + if (current_block->active_extruder != 0) + WRITE(X2_DIR_PIN, !INVERT_X_DIR); + else + WRITE(X_DIR_PIN, !INVERT_X_DIR); + } + #else WRITE(X_DIR_PIN, !INVERT_X_DIR); + #endif count_direction[X_AXIS]=1; } if((out_bits & (1<active_extruder == 0 && X_HOME_DIR == -1) + || (current_block->active_extruder != 0 && X2_HOME_DIR == -1)) #endif { #if defined(X_MIN_PIN) && X_MIN_PIN > -1 - bool x_min_endstop=(READ(X_MIN_PIN) != X_ENDSTOPS_INVERTING); + bool x_min_endstop=(READ(X_MIN_PIN) != X_MIN_ENDSTOP_INVERTING); if(x_min_endstop && old_x_min_endstop && (current_block->steps_x > 0)) { endstops_trigsteps[X_AXIS] = count_position[X_AXIS]; endstop_x_hit=true; @@ -400,15 +430,16 @@ ISR(TIMER1_COMPA_vect) } } else { // +direction - CHECK_ENDSTOPS + CHECK_ENDSTOPS { #ifdef DUAL_X_CARRIAGE // with 2 x-carriages, endstops are only checked in the homing direction for the active extruder - if ((active_extruder == 0 && X_HOME_DIR == 1) || (active_extruder != 0 && X2_HOME_DIR == 1)) + if ((current_block->active_extruder == 0 && X_HOME_DIR == 1) + || (current_block->active_extruder != 0 && X2_HOME_DIR == 1)) #endif { #if defined(X_MAX_PIN) && X_MAX_PIN > -1 - bool x_max_endstop=(READ(X_MAX_PIN) != X_ENDSTOPS_INVERTING); + bool x_max_endstop=(READ(X_MAX_PIN) != X_MAX_ENDSTOP_INVERTING); if(x_max_endstop && old_x_max_endstop && (current_block->steps_x > 0)){ endstops_trigsteps[X_AXIS] = count_position[X_AXIS]; endstop_x_hit=true; @@ -416,7 +447,7 @@ ISR(TIMER1_COMPA_vect) } old_x_max_endstop = x_max_endstop; #endif - } + } } } @@ -428,7 +459,7 @@ ISR(TIMER1_COMPA_vect) CHECK_ENDSTOPS { #if defined(Y_MIN_PIN) && Y_MIN_PIN > -1 - bool y_min_endstop=(READ(Y_MIN_PIN) != Y_ENDSTOPS_INVERTING); + bool y_min_endstop=(READ(Y_MIN_PIN) != Y_MIN_ENDSTOP_INVERTING); if(y_min_endstop && old_y_min_endstop && (current_block->steps_y > 0)) { endstops_trigsteps[Y_AXIS] = count_position[Y_AXIS]; endstop_y_hit=true; @@ -442,7 +473,7 @@ ISR(TIMER1_COMPA_vect) CHECK_ENDSTOPS { #if defined(Y_MAX_PIN) && Y_MAX_PIN > -1 - bool y_max_endstop=(READ(Y_MAX_PIN) != Y_ENDSTOPS_INVERTING); + bool y_max_endstop=(READ(Y_MAX_PIN) != Y_MAX_ENDSTOP_INVERTING); if(y_max_endstop && old_y_max_endstop && (current_block->steps_y > 0)){ endstops_trigsteps[Y_AXIS] = count_position[Y_AXIS]; endstop_y_hit=true; @@ -456,15 +487,15 @@ ISR(TIMER1_COMPA_vect) if ((out_bits & (1< -1 - bool z_min_endstop=(READ(Z_MIN_PIN) != Z_ENDSTOPS_INVERTING); + bool z_min_endstop=(READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING); if(z_min_endstop && old_z_min_endstop && (current_block->steps_z > 0)) { endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS]; endstop_z_hit=true; @@ -477,7 +508,7 @@ ISR(TIMER1_COMPA_vect) else { // +direction WRITE(Z_DIR_PIN,!INVERT_Z_DIR); - #ifdef Z_DUAL_STEPPER_DRIVERS + #ifdef Z_DUAL_STEPPER_DRIVERS WRITE(Z2_DIR_PIN,!INVERT_Z_DIR); #endif @@ -485,7 +516,7 @@ ISR(TIMER1_COMPA_vect) CHECK_ENDSTOPS { #if defined(Z_MAX_PIN) && Z_MAX_PIN > -1 - bool z_max_endstop=(READ(Z_MAX_PIN) != Z_ENDSTOPS_INVERTING); + bool z_max_endstop=(READ(Z_MAX_PIN) != Z_MAX_ENDSTOP_INVERTING); if(z_max_endstop && old_z_max_endstop && (current_block->steps_z > 0)) { endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS]; endstop_z_hit=true; @@ -506,10 +537,10 @@ ISR(TIMER1_COMPA_vect) count_direction[E_AXIS]=1; } #endif //!ADVANCE - - - for(int8_t i=0; i < step_loops; i++) { // Take multiple steps per interrupt (For high speed moves) + + + for(int8_t i=0; i < step_loops; i++) { // Take multiple steps per interrupt (For high speed moves) #ifndef AT90USB MSerial.checkRx(); // Check for serial chars. #endif @@ -524,48 +555,73 @@ ISR(TIMER1_COMPA_vect) else { e_steps[current_block->active_extruder]++; } - } + } #endif //ADVANCE counter_x += current_block->steps_x; if (counter_x > 0) { - #ifdef DUAL_X_CARRIAGE - if (active_extruder != 0) - WRITE(X2_STEP_PIN,!INVERT_X_STEP_PIN); - else - #endif + #ifdef DUAL_X_CARRIAGE + if (extruder_duplication_enabled){ WRITE(X_STEP_PIN, !INVERT_X_STEP_PIN); + WRITE(X2_STEP_PIN, !INVERT_X_STEP_PIN); + } + else { + if (current_block->active_extruder != 0) + WRITE(X2_STEP_PIN, !INVERT_X_STEP_PIN); + else + WRITE(X_STEP_PIN, !INVERT_X_STEP_PIN); + } + #else + WRITE(X_STEP_PIN, !INVERT_X_STEP_PIN); + #endif counter_x -= current_block->step_event_count; count_position[X_AXIS]+=count_direction[X_AXIS]; - #ifdef DUAL_X_CARRIAGE - if (active_extruder != 0) - WRITE(X2_STEP_PIN,INVERT_X_STEP_PIN); - else - #endif + #ifdef DUAL_X_CARRIAGE + if (extruder_duplication_enabled){ WRITE(X_STEP_PIN, INVERT_X_STEP_PIN); + WRITE(X2_STEP_PIN, INVERT_X_STEP_PIN); + } + else { + if (current_block->active_extruder != 0) + WRITE(X2_STEP_PIN, INVERT_X_STEP_PIN); + else + WRITE(X_STEP_PIN, INVERT_X_STEP_PIN); + } + #else + WRITE(X_STEP_PIN, INVERT_X_STEP_PIN); + #endif } - + counter_y += current_block->steps_y; if (counter_y > 0) { WRITE(Y_STEP_PIN, !INVERT_Y_STEP_PIN); - counter_y -= current_block->step_event_count; - count_position[Y_AXIS]+=count_direction[Y_AXIS]; + + #ifdef Y_DUAL_STEPPER_DRIVERS + WRITE(Y2_STEP_PIN, !INVERT_Y_STEP_PIN); + #endif + + counter_y -= current_block->step_event_count; + count_position[Y_AXIS]+=count_direction[Y_AXIS]; WRITE(Y_STEP_PIN, INVERT_Y_STEP_PIN); + + #ifdef Y_DUAL_STEPPER_DRIVERS + WRITE(Y2_STEP_PIN, INVERT_Y_STEP_PIN); + #endif } - + counter_z += current_block->steps_z; if (counter_z > 0) { WRITE(Z_STEP_PIN, !INVERT_Z_STEP_PIN); - #ifdef Z_DUAL_STEPPER_DRIVERS + #ifdef Z_DUAL_STEPPER_DRIVERS WRITE(Z2_STEP_PIN, !INVERT_Z_STEP_PIN); #endif - + counter_z -= current_block->step_event_count; count_position[Z_AXIS]+=count_direction[Z_AXIS]; WRITE(Z_STEP_PIN, INVERT_Z_STEP_PIN); - #ifdef Z_DUAL_STEPPER_DRIVERS + #ifdef Z_DUAL_STEPPER_DRIVERS WRITE(Z2_STEP_PIN, INVERT_Z_STEP_PIN); #endif } @@ -579,17 +635,17 @@ ISR(TIMER1_COMPA_vect) WRITE_E_STEP(INVERT_E_STEP_PIN); } #endif //!ADVANCE - step_events_completed += 1; + step_events_completed += 1; if(step_events_completed >= current_block->step_event_count) break; } // Calculare new timer value unsigned short timer; unsigned short step_rate; if (step_events_completed <= (unsigned long int)current_block->accelerate_until) { - + MultiU24X24toH16(acc_step_rate, acceleration_time, current_block->acceleration_rate); acc_step_rate += current_block->initial_rate; - + // upper limit if(acc_step_rate > current_block->nominal_rate) acc_step_rate = current_block->nominal_rate; @@ -605,13 +661,13 @@ ISR(TIMER1_COMPA_vect) //if(advance > current_block->advance) advance = current_block->advance; // Do E steps + advance steps e_steps[current_block->active_extruder] += ((advance >>8) - old_advance); - old_advance = advance >>8; - + old_advance = advance >>8; + #endif - } - else if (step_events_completed > (unsigned long int)current_block->decelerate_after) { + } + else if (step_events_completed > (unsigned long int)current_block->decelerate_after) { MultiU24X24toH16(step_rate, deceleration_time, current_block->acceleration_rate); - + if(step_rate > acc_step_rate) { // Check step_rate stays positive step_rate = current_block->final_rate; } @@ -634,7 +690,7 @@ ISR(TIMER1_COMPA_vect) if(advance < final_advance) advance = final_advance; // Do E steps + advance steps e_steps[current_block->active_extruder] += ((advance >>8) - old_advance); - old_advance = advance >>8; + old_advance = advance >>8; #endif //ADVANCE } else { @@ -643,12 +699,12 @@ ISR(TIMER1_COMPA_vect) step_loops = step_loops_nominal; } - // If current block is finished, reset pointer + // If current block is finished, reset pointer if (step_events_completed >= current_block->step_event_count) { current_block = NULL; plan_discard_current_block(); - } - } + } + } } #ifdef ADVANCE @@ -667,7 +723,7 @@ ISR(TIMER1_COMPA_vect) WRITE(E0_DIR_PIN, INVERT_E0_DIR); e_steps[0]++; WRITE(E0_STEP_PIN, !INVERT_E_STEP_PIN); - } + } else if (e_steps[0] > 0) { WRITE(E0_DIR_PIN, !INVERT_E0_DIR); e_steps[0]--; @@ -681,7 +737,7 @@ ISR(TIMER1_COMPA_vect) WRITE(E1_DIR_PIN, INVERT_E1_DIR); e_steps[1]++; WRITE(E1_STEP_PIN, !INVERT_E_STEP_PIN); - } + } else if (e_steps[1] > 0) { WRITE(E1_DIR_PIN, !INVERT_E1_DIR); e_steps[1]--; @@ -696,7 +752,7 @@ ISR(TIMER1_COMPA_vect) WRITE(E2_DIR_PIN, INVERT_E2_DIR); e_steps[2]++; WRITE(E2_STEP_PIN, !INVERT_E_STEP_PIN); - } + } else if (e_steps[2] > 0) { WRITE(E2_DIR_PIN, !INVERT_E2_DIR); e_steps[2]--; @@ -712,7 +768,7 @@ void st_init() { digipot_init(); //Initialize Digipot Motor Current microstep_init(); //Initialize Microstepping Pins - + //Initialize Dir Pins #if defined(X_DIR_PIN) && X_DIR_PIN > -1 SET_OUTPUT(X_DIR_PIN); @@ -720,17 +776,21 @@ void st_init() #if defined(X2_DIR_PIN) && X2_DIR_PIN > -1 SET_OUTPUT(X2_DIR_PIN); #endif - #if defined(Y_DIR_PIN) && Y_DIR_PIN > -1 + #if defined(Y_DIR_PIN) && Y_DIR_PIN > -1 SET_OUTPUT(Y_DIR_PIN); + + #if defined(Y_DUAL_STEPPER_DRIVERS) && defined(Y2_DIR_PIN) && (Y2_DIR_PIN > -1) + SET_OUTPUT(Y2_DIR_PIN); + #endif #endif - #if defined(Z_DIR_PIN) && Z_DIR_PIN > -1 + #if defined(Z_DIR_PIN) && Z_DIR_PIN > -1 SET_OUTPUT(Z_DIR_PIN); #if defined(Z_DUAL_STEPPER_DRIVERS) && defined(Z2_DIR_PIN) && (Z2_DIR_PIN > -1) SET_OUTPUT(Z2_DIR_PIN); #endif #endif - #if defined(E0_DIR_PIN) && E0_DIR_PIN > -1 + #if defined(E0_DIR_PIN) && E0_DIR_PIN > -1 SET_OUTPUT(E0_DIR_PIN); #endif #if defined(E1_DIR_PIN) && (E1_DIR_PIN > -1) @@ -753,11 +813,16 @@ void st_init() #if defined(Y_ENABLE_PIN) && Y_ENABLE_PIN > -1 SET_OUTPUT(Y_ENABLE_PIN); if(!Y_ENABLE_ON) WRITE(Y_ENABLE_PIN,HIGH); + + #if defined(Y_DUAL_STEPPER_DRIVERS) && defined(Y2_ENABLE_PIN) && (Y2_ENABLE_PIN > -1) + SET_OUTPUT(Y2_ENABLE_PIN); + if(!Y_ENABLE_ON) WRITE(Y2_ENABLE_PIN,HIGH); + #endif #endif #if defined(Z_ENABLE_PIN) && Z_ENABLE_PIN > -1 SET_OUTPUT(Z_ENABLE_PIN); if(!Z_ENABLE_ON) WRITE(Z_ENABLE_PIN,HIGH); - + #if defined(Z_DUAL_STEPPER_DRIVERS) && defined(Z2_ENABLE_PIN) && (Z2_ENABLE_PIN > -1) SET_OUTPUT(Z2_ENABLE_PIN); if(!Z_ENABLE_ON) WRITE(Z2_ENABLE_PIN,HIGH); @@ -777,67 +842,71 @@ void st_init() #endif //endstops and pullups - + #if defined(X_MIN_PIN) && X_MIN_PIN > -1 - SET_INPUT(X_MIN_PIN); + SET_INPUT(X_MIN_PIN); #ifdef ENDSTOPPULLUP_XMIN WRITE(X_MIN_PIN,HIGH); #endif #endif - + #if defined(Y_MIN_PIN) && Y_MIN_PIN > -1 - SET_INPUT(Y_MIN_PIN); + SET_INPUT(Y_MIN_PIN); #ifdef ENDSTOPPULLUP_YMIN WRITE(Y_MIN_PIN,HIGH); #endif #endif - + #if defined(Z_MIN_PIN) && Z_MIN_PIN > -1 - SET_INPUT(Z_MIN_PIN); + SET_INPUT(Z_MIN_PIN); #ifdef ENDSTOPPULLUP_ZMIN WRITE(Z_MIN_PIN,HIGH); #endif #endif - + #if defined(X_MAX_PIN) && X_MAX_PIN > -1 - SET_INPUT(X_MAX_PIN); + SET_INPUT(X_MAX_PIN); #ifdef ENDSTOPPULLUP_XMAX WRITE(X_MAX_PIN,HIGH); #endif #endif - + #if defined(Y_MAX_PIN) && Y_MAX_PIN > -1 - SET_INPUT(Y_MAX_PIN); + SET_INPUT(Y_MAX_PIN); #ifdef ENDSTOPPULLUP_YMAX WRITE(Y_MAX_PIN,HIGH); #endif #endif - + #if defined(Z_MAX_PIN) && Z_MAX_PIN > -1 - SET_INPUT(Z_MAX_PIN); + SET_INPUT(Z_MAX_PIN); #ifdef ENDSTOPPULLUP_ZMAX WRITE(Z_MAX_PIN,HIGH); #endif #endif - + //Initialize Step Pins - #if defined(X_STEP_PIN) && (X_STEP_PIN > -1) + #if defined(X_STEP_PIN) && (X_STEP_PIN > -1) SET_OUTPUT(X_STEP_PIN); WRITE(X_STEP_PIN,INVERT_X_STEP_PIN); disable_x(); - #endif - #if defined(X2_STEP_PIN) && (X2_STEP_PIN > -1) + #endif + #if defined(X2_STEP_PIN) && (X2_STEP_PIN > -1) SET_OUTPUT(X2_STEP_PIN); WRITE(X2_STEP_PIN,INVERT_X_STEP_PIN); disable_x(); - #endif - #if defined(Y_STEP_PIN) && (Y_STEP_PIN > -1) + #endif + #if defined(Y_STEP_PIN) && (Y_STEP_PIN > -1) SET_OUTPUT(Y_STEP_PIN); WRITE(Y_STEP_PIN,INVERT_Y_STEP_PIN); + #if defined(Y_DUAL_STEPPER_DRIVERS) && defined(Y2_STEP_PIN) && (Y2_STEP_PIN > -1) + SET_OUTPUT(Y2_STEP_PIN); + WRITE(Y2_STEP_PIN,INVERT_Y_STEP_PIN); + #endif disable_y(); - #endif - #if defined(Z_STEP_PIN) && (Z_STEP_PIN > -1) + #endif + #if defined(Z_STEP_PIN) && (Z_STEP_PIN > -1) SET_OUTPUT(Z_STEP_PIN); WRITE(Z_STEP_PIN,INVERT_Z_STEP_PIN); #if defined(Z_DUAL_STEPPER_DRIVERS) && defined(Z2_STEP_PIN) && (Z2_STEP_PIN > -1) @@ -845,33 +914,33 @@ void st_init() WRITE(Z2_STEP_PIN,INVERT_Z_STEP_PIN); #endif disable_z(); - #endif - #if defined(E0_STEP_PIN) && (E0_STEP_PIN > -1) + #endif + #if defined(E0_STEP_PIN) && (E0_STEP_PIN > -1) SET_OUTPUT(E0_STEP_PIN); WRITE(E0_STEP_PIN,INVERT_E_STEP_PIN); disable_e0(); - #endif - #if defined(E1_STEP_PIN) && (E1_STEP_PIN > -1) + #endif + #if defined(E1_STEP_PIN) && (E1_STEP_PIN > -1) SET_OUTPUT(E1_STEP_PIN); WRITE(E1_STEP_PIN,INVERT_E_STEP_PIN); disable_e1(); - #endif - #if defined(E2_STEP_PIN) && (E2_STEP_PIN > -1) + #endif + #if defined(E2_STEP_PIN) && (E2_STEP_PIN > -1) SET_OUTPUT(E2_STEP_PIN); WRITE(E2_STEP_PIN,INVERT_E_STEP_PIN); disable_e2(); - #endif + #endif // waveform generation = 0100 = CTC TCCR1B &= ~(1< -1 @@ -970,13 +1194,23 @@ void digipot_init() //Initialize Digipot Motor Current { #if defined(DIGIPOTSS_PIN) && DIGIPOTSS_PIN > -1 const uint8_t digipot_motor_current[] = DIGIPOT_MOTOR_CURRENT; - - SPI.begin(); - pinMode(DIGIPOTSS_PIN, OUTPUT); - for(int i=0;i<=4;i++) + + SPI.begin(); + pinMode(DIGIPOTSS_PIN, OUTPUT); + for(int i=0;i<=4;i++) //digitalPotWrite(digipot_ch[i], digipot_motor_current[i]); digipot_current(i,digipot_motor_current[i]); #endif + #ifdef MOTOR_CURRENT_PWM_XY_PIN + pinMode(MOTOR_CURRENT_PWM_XY_PIN, OUTPUT); + pinMode(MOTOR_CURRENT_PWM_Z_PIN, OUTPUT); + pinMode(MOTOR_CURRENT_PWM_E_PIN, OUTPUT); + digipot_current(0, motor_current_setting[0]); + digipot_current(1, motor_current_setting[1]); + digipot_current(2, motor_current_setting[2]); + //Set timer5 to 31khz so the PWM of the motor power is as constant as possible. (removes a buzzing noise) + TCCR5B = (TCCR5B & ~(_BV(CS50) | _BV(CS51) | _BV(CS52))) | _BV(CS50); + #endif } void digipot_current(uint8_t driver, int current) @@ -985,17 +1219,31 @@ void digipot_current(uint8_t driver, int current) const uint8_t digipot_ch[] = DIGIPOT_CHANNELS; digitalPotWrite(digipot_ch[driver], current); #endif + #ifdef MOTOR_CURRENT_PWM_XY_PIN + if (driver == 0) analogWrite(MOTOR_CURRENT_PWM_XY_PIN, (long)current * 255L / (long)MOTOR_CURRENT_PWM_RANGE); + if (driver == 1) analogWrite(MOTOR_CURRENT_PWM_Z_PIN, (long)current * 255L / (long)MOTOR_CURRENT_PWM_RANGE); + if (driver == 2) analogWrite(MOTOR_CURRENT_PWM_E_PIN, (long)current * 255L / (long)MOTOR_CURRENT_PWM_RANGE); + #endif } void microstep_init() { - #if defined(X_MS1_PIN) && X_MS1_PIN > -1 const uint8_t microstep_modes[] = MICROSTEP_MODES; - pinMode(X_MS2_PIN,OUTPUT); + + #if defined(E1_MS1_PIN) && E1_MS1_PIN > -1 + pinMode(E1_MS1_PIN,OUTPUT); + pinMode(E1_MS2_PIN,OUTPUT); + #endif + + #if defined(X_MS1_PIN) && X_MS1_PIN > -1 + pinMode(X_MS1_PIN,OUTPUT); + pinMode(X_MS2_PIN,OUTPUT); + pinMode(Y_MS1_PIN,OUTPUT); pinMode(Y_MS2_PIN,OUTPUT); - pinMode(Z_MS2_PIN,OUTPUT); + pinMode(Z_MS1_PIN,OUTPUT); + pinMode(Z_MS2_PIN,OUTPUT); + pinMode(E0_MS1_PIN,OUTPUT); pinMode(E0_MS2_PIN,OUTPUT); - pinMode(E1_MS2_PIN,OUTPUT); for(int i=0;i<=4;i++) microstep_mode(i,microstep_modes[i]); #endif } @@ -1008,7 +1256,9 @@ void microstep_ms(uint8_t driver, int8_t ms1, int8_t ms2) case 1: digitalWrite( Y_MS1_PIN,ms1); break; case 2: digitalWrite( Z_MS1_PIN,ms1); break; case 3: digitalWrite(E0_MS1_PIN,ms1); break; + #if defined(E1_MS1_PIN) && E1_MS1_PIN > -1 case 4: digitalWrite(E1_MS1_PIN,ms1); break; + #endif } if(ms2 > -1) switch(driver) { @@ -1016,7 +1266,9 @@ void microstep_ms(uint8_t driver, int8_t ms1, int8_t ms2) case 1: digitalWrite( Y_MS2_PIN,ms2); break; case 2: digitalWrite( Z_MS2_PIN,ms2); break; case 3: digitalWrite(E0_MS2_PIN,ms2); break; + #if defined(E1_MS2_PIN) && E1_MS2_PIN > -1 case 4: digitalWrite(E1_MS2_PIN,ms2); break; + #endif } } @@ -1047,8 +1299,10 @@ void microstep_readings() SERIAL_PROTOCOLPGM("E0: "); SERIAL_PROTOCOL( digitalRead(E0_MS1_PIN)); SERIAL_PROTOCOLLN( digitalRead(E0_MS2_PIN)); + #if defined(E1_MS1_PIN) && E1_MS1_PIN > -1 SERIAL_PROTOCOLPGM("E1: "); SERIAL_PROTOCOL( digitalRead(E1_MS1_PIN)); SERIAL_PROTOCOLLN( digitalRead(E1_MS2_PIN)); + #endif } diff --git a/Marlin/stepper.h b/Marlin/stepper.h index 6e60a332e..1477a6e03 100644 --- a/Marlin/stepper.h +++ b/Marlin/stepper.h @@ -28,18 +28,25 @@ #define NORM_E_DIR() { if(current_block->active_extruder == 2) { WRITE(E2_DIR_PIN, !INVERT_E2_DIR); } else { if(current_block->active_extruder == 1) { WRITE(E1_DIR_PIN, !INVERT_E1_DIR); } else { WRITE(E0_DIR_PIN, !INVERT_E0_DIR); }}} #define REV_E_DIR() { if(current_block->active_extruder == 2) { WRITE(E2_DIR_PIN, INVERT_E2_DIR); } else { if(current_block->active_extruder == 1) { WRITE(E1_DIR_PIN, INVERT_E1_DIR); } else { WRITE(E0_DIR_PIN, INVERT_E0_DIR); }}} #elif EXTRUDERS > 1 - #define WRITE_E_STEP(v) { if(current_block->active_extruder == 1) { WRITE(E1_STEP_PIN, v); } else { WRITE(E0_STEP_PIN, v); }} - #define NORM_E_DIR() { if(current_block->active_extruder == 1) { WRITE(E1_DIR_PIN, !INVERT_E1_DIR); } else { WRITE(E0_DIR_PIN, !INVERT_E0_DIR); }} - #define REV_E_DIR() { if(current_block->active_extruder == 1) { WRITE(E1_DIR_PIN, INVERT_E1_DIR); } else { WRITE(E0_DIR_PIN, INVERT_E0_DIR); }} + #ifndef DUAL_X_CARRIAGE + #define WRITE_E_STEP(v) { if(current_block->active_extruder == 1) { WRITE(E1_STEP_PIN, v); } else { WRITE(E0_STEP_PIN, v); }} + #define NORM_E_DIR() { if(current_block->active_extruder == 1) { WRITE(E1_DIR_PIN, !INVERT_E1_DIR); } else { WRITE(E0_DIR_PIN, !INVERT_E0_DIR); }} + #define REV_E_DIR() { if(current_block->active_extruder == 1) { WRITE(E1_DIR_PIN, INVERT_E1_DIR); } else { WRITE(E0_DIR_PIN, INVERT_E0_DIR); }} + #else + extern bool extruder_duplication_enabled; + #define WRITE_E_STEP(v) { if(extruder_duplication_enabled) { WRITE(E0_STEP_PIN, v); WRITE(E1_STEP_PIN, v); } else if(current_block->active_extruder == 1) { WRITE(E1_STEP_PIN, v); } else { WRITE(E0_STEP_PIN, v); }} + #define NORM_E_DIR() { if(extruder_duplication_enabled) { WRITE(E0_DIR_PIN, !INVERT_E0_DIR); WRITE(E1_DIR_PIN, !INVERT_E1_DIR); } else if(current_block->active_extruder == 1) { WRITE(E1_DIR_PIN, !INVERT_E1_DIR); } else { WRITE(E0_DIR_PIN, !INVERT_E0_DIR); }} + #define REV_E_DIR() { if(extruder_duplication_enabled) { WRITE(E0_DIR_PIN, INVERT_E0_DIR); WRITE(E1_DIR_PIN, INVERT_E1_DIR); } else if(current_block->active_extruder == 1) { WRITE(E1_DIR_PIN, INVERT_E1_DIR); } else { WRITE(E0_DIR_PIN, INVERT_E0_DIR); }} + #endif #else #define WRITE_E_STEP(v) WRITE(E0_STEP_PIN, v) #define NORM_E_DIR() WRITE(E0_DIR_PIN, !INVERT_E0_DIR) #define REV_E_DIR() WRITE(E0_DIR_PIN, INVERT_E0_DIR) #endif -#ifdef ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED -extern bool abort_on_endstop_hit; -#endif +#ifdef ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED +extern bool abort_on_endstop_hit; +#endif // Initialize and start the stepper motor subsystem void st_init(); @@ -54,13 +61,18 @@ void st_set_e_position(const long &e); // Get current position in steps long st_get_position(uint8_t axis); +#ifdef ENABLE_AUTO_BED_LEVELING +// Get current position in mm +float st_get_position_mm(uint8_t axis); +#endif //ENABLE_AUTO_BED_LEVELING + // The stepper subsystem goes to sleep when it runs out of things to execute. Call this // to notify the subsystem that it is time to go to work. void st_wake_up(); -void checkHitEndstops(); //call from somwhere to create an serial error message with the locations the endstops where hit, in case they were triggered -void endstops_hit_on_purpose(); //avoid creation of the message, i.e. after homeing and before a routine call of checkHitEndstops(); +void checkHitEndstops(); //call from somewhere to create an serial error message with the locations the endstops where hit, in case they were triggered +void endstops_hit_on_purpose(); //avoid creation of the message, i.e. after homing and before a routine call of checkHitEndstops(); void enable_endstops(bool check); // Enable/disable endstop checking @@ -80,4 +92,10 @@ void digipot_current(uint8_t driver, int current); void microstep_init(); void microstep_readings(); +#ifdef BABYSTEPPING + void babystep(const uint8_t axis,const bool direction); // perform a short step with a single stepper motor, outside of any convention +#endif + + + #endif diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp index f5df7a1e7..a10c255af 100644 --- a/Marlin/temperature.cpp +++ b/Marlin/temperature.cpp @@ -65,6 +65,12 @@ float current_temperature_bed = 0.0; #ifdef FAN_SOFT_PWM unsigned char fanSpeedSoftPwm; #endif + +unsigned char soft_pwm_bed; + +#ifdef BABYSTEPPING + volatile int babystepsTodo[3]={0,0,0}; +#endif //=========================================================================== //=============================private variables============================ @@ -101,7 +107,7 @@ static volatile bool temp_meas_ready = false; static unsigned long previous_millis_bed_heater; #endif //PIDTEMPBED static unsigned char soft_pwm[EXTRUDERS]; - static unsigned char soft_pwm_bed; + #ifdef FAN_SOFT_PWM static unsigned char soft_pwm_fan; #endif @@ -173,7 +179,7 @@ void PID_autotune(float temp, int extruder, int ncycles) float Kp, Ki, Kd; float max = 0, min = 10000; - if ((extruder > EXTRUDERS) + if ((extruder >= EXTRUDERS) #if (TEMP_BED_PIN <= -1) ||(extruder < 0) #endif @@ -244,7 +250,7 @@ void PID_autotune(float temp, int extruder, int ncycles) Kp = 0.6*Ku; Ki = 2*Kp/Tu; Kd = Kp*Tu/8; - SERIAL_PROTOCOLLNPGM(" Clasic PID ") + SERIAL_PROTOCOLLNPGM(" Classic PID "); SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(Kp); SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(Ki); SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(Kd); @@ -252,14 +258,14 @@ void PID_autotune(float temp, int extruder, int ncycles) Kp = 0.33*Ku; Ki = Kp/Tu; Kd = Kp*Tu/3; - SERIAL_PROTOCOLLNPGM(" Some overshoot ") + SERIAL_PROTOCOLLNPGM(" Some overshoot "); SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(Kp); SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(Ki); SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(Kd); Kp = 0.2*Ku; Ki = 2*Kp/Tu; Kd = Kp*Tu/3; - SERIAL_PROTOCOLLNPGM(" No overshoot ") + SERIAL_PROTOCOLLNPGM(" No overshoot "); SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(Kp); SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(Ki); SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(Kd); @@ -300,7 +306,7 @@ void PID_autotune(float temp, int extruder, int ncycles) return; } if(cycles > ncycles) { - SERIAL_PROTOCOLLNPGM("PID Autotune finished! Put the Kp, Ki and Kd constants into Configuration.h"); + SERIAL_PROTOCOLLNPGM("PID Autotune finished! Put the last Kp, Ki and Kd constants from above into Configuration.h"); return; } lcd_update(); @@ -410,6 +416,10 @@ void manage_heater() for(int e = 0; e < EXTRUDERS; e++) { + #ifdef THERMAL_RUNAWAY_PROTECTION_PERIOD && THERMAL_RUNAWAY_PROTECTION_PERIOD > 0 + thermal_runaway_protection(&thermal_runaway_state_machine[e], &thermal_runaway_timer[e], current_temperature[e], target_temperature[e], e, THERMAL_RUNAWAY_PROTECTION_PERIOD, THERMAL_RUNAWAY_PROTECTION_HYSTERESIS); + #endif + #ifdef PIDTEMP pid_input = current_temperature[e]; @@ -436,15 +446,15 @@ void manage_heater() //K1 defined in Configuration.h in the PID settings #define K2 (1.0-K1) dTerm[e] = (Kd * (pid_input - temp_dState[e]))*K2 + (K1 * dTerm[e]); - temp_dState[e] = pid_input; - pid_output = constrain(pTerm[e] + iTerm[e] - dTerm[e], 0, PID_MAX); } + temp_dState[e] = pid_input; #else pid_output = constrain(target_temperature[e], 0, PID_MAX); #endif //PID_OPENLOOP #ifdef PID_DEBUG - SERIAL_ECHO_START(" PIDDEBUG "); + SERIAL_ECHO_START; + SERIAL_ECHO(" PID_DEBUG "); SERIAL_ECHO(e); SERIAL_ECHO(": Input "); SERIAL_ECHO(pid_input); @@ -520,6 +530,10 @@ void manage_heater() #if TEMP_SENSOR_BED != 0 + #ifdef THERMAL_RUNAWAY_PROTECTION_PERIOD && THERMAL_RUNAWAY_PROTECTION_PERIOD > 0 + thermal_runaway_protection(&thermal_runaway_bed_state_machine, &thermal_runaway_bed_timer, current_temperature_bed, target_temperature_bed, 9, THERMAL_RUNAWAY_PROTECTION_BED_PERIOD, THERMAL_RUNAWAY_PROTECTION_BED_HYSTERESIS); + #endif + #ifdef PIDTEMPBED pid_input = current_temperature_bed; @@ -603,6 +617,7 @@ static float analog2temp(int raw, uint8_t e) { SERIAL_ERROR((int)e); SERIAL_ERRORLNPGM(" - Invalid extruder number !"); kill(); + return 0.0; } #ifdef HEATER_0_USES_MAX6675 if (e == 0) @@ -889,6 +904,66 @@ void setWatch() #endif } +#ifdef THERMAL_RUNAWAY_PROTECTION_PERIOD && THERMAL_RUNAWAY_PROTECTION_PERIOD > 0 +void thermal_runaway_protection(int *state, unsigned long *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc) +{ +/* + SERIAL_ECHO_START; + SERIAL_ECHO("Thermal Thermal Runaway Running. Heater ID:"); + SERIAL_ECHO(heater_id); + SERIAL_ECHO(" ; State:"); + SERIAL_ECHO(*state); + SERIAL_ECHO(" ; Timer:"); + SERIAL_ECHO(*timer); + SERIAL_ECHO(" ; Temperature:"); + SERIAL_ECHO(temperature); + SERIAL_ECHO(" ; Target Temp:"); + SERIAL_ECHO(target_temperature); + SERIAL_ECHOLN(""); +*/ + if ((target_temperature == 0) || thermal_runaway) + { + *state = 0; + *timer = 0; + return; + } + switch (*state) + { + case 0: // "Heater Inactive" state + if (target_temperature > 0) *state = 1; + break; + case 1: // "First Heating" state + if (temperature >= target_temperature) *state = 2; + break; + case 2: // "Temperature Stable" state + if (temperature >= (target_temperature - hysteresis_degc)) + { + *timer = millis(); + } + else if ( (millis() - *timer) > period_seconds*1000) + { + SERIAL_ERROR_START; + SERIAL_ERRORLNPGM("Thermal Runaway, system stopped! Heater_ID: "); + SERIAL_ERRORLN((int)heater_id); + LCD_ALERTMESSAGEPGM("THERMAL RUNAWAY"); + thermal_runaway = true; + while(1) + { + disable_heater(); + disable_x(); + disable_y(); + disable_z(); + disable_e0(); + disable_e1(); + disable_e2(); + manage_heater(); + lcd_update(); + } + } + break; + } +} +#endif void disable_heater() { @@ -903,7 +978,7 @@ void disable_heater() #endif #endif - #if defined(TEMP_1_PIN) && TEMP_1_PIN > -1 + #if defined(TEMP_1_PIN) && TEMP_1_PIN > -1 && EXTRUDERS > 1 target_temperature[1]=0; soft_pwm[1]=0; #if defined(HEATER_1_PIN) && HEATER_1_PIN > -1 @@ -911,7 +986,7 @@ void disable_heater() #endif #endif - #if defined(TEMP_2_PIN) && TEMP_2_PIN > -1 + #if defined(TEMP_2_PIN) && TEMP_2_PIN > -1 && EXTRUDERS > 2 target_temperature[2]=0; soft_pwm[2]=0; #if defined(HEATER_2_PIN) && HEATER_2_PIN > -1 @@ -1034,10 +1109,10 @@ ISR(TIMER0_COMPB_vect) static unsigned long raw_temp_1_value = 0; static unsigned long raw_temp_2_value = 0; static unsigned long raw_temp_bed_value = 0; - static unsigned char temp_state = 0; + static unsigned char temp_state = 8; static unsigned char pwm_count = (1 << SOFT_PWM_SCALE); static unsigned char soft_pwm_0; - #if EXTRUDERS > 1 + #if (EXTRUDERS > 1) || defined(HEATERS_PARALLEL) static unsigned char soft_pwm_1; #endif #if EXTRUDERS > 2 @@ -1049,36 +1124,47 @@ ISR(TIMER0_COMPB_vect) if(pwm_count == 0){ soft_pwm_0 = soft_pwm[0]; - if(soft_pwm_0 > 0) WRITE(HEATER_0_PIN,1); + if(soft_pwm_0 > 0) { + WRITE(HEATER_0_PIN,1); + #ifdef HEATERS_PARALLEL + WRITE(HEATER_1_PIN,1); + #endif + } else WRITE(HEATER_0_PIN,0); + #if EXTRUDERS > 1 soft_pwm_1 = soft_pwm[1]; - if(soft_pwm_1 > 0) WRITE(HEATER_1_PIN,1); + if(soft_pwm_1 > 0) WRITE(HEATER_1_PIN,1); else WRITE(HEATER_1_PIN,0); #endif #if EXTRUDERS > 2 soft_pwm_2 = soft_pwm[2]; - if(soft_pwm_2 > 0) WRITE(HEATER_2_PIN,1); + if(soft_pwm_2 > 0) WRITE(HEATER_2_PIN,1); else WRITE(HEATER_2_PIN,0); #endif #if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1 soft_pwm_b = soft_pwm_bed; - if(soft_pwm_b > 0) WRITE(HEATER_BED_PIN,1); + if(soft_pwm_b > 0) WRITE(HEATER_BED_PIN,1); else WRITE(HEATER_BED_PIN,0); #endif #ifdef FAN_SOFT_PWM soft_pwm_fan = fanSpeedSoftPwm / 2; - if(soft_pwm_fan > 0) WRITE(FAN_PIN,1); + if(soft_pwm_fan > 0) WRITE(FAN_PIN,1); else WRITE(FAN_PIN,0); #endif } - if(soft_pwm_0 <= pwm_count) WRITE(HEATER_0_PIN,0); + if(soft_pwm_0 < pwm_count) { + WRITE(HEATER_0_PIN,0); + #ifdef HEATERS_PARALLEL + WRITE(HEATER_1_PIN,0); + #endif + } #if EXTRUDERS > 1 - if(soft_pwm_1 <= pwm_count) WRITE(HEATER_1_PIN,0); + if(soft_pwm_1 < pwm_count) WRITE(HEATER_1_PIN,0); #endif #if EXTRUDERS > 2 - if(soft_pwm_2 <= pwm_count) WRITE(HEATER_2_PIN,0); + if(soft_pwm_2 < pwm_count) WRITE(HEATER_2_PIN,0); #endif #if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1 - if(soft_pwm_b <= pwm_count) WRITE(HEATER_BED_PIN,0); + if(soft_pwm_b < pwm_count) WRITE(HEATER_BED_PIN,0); #endif #ifdef FAN_SOFT_PWM - if(soft_pwm_fan <= pwm_count) WRITE(FAN_PIN,0); + if(soft_pwm_fan < pwm_count) WRITE(FAN_PIN,0); #endif pwm_count += (1 << SOFT_PWM_SCALE); @@ -1165,13 +1251,16 @@ ISR(TIMER0_COMPB_vect) temp_state = 0; temp_count++; break; + case 8: //Startup, delay initial temp reading a tiny bit so the hardware can settle. + temp_state = 0; + break; // default: // SERIAL_ERROR_START; // SERIAL_ERRORLNPGM("Temp measurement error!"); // break; } - if(temp_count >= 16) // 8 ms * 16 = 128ms. + if(temp_count >= OVERSAMPLENR) // 8 * 16 * 1/(16000000/64/256) = 131ms. { if (!temp_meas_ready) //Only update the raw values if they have been read. Else we could be updating them during reading. { @@ -1253,7 +1342,26 @@ ISR(TIMER0_COMPB_vect) bed_max_temp_error(); } #endif - } + } + +#ifdef BABYSTEPPING + for(uint8_t axis=0;axis<3;axis++) + { + int curTodo=babystepsTodo[axis]; //get rid of volatile for performance + + if(curTodo>0) + { + babystep(axis,/*fwd*/true); + babystepsTodo[axis]--; //less to do next time + } + else + if(curTodo<0) + { + babystep(axis,/*fwd*/false); + babystepsTodo[axis]++; //less to do next time + } + } +#endif //BABYSTEPPING } #ifdef PIDTEMP diff --git a/Marlin/temperature.h b/Marlin/temperature.h index 75ffcd06b..df2b5deac 100644 --- a/Marlin/temperature.h +++ b/Marlin/temperature.h @@ -28,19 +28,27 @@ #endif // public functions -void tp_init(); //initialise the heating +void tp_init(); //initialize the heating void manage_heater(); //it is critical that this is called periodically. // low level conversion routines // do not use these routines and variables outside of temperature.cpp extern int target_temperature[EXTRUDERS]; extern float current_temperature[EXTRUDERS]; +#ifdef SHOW_TEMP_ADC_VALUES + extern int current_temperature_raw[EXTRUDERS]; + extern int current_temperature_bed_raw; +#endif extern int target_temperature_bed; extern float current_temperature_bed; #ifdef TEMP_SENSOR_1_AS_REDUNDANT extern float redundant_temperature; #endif +#if defined(CONTROLLERFAN_PIN) && CONTROLLERFAN_PIN > -1 + extern unsigned char soft_pwm_bed; +#endif + #ifdef PIDTEMP extern float Kp,Ki,Kd,Kc; float scalePID_i(float i); @@ -53,6 +61,11 @@ extern float current_temperature_bed; extern float bedKp,bedKi,bedKd; #endif + +#ifdef BABYSTEPPING + extern volatile int babystepsTodo[3]; +#endif + //high level conversion routines, for use outside of temperature.cpp //inline so that there is no performance decrease. //deg=degreeCelsius @@ -61,6 +74,16 @@ FORCE_INLINE float degHotend(uint8_t extruder) { return current_temperature[extruder]; }; +#ifdef SHOW_TEMP_ADC_VALUES + FORCE_INLINE float rawHotendTemp(uint8_t extruder) { + return current_temperature_raw[extruder]; + }; + + FORCE_INLINE float rawBedTemp() { + return current_temperature_bed_raw; + }; +#endif + FORCE_INLINE float degBed() { return current_temperature_bed; }; @@ -131,6 +154,17 @@ void disable_heater(); void setWatch(); void updatePID(); +#ifdef THERMAL_RUNAWAY_PROTECTION_PERIOD && THERMAL_RUNAWAY_PROTECTION_PERIOD > 0 +void thermal_runaway_protection(int *state, unsigned long *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc); +static int thermal_runaway_state_machine[3]; // = {0,0,0}; +static unsigned long thermal_runaway_timer[3]; // = {0,0,0}; +static bool thermal_runaway = false; + #if TEMP_SENSOR_BED != 0 + static int thermal_runaway_bed_state_machine; + static unsigned long thermal_runaway_bed_timer; + #endif +#endif + FORCE_INLINE void autotempShutdown(){ #ifdef AUTOTEMP if(autotemp_enabled) diff --git a/Marlin/thermistortables.h b/Marlin/thermistortables.h index 09182208f..86bf5c2d4 100644 --- a/Marlin/thermistortables.h +++ b/Marlin/thermistortables.h @@ -314,6 +314,158 @@ const short temptable_7[][2] PROGMEM = { {1023*OVERSAMPLENR, 0} //to allow internal 0 degrees C }; #endif + +#if (THERMISTORHEATER_0 == 71) || (THERMISTORHEATER_1 == 71) || (THERMISTORHEATER_2 == 71) || (THERMISTORBED == 71) // 100k Honeywell 135-104LAF-J01 +// R0 = 100000 Ohm +// T0 = 25 °C +// Beta = 3974 +// R1 = 0 Ohm +// R2 = 4700 Ohm +const short temptable_71[][2] PROGMEM = { + {35*OVERSAMPLENR, 300}, + {51*OVERSAMPLENR, 270}, + {54*OVERSAMPLENR, 265}, + {58*OVERSAMPLENR, 260}, + {59*OVERSAMPLENR, 258}, + {61*OVERSAMPLENR, 256}, + {63*OVERSAMPLENR, 254}, + {64*OVERSAMPLENR, 252}, + {66*OVERSAMPLENR, 250}, + {67*OVERSAMPLENR, 249}, + {68*OVERSAMPLENR, 248}, + {69*OVERSAMPLENR, 247}, + {70*OVERSAMPLENR, 246}, + {71*OVERSAMPLENR, 245}, + {72*OVERSAMPLENR, 244}, + {73*OVERSAMPLENR, 243}, + {74*OVERSAMPLENR, 242}, + {75*OVERSAMPLENR, 241}, + {76*OVERSAMPLENR, 240}, + {77*OVERSAMPLENR, 239}, + {78*OVERSAMPLENR, 238}, + {79*OVERSAMPLENR, 237}, + {80*OVERSAMPLENR, 236}, + {81*OVERSAMPLENR, 235}, + {82*OVERSAMPLENR, 234}, + {84*OVERSAMPLENR, 233}, + {85*OVERSAMPLENR, 232}, + {86*OVERSAMPLENR, 231}, + {87*OVERSAMPLENR, 230}, + {89*OVERSAMPLENR, 229}, + {90*OVERSAMPLENR, 228}, + {91*OVERSAMPLENR, 227}, + {92*OVERSAMPLENR, 226}, + {94*OVERSAMPLENR, 225}, + {95*OVERSAMPLENR, 224}, + {97*OVERSAMPLENR, 223}, + {98*OVERSAMPLENR, 222}, + {99*OVERSAMPLENR, 221}, + {101*OVERSAMPLENR, 220}, + {102*OVERSAMPLENR, 219}, + {104*OVERSAMPLENR, 218}, + {106*OVERSAMPLENR, 217}, + {107*OVERSAMPLENR, 216}, + {109*OVERSAMPLENR, 215}, + {110*OVERSAMPLENR, 214}, + {112*OVERSAMPLENR, 213}, + {114*OVERSAMPLENR, 212}, + {115*OVERSAMPLENR, 211}, + {117*OVERSAMPLENR, 210}, + {119*OVERSAMPLENR, 209}, + {121*OVERSAMPLENR, 208}, + {123*OVERSAMPLENR, 207}, + {125*OVERSAMPLENR, 206}, + {126*OVERSAMPLENR, 205}, + {128*OVERSAMPLENR, 204}, + {130*OVERSAMPLENR, 203}, + {132*OVERSAMPLENR, 202}, + {134*OVERSAMPLENR, 201}, + {136*OVERSAMPLENR, 200}, + {139*OVERSAMPLENR, 199}, + {141*OVERSAMPLENR, 198}, + {143*OVERSAMPLENR, 197}, + {145*OVERSAMPLENR, 196}, + {147*OVERSAMPLENR, 195}, + {150*OVERSAMPLENR, 194}, + {152*OVERSAMPLENR, 193}, + {154*OVERSAMPLENR, 192}, + {157*OVERSAMPLENR, 191}, + {159*OVERSAMPLENR, 190}, + {162*OVERSAMPLENR, 189}, + {164*OVERSAMPLENR, 188}, + {167*OVERSAMPLENR, 187}, + {170*OVERSAMPLENR, 186}, + {172*OVERSAMPLENR, 185}, + {175*OVERSAMPLENR, 184}, + {178*OVERSAMPLENR, 183}, + {181*OVERSAMPLENR, 182}, + {184*OVERSAMPLENR, 181}, + {187*OVERSAMPLENR, 180}, + {190*OVERSAMPLENR, 179}, + {193*OVERSAMPLENR, 178}, + {196*OVERSAMPLENR, 177}, + {199*OVERSAMPLENR, 176}, + {202*OVERSAMPLENR, 175}, + {205*OVERSAMPLENR, 174}, + {208*OVERSAMPLENR, 173}, + {212*OVERSAMPLENR, 172}, + {215*OVERSAMPLENR, 171}, + {219*OVERSAMPLENR, 170}, + {237*OVERSAMPLENR, 165}, + {256*OVERSAMPLENR, 160}, + {300*OVERSAMPLENR, 150}, + {351*OVERSAMPLENR, 140}, + {470*OVERSAMPLENR, 120}, + {504*OVERSAMPLENR, 115}, + {538*OVERSAMPLENR, 110}, + {552*OVERSAMPLENR, 108}, + {566*OVERSAMPLENR, 106}, + {580*OVERSAMPLENR, 104}, + {594*OVERSAMPLENR, 102}, + {608*OVERSAMPLENR, 100}, + {622*OVERSAMPLENR, 98}, + {636*OVERSAMPLENR, 96}, + {650*OVERSAMPLENR, 94}, + {664*OVERSAMPLENR, 92}, + {678*OVERSAMPLENR, 90}, + {712*OVERSAMPLENR, 85}, + {745*OVERSAMPLENR, 80}, + {758*OVERSAMPLENR, 78}, + {770*OVERSAMPLENR, 76}, + {783*OVERSAMPLENR, 74}, + {795*OVERSAMPLENR, 72}, + {806*OVERSAMPLENR, 70}, + {818*OVERSAMPLENR, 68}, + {829*OVERSAMPLENR, 66}, + {840*OVERSAMPLENR, 64}, + {850*OVERSAMPLENR, 62}, + {860*OVERSAMPLENR, 60}, + {870*OVERSAMPLENR, 58}, + {879*OVERSAMPLENR, 56}, + {888*OVERSAMPLENR, 54}, + {897*OVERSAMPLENR, 52}, + {905*OVERSAMPLENR, 50}, + {924*OVERSAMPLENR, 45}, + {940*OVERSAMPLENR, 40}, + {955*OVERSAMPLENR, 35}, + {967*OVERSAMPLENR, 30}, + {970*OVERSAMPLENR, 29}, + {972*OVERSAMPLENR, 28}, + {974*OVERSAMPLENR, 27}, + {976*OVERSAMPLENR, 26}, + {978*OVERSAMPLENR, 25}, + {980*OVERSAMPLENR, 24}, + {982*OVERSAMPLENR, 23}, + {984*OVERSAMPLENR, 22}, + {985*OVERSAMPLENR, 21}, + {987*OVERSAMPLENR, 20}, + {995*OVERSAMPLENR, 15}, + {1001*OVERSAMPLENR, 10}, + {1006*OVERSAMPLENR, 5}, + {1010*OVERSAMPLENR, 0}, +}; +#endif + #if (THERMISTORHEATER_0 == 8) || (THERMISTORHEATER_1 == 8) || (THERMISTORHEATER_2 == 8) || (THERMISTORBED == 8) // 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) const short temptable_8[][2] PROGMEM = { @@ -412,6 +564,135 @@ const short temptable_10[][2] PROGMEM = { }; #endif +#if (THERMISTORHEATER_0 == 11) || (THERMISTORHEATER_1 == 11) || (THERMISTORHEATER_2 == 11) || (THERMISTORBED == 11) +// QU-BD silicone bed QWG-104F-3950 thermistor + +const short temptable_11[][2] PROGMEM = { + {1*OVERSAMPLENR, 938}, + {31*OVERSAMPLENR, 314}, + {41*OVERSAMPLENR, 290}, + {51*OVERSAMPLENR, 272}, + {61*OVERSAMPLENR, 258}, + {71*OVERSAMPLENR, 247}, + {81*OVERSAMPLENR, 237}, + {91*OVERSAMPLENR, 229}, + {101*OVERSAMPLENR, 221}, + {111*OVERSAMPLENR, 215}, + {121*OVERSAMPLENR, 209}, + {131*OVERSAMPLENR, 204}, + {141*OVERSAMPLENR, 199}, + {151*OVERSAMPLENR, 195}, + {161*OVERSAMPLENR, 190}, + {171*OVERSAMPLENR, 187}, + {181*OVERSAMPLENR, 183}, + {191*OVERSAMPLENR, 179}, + {201*OVERSAMPLENR, 176}, + {221*OVERSAMPLENR, 170}, + {241*OVERSAMPLENR, 165}, + {261*OVERSAMPLENR, 160}, + {281*OVERSAMPLENR, 155}, + {301*OVERSAMPLENR, 150}, + {331*OVERSAMPLENR, 144}, + {361*OVERSAMPLENR, 139}, + {391*OVERSAMPLENR, 133}, + {421*OVERSAMPLENR, 128}, + {451*OVERSAMPLENR, 123}, + {491*OVERSAMPLENR, 117}, + {531*OVERSAMPLENR, 111}, + {571*OVERSAMPLENR, 105}, + {611*OVERSAMPLENR, 100}, + {641*OVERSAMPLENR, 95}, + {681*OVERSAMPLENR, 90}, + {711*OVERSAMPLENR, 85}, + {751*OVERSAMPLENR, 79}, + {791*OVERSAMPLENR, 72}, + {811*OVERSAMPLENR, 69}, + {831*OVERSAMPLENR, 65}, + {871*OVERSAMPLENR, 57}, + {881*OVERSAMPLENR, 55}, + {901*OVERSAMPLENR, 51}, + {921*OVERSAMPLENR, 45}, + {941*OVERSAMPLENR, 39}, + {971*OVERSAMPLENR, 28}, + {981*OVERSAMPLENR, 23}, + {991*OVERSAMPLENR, 17}, + {1001*OVERSAMPLENR, 9}, + {1021*OVERSAMPLENR, -27} +}; +#endif + +#if (THERMISTORHEATER_0 == 20) || (THERMISTORHEATER_1 == 20) || (THERMISTORHEATER_2 == 20) || (THERMISTORBED == 20) // PT100 with INA826 amp on Ultimaker v2.0 electronics +/* The PT100 in the Ultimaker v2.0 electronics has a high sample value for a high temperature. +This does not match the normal thermistor behaviour so we need to set the following defines */ +#if (THERMISTORHEATER_0 == 20) +# define HEATER_0_RAW_HI_TEMP 16383 +# define HEATER_0_RAW_LO_TEMP 0 +#endif +#if (THERMISTORHEATER_1 == 20) +# define HEATER_1_RAW_HI_TEMP 16383 +# define HEATER_1_RAW_LO_TEMP 0 +#endif +#if (THERMISTORHEATER_2 == 20) +# define HEATER_2_RAW_HI_TEMP 16383 +# define HEATER_2_RAW_LO_TEMP 0 +#endif +#if (THERMISTORBED == 20) +# define HEATER_BED_RAW_HI_TEMP 16383 +# define HEATER_BED_RAW_LO_TEMP 0 +#endif +const short temptable_20[][2] PROGMEM = { +{ 0*OVERSAMPLENR , 0 }, +{ 227*OVERSAMPLENR , 1 }, +{ 236*OVERSAMPLENR , 10 }, +{ 245*OVERSAMPLENR , 20 }, +{ 253*OVERSAMPLENR , 30 }, +{ 262*OVERSAMPLENR , 40 }, +{ 270*OVERSAMPLENR , 50 }, +{ 279*OVERSAMPLENR , 60 }, +{ 287*OVERSAMPLENR , 70 }, +{ 295*OVERSAMPLENR , 80 }, +{ 304*OVERSAMPLENR , 90 }, +{ 312*OVERSAMPLENR , 100 }, +{ 320*OVERSAMPLENR , 110 }, +{ 329*OVERSAMPLENR , 120 }, +{ 337*OVERSAMPLENR , 130 }, +{ 345*OVERSAMPLENR , 140 }, +{ 353*OVERSAMPLENR , 150 }, +{ 361*OVERSAMPLENR , 160 }, +{ 369*OVERSAMPLENR , 170 }, +{ 377*OVERSAMPLENR , 180 }, +{ 385*OVERSAMPLENR , 190 }, +{ 393*OVERSAMPLENR , 200 }, +{ 401*OVERSAMPLENR , 210 }, +{ 409*OVERSAMPLENR , 220 }, +{ 417*OVERSAMPLENR , 230 }, +{ 424*OVERSAMPLENR , 240 }, +{ 432*OVERSAMPLENR , 250 }, +{ 440*OVERSAMPLENR , 260 }, +{ 447*OVERSAMPLENR , 270 }, +{ 455*OVERSAMPLENR , 280 }, +{ 463*OVERSAMPLENR , 290 }, +{ 470*OVERSAMPLENR , 300 }, +{ 478*OVERSAMPLENR , 310 }, +{ 485*OVERSAMPLENR , 320 }, +{ 493*OVERSAMPLENR , 330 }, +{ 500*OVERSAMPLENR , 340 }, +{ 507*OVERSAMPLENR , 350 }, +{ 515*OVERSAMPLENR , 360 }, +{ 522*OVERSAMPLENR , 370 }, +{ 529*OVERSAMPLENR , 380 }, +{ 537*OVERSAMPLENR , 390 }, +{ 544*OVERSAMPLENR , 400 }, +{ 614*OVERSAMPLENR , 500 }, +{ 681*OVERSAMPLENR , 600 }, +{ 744*OVERSAMPLENR , 700 }, +{ 805*OVERSAMPLENR , 800 }, +{ 862*OVERSAMPLENR , 900 }, +{ 917*OVERSAMPLENR , 1000 }, +{ 968*OVERSAMPLENR , 1100 } +}; +#endif + #if (THERMISTORHEATER_0 == 51) || (THERMISTORHEATER_1 == 51) || (THERMISTORHEATER_2 == 51) || (THERMISTORBED == 51) // 100k EPCOS (WITH 1kohm RESISTOR FOR PULLUP, R9 ON SANGUINOLOLU! NOT FOR 4.7kohm PULLUP! THIS IS NOT NORMAL!) // Verified by linagee. @@ -557,6 +838,14 @@ const short temptable_55[][2] PROGMEM = { #endif #if (THERMISTORHEATER_0 == 60) || (THERMISTORHEATER_1 == 60) || (THERMISTORHEATER_2 == 60) || (THERMISTORBED == 60) // Maker's Tool Works Kapton Bed Thermister +// ./createTemperatureLookup.py --r0=100000 --t0=25 --r1=0 --r2=4700 --beta=3950 +// r0: 100000 +// t0: 25 +// r1: 0 (parallel with rTherm) +// r2: 4700 (series with rTherm) +// beta: 3950 +// min adc: 1 at 0.0048828125 V +// max adc: 1023 at 4.9951171875 V const short temptable_60[][2] PROGMEM = { {51*OVERSAMPLENR, 272}, {61*OVERSAMPLENR, 258}, @@ -632,7 +921,181 @@ const short temptable_60[][2] PROGMEM = { {1008*OVERSAMPLENR, 0}, }; #endif +#if (THERMISTORBED == 12) +//100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) (calibrated for Makibox hot bed) +const short temptable_12[][2] PROGMEM = { + {35*OVERSAMPLENR, 180}, //top rating 180C + {211*OVERSAMPLENR, 140}, + {233*OVERSAMPLENR, 135}, + {261*OVERSAMPLENR, 130}, + {290*OVERSAMPLENR, 125}, + {328*OVERSAMPLENR, 120}, + {362*OVERSAMPLENR, 115}, + {406*OVERSAMPLENR, 110}, + {446*OVERSAMPLENR, 105}, + {496*OVERSAMPLENR, 100}, + {539*OVERSAMPLENR, 95}, + {585*OVERSAMPLENR, 90}, + {629*OVERSAMPLENR, 85}, + {675*OVERSAMPLENR, 80}, + {718*OVERSAMPLENR, 75}, + {758*OVERSAMPLENR, 70}, + {793*OVERSAMPLENR, 65}, + {822*OVERSAMPLENR, 60}, + {841*OVERSAMPLENR, 55}, + {875*OVERSAMPLENR, 50}, + {899*OVERSAMPLENR, 45}, + {926*OVERSAMPLENR, 40}, + {946*OVERSAMPLENR, 35}, + {962*OVERSAMPLENR, 30}, + {977*OVERSAMPLENR, 25}, + {987*OVERSAMPLENR, 20}, + {995*OVERSAMPLENR, 15}, + {1001*OVERSAMPLENR, 10}, + {1010*OVERSAMPLENR, 0}, + {1023*OVERSAMPLENR, -40}, +}; +#endif + +// Pt1000 and Pt100 handling +// +// Rt=R0*(1+a*T+b*T*T) [for T>0] +// a=3.9083E-3, b=-5.775E-7 +#define PtA 3.9083E-3 +#define PtB -5.775E-7 +#define PtRt(T,R0) ((R0)*(1.0+(PtA)*(T)+(PtB)*(T)*(T))) +#define PtAdVal(T,R0,Rup) (short)(1024/(Rup/PtRt(T,R0)+1)) +#define PtLine(T,R0,Rup) { PtAdVal(T,R0,Rup)*OVERSAMPLENR, T }, + +#if (THERMISTORHEATER_0 == 110) || (THERMISTORHEATER_1 == 110) || (THERMISTORHEATER_2 == 110) || (THERMISTORBED == 110) // Pt100 with 1k0 pullup +const short temptable_110[][2] PROGMEM = { +// only few values are needed as the curve is very flat + PtLine(0,100,1000) + PtLine(50,100,1000) + PtLine(100,100,1000) + PtLine(150,100,1000) + PtLine(200,100,1000) + PtLine(250,100,1000) + PtLine(300,100,1000) +}; +#endif +#if (THERMISTORHEATER_0 == 147) || (THERMISTORHEATER_1 == 147) || (THERMISTORHEATER_2 == 147) || (THERMISTORBED == 147) // Pt100 with 4k7 pullup +const short temptable_147[][2] PROGMEM = { +// only few values are needed as the curve is very flat + PtLine(0,100,4700) + PtLine(50,100,4700) + PtLine(100,100,4700) + PtLine(150,100,4700) + PtLine(200,100,4700) + PtLine(250,100,4700) + PtLine(300,100,4700) +}; +#endif +#if (THERMISTORHEATER_0 == 1010) || (THERMISTORHEATER_1 == 1010) || (THERMISTORHEATER_2 == 1010) || (THERMISTORBED == 1010) // Pt1000 with 1k0 pullup +const short temptable_1010[][2] PROGMEM = { + PtLine(0,1000,1000) + PtLine(25,1000,1000) + PtLine(50,1000,1000) + PtLine(75,1000,1000) + PtLine(100,1000,1000) + PtLine(125,1000,1000) + PtLine(150,1000,1000) + PtLine(175,1000,1000) + PtLine(200,1000,1000) + PtLine(225,1000,1000) + PtLine(250,1000,1000) + PtLine(275,1000,1000) + PtLine(300,1000,1000) +}; +#endif +#if (THERMISTORHEATER_0 == 1047) || (THERMISTORHEATER_1 == 1047) || (THERMISTORHEATER_2 == 1047) || (THERMISTORBED == 1047) // Pt1000 with 4k7 pullup +const short temptable_1047[][2] PROGMEM = { +// only few values are needed as the curve is very flat + PtLine(0,1000,4700) + PtLine(50,1000,4700) + PtLine(100,1000,4700) + PtLine(150,1000,4700) + PtLine(200,1000,4700) + PtLine(250,1000,4700) + PtLine(300,1000,4700) +}; +#endif +#if (THERMISTORHEATER_0 == 70) || (THERMISTORHEATER_1 == 70) || (THERMISTORHEATER_2 == 70) || (THERMISTORBED == 70) // 500C thermistor for Pico hot end +const short temptable_70[][2] PROGMEM = { + { 110.774119598719*OVERSAMPLENR , 350 }, + { 118.214386957249*OVERSAMPLENR , 345 }, + { 126.211418543166*OVERSAMPLENR , 340 }, + { 134.789559066223*OVERSAMPLENR , 335 }, + { 144.004513869701*OVERSAMPLENR , 330 }, + { 153.884483790827*OVERSAMPLENR , 325 }, + { 164.484880793637*OVERSAMPLENR , 320 }, + { 175.848885102724*OVERSAMPLENR , 315 }, + { 188.006799079015*OVERSAMPLENR , 310 }, + { 201.008072969044*OVERSAMPLENR , 305 }, + { 214.83716032276*OVERSAMPLENR , 300 }, + { 229.784739779664*OVERSAMPLENR , 295 }, + { 245.499466045473*OVERSAMPLENR , 290 }, + { 262.2766342096*OVERSAMPLENR , 285 }, + { 280.073883176433*OVERSAMPLENR , 280 }, + { 298.952693467726*OVERSAMPLENR , 275 }, + { 318.808251051674*OVERSAMPLENR , 270 }, + { 337.490932563222*OVERSAMPLENR , 265 }, + { 361.683649122745*OVERSAMPLENR , 260 }, + { 384.717024083981*OVERSAMPLENR , 255 }, + { 408.659301759076*OVERSAMPLENR , 250 }, + { 433.471659455884*OVERSAMPLENR , 245 }, + { 459.199039926034*OVERSAMPLENR , 240 }, + { 485.566500982316*OVERSAMPLENR , 235 }, + { 512.538918631075*OVERSAMPLENR , 230 }, + { 539.980999544838*OVERSAMPLENR , 225 }, + { 567.783095549935*OVERSAMPLENR , 220 }, + { 595.698041673552*OVERSAMPLENR , 215 }, + { 623.633922319597*OVERSAMPLENR , 210 }, + { 651.356162750829*OVERSAMPLENR , 205 }, + { 678.700901620956*OVERSAMPLENR , 200 }, + { 705.528145361264*OVERSAMPLENR , 195 }, + { 731.61267976339*OVERSAMPLENR , 190 }, + { 756.786212184365*OVERSAMPLENR , 185 }, + { 780.950223357761*OVERSAMPLENR , 180 }, + { 804.012961595082*OVERSAMPLENR , 175 }, + { 825.904975939166*OVERSAMPLENR , 170 }, + { 846.403941639008*OVERSAMPLENR , 165 }, + { 865.52326974895*OVERSAMPLENR , 160 }, + { 883.246145367727*OVERSAMPLENR , 155 }, + { 899.5821946515*OVERSAMPLENR , 150 }, + { 914.544289228582*OVERSAMPLENR , 145 }, + { 928.145628221761*OVERSAMPLENR , 140 }, + { 940.422208546562*OVERSAMPLENR , 135 }, + { 951.456922916497*OVERSAMPLENR , 130 }, + { 961.303500633788*OVERSAMPLENR , 125 }, + { 970.044756889055*OVERSAMPLENR , 120 }, + { 977.761456230051*OVERSAMPLENR , 115 }, + { 984.540978083453*OVERSAMPLENR , 110 }, + { 990.440780765757*OVERSAMPLENR , 105 }, + { 995.589621465301*OVERSAMPLENR , 100 }, + { 1000.02514280144*OVERSAMPLENR , 95 }, + { 1003.84429789876*OVERSAMPLENR , 90 }, + { 1007.10199009318*OVERSAMPLENR , 85 }, + { 1009.87151698323*OVERSAMPLENR , 80 }, + { 1012.21633594237*OVERSAMPLENR , 75 }, + { 1014.18959892949*OVERSAMPLENR , 70 }, + { 1015.84079162998*OVERSAMPLENR , 65 }, + { 1017.21555915335*OVERSAMPLENR , 60 }, + { 1018.35284662863*OVERSAMPLENR , 55 }, + { 1019.28926921888*OVERSAMPLENR , 50 }, + { 1020.05398015669*OVERSAMPLENR , 45 }, + { 1020.67737496272*OVERSAMPLENR , 40 }, + { 1021.1802909627*OVERSAMPLENR , 35 }, + { 1021.58459281248*OVERSAMPLENR , 30 }, + { 1021.90701441192*OVERSAMPLENR , 25 }, + { 1022.16215103698*OVERSAMPLENR , 20 }, + { 1022.36275529549*OVERSAMPLENR , 15 }, + { 1022.51930392497*OVERSAMPLENR , 10 }, + { 1022.64051573734*OVERSAMPLENR , 5 }, + { 1022.73355805611*OVERSAMPLENR , 0 } +}; +#endif #define _TT_NAME(_N) temptable_ ## _N #define TT_NAME(_N) _TT_NAME(_N) diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index f6fc82d40..18c85887a 100644 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -18,6 +18,11 @@ int plaPreheatFanSpeed; int absPreheatHotendTemp; int absPreheatHPBTemp; int absPreheatFanSpeed; + +#ifdef ULTIPANEL +static float manual_feedrate[] = MANUAL_FEEDRATE; +#endif // ULTIPANEL + /* !Configuration settings */ //Function pointer to menu functions. @@ -32,7 +37,7 @@ char lcd_status_message[LCD_WIDTH+1] = WELCOME_MSG; #include "ultralcd_implementation_hitachi_HD44780.h" #endif -/** forward declerations **/ +/** forward declarations **/ void copy_and_scalePID_i(); void copy_and_scalePID_d(); @@ -56,9 +61,9 @@ static void lcd_set_contrast(); static void lcd_control_retract_menu(); static void lcd_sdcard_menu(); -static void lcd_quick_feedback();//Cause an LCD refresh, and give the user visual or audiable feedback that something has happend +static void lcd_quick_feedback();//Cause an LCD refresh, and give the user visual or audible feedback that something has happened -/* Different types of actions that can be used in menuitems. */ +/* Different types of actions that can be used in menu items. */ static void menu_action_back(menuFunc_t data); static void menu_action_submenu(menuFunc_t data); static void menu_action_gcode(const char* pgcode); @@ -85,9 +90,19 @@ static void menu_action_setting_edit_callback_long5(const char* pstr, unsigned l #define ENCODER_FEEDRATE_DEADZONE 10 #if !defined(LCD_I2C_VIKI) - #define ENCODER_STEPS_PER_MENU_ITEM 5 + #ifndef ENCODER_STEPS_PER_MENU_ITEM + #define ENCODER_STEPS_PER_MENU_ITEM 5 + #endif + #ifndef ENCODER_PULSES_PER_STEP + #define ENCODER_PULSES_PER_STEP 1 + #endif #else - #define ENCODER_STEPS_PER_MENU_ITEM 2 // VIKI LCD rotary encoder uses a different number of steps per rotation + #ifndef ENCODER_STEPS_PER_MENU_ITEM + #define ENCODER_STEPS_PER_MENU_ITEM 2 // VIKI LCD rotary encoder uses a different number of steps per rotation + #endif + #ifndef ENCODER_PULSES_PER_STEP + #define ENCODER_PULSES_PER_STEP 1 + #endif #endif @@ -96,6 +111,7 @@ static void menu_action_setting_edit_callback_long5(const char* pstr, unsigned l if (encoderPosition > 0x8000) encoderPosition = 0; \ if (encoderPosition / ENCODER_STEPS_PER_MENU_ITEM < currentMenuViewOffset) currentMenuViewOffset = encoderPosition / ENCODER_STEPS_PER_MENU_ITEM;\ uint8_t _lineNr = currentMenuViewOffset, _menuItemNr; \ + bool wasClicked = LCD_CLICKED;\ for(uint8_t _drawLineNr = 0; _drawLineNr < LCD_HEIGHT; _drawLineNr++, _lineNr++) { \ _menuItemNr = 0; #define MENU_ITEM(type, label, args...) do { \ @@ -108,7 +124,7 @@ static void menu_action_setting_edit_callback_long5(const char* pstr, unsigned l lcd_implementation_drawmenu_ ## type (_drawLineNr, _label_pstr , ## args ); \ }\ }\ - if (LCD_CLICKED && (encoderPosition / ENCODER_STEPS_PER_MENU_ITEM) == _menuItemNr) {\ + if (wasClicked && (encoderPosition / ENCODER_STEPS_PER_MENU_ITEM) == _menuItemNr) {\ lcd_quick_feedback(); \ menu_action_ ## type ( args ); \ return;\ @@ -128,7 +144,10 @@ static void menu_action_setting_edit_callback_long5(const char* pstr, unsigned l #ifndef REPRAPWORLD_KEYPAD volatile uint8_t buttons;//Contains the bits of the currently pressed buttons. #else -volatile uint8_t buttons_reprapworld_keypad; // to store the reprapworld_keypad shiftregister values +volatile uint8_t buttons_reprapworld_keypad; // to store the reprapworld_keypad shift register values +#endif +#ifdef LCD_HAS_SLOW_BUTTONS +volatile uint8_t slow_buttons;//Contains the bits of the currently pressed buttons. #endif uint8_t currentMenuViewOffset; /* scroll offset in the current menu */ uint32_t blocking_enc; @@ -142,7 +161,7 @@ bool lcd_oldcardstatus; menuFunc_t currentMenu = lcd_status_screen; /* function pointer to the currently active menu */ uint32_t lcd_next_update_millis; uint8_t lcd_status_update_delay; -uint8_t lcdDrawUpdate = 2; /* Set to none-zero when the LCD needs to draw, decreased after every draw. Set to 2 in LCD routines so the LCD gets atleast 1 full redraw (first redraw is partial) */ +uint8_t lcdDrawUpdate = 2; /* Set to none-zero when the LCD needs to draw, decreased after every draw. Set to 2 in LCD routines so the LCD gets at least 1 full redraw (first redraw is partial) */ //prevMenu and prevEncoderPosition are used to store the previous menu location when editing settings. menuFunc_t prevMenu = NULL; @@ -153,10 +172,10 @@ void* editValue; int32_t minEditValue, maxEditValue; menuFunc_t callbackFunc; -// placeholders for Ki and Kd edits +// place-holders for Ki and Kd edits float raw_Ki, raw_Kd; -/* Main status screen. It's up to the implementation specific part to show what is needed. As this is very display dependend */ +/* Main status screen. It's up to the implementation specific part to show what is needed. As this is very display dependent */ static void lcd_status_screen() { if (lcd_status_update_delay) @@ -174,8 +193,10 @@ static void lcd_status_screen() currentMenu = lcd_main_menu; encoderPosition = 0; lcd_quick_feedback(); + lcd_implementation_init(); // to maybe revive the LCD if static electricity killed it. } +#ifdef ULTIPANEL_FEEDMULTIPLY // Dead zone at 100% feedrate if ((feedmultiply < 100 && (feedmultiply + int(encoderPosition)) > 100) || (feedmultiply > 100 && (feedmultiply + int(encoderPosition)) < 100)) @@ -192,13 +213,14 @@ static void lcd_status_screen() else if (feedmultiply == 100 && int(encoderPosition) < -ENCODER_FEEDRATE_DEADZONE) { feedmultiply += int(encoderPosition) + ENCODER_FEEDRATE_DEADZONE; - encoderPosition = 0; + encoderPosition = 0; } else if (feedmultiply != 100) { feedmultiply += int(encoderPosition); encoderPosition = 0; } +#endif//ULTIPANEL_FEEDMULTIPLY if (feedmultiply < 10) feedmultiply = 10; @@ -233,6 +255,8 @@ static void lcd_sdcard_stop() enquecommand_P(PSTR(SD_FINISHED_RELEASECOMMAND)); } autotempShutdown(); + + cancel_heatup = true; } /* Menu implementation */ @@ -282,36 +306,67 @@ static void lcd_autostart_sd() } #endif -void lcd_preheat_pla() +#ifdef BABYSTEPPING +static void lcd_babystep_x() { - setTargetHotend0(plaPreheatHotendTemp); - setTargetHotend1(plaPreheatHotendTemp); - setTargetHotend2(plaPreheatHotendTemp); - setTargetBed(plaPreheatHPBTemp); - fanSpeed = plaPreheatFanSpeed; - lcd_return_to_status(); - setWatch(); // heater sanity check timer + if (encoderPosition != 0) + { + babystepsTodo[X_AXIS]+=(int)encoderPosition; + encoderPosition=0; + lcdDrawUpdate = 1; + } + if (lcdDrawUpdate) + { + lcd_implementation_drawedit(PSTR(MSG_BABYSTEPPING_X),""); + } + if (LCD_CLICKED) + { + lcd_quick_feedback(); + currentMenu = lcd_tune_menu; + encoderPosition = 0; + } } -void lcd_preheat_abs() +static void lcd_babystep_y() { - setTargetHotend0(absPreheatHotendTemp); - setTargetHotend1(absPreheatHotendTemp); - setTargetHotend2(absPreheatHotendTemp); - setTargetBed(absPreheatHPBTemp); - fanSpeed = absPreheatFanSpeed; - lcd_return_to_status(); - setWatch(); // heater sanity check timer + if (encoderPosition != 0) + { + babystepsTodo[Y_AXIS]+=(int)encoderPosition; + encoderPosition=0; + lcdDrawUpdate = 1; + } + if (lcdDrawUpdate) + { + lcd_implementation_drawedit(PSTR(MSG_BABYSTEPPING_Y),""); + } + if (LCD_CLICKED) + { + lcd_quick_feedback(); + currentMenu = lcd_tune_menu; + encoderPosition = 0; + } } -static void lcd_cooldown() +static void lcd_babystep_z() { - setTargetHotend0(0); - setTargetHotend1(0); - setTargetHotend2(0); - setTargetBed(0); - lcd_return_to_status(); + if (encoderPosition != 0) + { + babystepsTodo[Z_AXIS]+=BABYSTEP_Z_MULTIPLICATOR*(int)encoderPosition; + encoderPosition=0; + lcdDrawUpdate = 1; + } + if (lcdDrawUpdate) + { + lcd_implementation_drawedit(PSTR(MSG_BABYSTEPPING_Z),""); + } + if (LCD_CLICKED) + { + lcd_quick_feedback(); + currentMenu = lcd_tune_menu; + encoderPosition = 0; + } } +#endif //BABYSTEPPING static void lcd_tune_menu() { @@ -330,24 +385,196 @@ static void lcd_tune_menu() #endif MENU_ITEM_EDIT(int3, MSG_FAN_SPEED, &fanSpeed, 0, 255); MENU_ITEM_EDIT(int3, MSG_FLOW, &extrudemultiply, 10, 999); + MENU_ITEM_EDIT(int3, MSG_FLOW0, &extruder_multiply[0], 10, 999); +#if TEMP_SENSOR_1 != 0 + MENU_ITEM_EDIT(int3, MSG_FLOW1, &extruder_multiply[1], 10, 999); +#endif +#if TEMP_SENSOR_2 != 0 + MENU_ITEM_EDIT(int3, MSG_FLOW2, &extruder_multiply[2], 10, 999); +#endif + +#ifdef BABYSTEPPING + #ifdef BABYSTEP_XY + MENU_ITEM(submenu, MSG_BABYSTEP_X, lcd_babystep_x); + MENU_ITEM(submenu, MSG_BABYSTEP_Y, lcd_babystep_y); + #endif //BABYSTEP_XY + MENU_ITEM(submenu, MSG_BABYSTEP_Z, lcd_babystep_z); +#endif #ifdef FILAMENTCHANGEENABLE MENU_ITEM(gcode, MSG_FILAMENTCHANGE, PSTR("M600")); #endif END_MENU(); } +void lcd_preheat_pla0() +{ + setTargetHotend0(plaPreheatHotendTemp); + setTargetBed(plaPreheatHPBTemp); + fanSpeed = plaPreheatFanSpeed; + lcd_return_to_status(); + setWatch(); // heater sanity check timer +} + +void lcd_preheat_abs0() +{ + setTargetHotend0(absPreheatHotendTemp); + setTargetBed(absPreheatHPBTemp); + fanSpeed = absPreheatFanSpeed; + lcd_return_to_status(); + setWatch(); // heater sanity check timer +} + +#if TEMP_SENSOR_1 != 0 //2nd extruder preheat +void lcd_preheat_pla1() +{ + setTargetHotend1(plaPreheatHotendTemp); + setTargetBed(plaPreheatHPBTemp); + fanSpeed = plaPreheatFanSpeed; + lcd_return_to_status(); + setWatch(); // heater sanity check timer +} + +void lcd_preheat_abs1() +{ + setTargetHotend1(absPreheatHotendTemp); + setTargetBed(absPreheatHPBTemp); + fanSpeed = absPreheatFanSpeed; + lcd_return_to_status(); + setWatch(); // heater sanity check timer +} +#endif //2nd extruder preheat + +#if TEMP_SENSOR_2 != 0 //3 extruder preheat +void lcd_preheat_pla2() +{ + setTargetHotend2(plaPreheatHotendTemp); + setTargetBed(plaPreheatHPBTemp); + fanSpeed = plaPreheatFanSpeed; + lcd_return_to_status(); + setWatch(); // heater sanity check timer +} + +void lcd_preheat_abs2() +{ + setTargetHotend2(absPreheatHotendTemp); + setTargetBed(absPreheatHPBTemp); + fanSpeed = absPreheatFanSpeed; + lcd_return_to_status(); + setWatch(); // heater sanity check timer +} +#endif //3 extruder preheat + +#if TEMP_SENSOR_1 != 0 || TEMP_SENSOR_2 != 0 //more than one extruder present +void lcd_preheat_pla012() +{ + setTargetHotend0(plaPreheatHotendTemp); + setTargetHotend1(plaPreheatHotendTemp); + setTargetHotend2(plaPreheatHotendTemp); + setTargetBed(plaPreheatHPBTemp); + fanSpeed = plaPreheatFanSpeed; + lcd_return_to_status(); + setWatch(); // heater sanity check timer +} + +void lcd_preheat_abs012() +{ + setTargetHotend0(absPreheatHotendTemp); + setTargetHotend1(absPreheatHotendTemp); + setTargetHotend2(absPreheatHotendTemp); + setTargetBed(absPreheatHPBTemp); + fanSpeed = absPreheatFanSpeed; + lcd_return_to_status(); + setWatch(); // heater sanity check timer +} +#endif //more than one extruder present + +void lcd_preheat_pla_bedonly() +{ + setTargetBed(plaPreheatHPBTemp); + fanSpeed = plaPreheatFanSpeed; + lcd_return_to_status(); + setWatch(); // heater sanity check timer +} + +void lcd_preheat_abs_bedonly() +{ + setTargetBed(absPreheatHPBTemp); + fanSpeed = absPreheatFanSpeed; + lcd_return_to_status(); + setWatch(); // heater sanity check timer +} + +static void lcd_preheat_pla_menu() +{ + START_MENU(); + MENU_ITEM(back, MSG_PREPARE, lcd_prepare_menu); + MENU_ITEM(function, MSG_PREHEAT_PLA0, lcd_preheat_pla0); +#if TEMP_SENSOR_1 != 0 //2 extruder preheat + MENU_ITEM(function, MSG_PREHEAT_PLA1, lcd_preheat_pla1); +#endif //2 extruder preheat +#if TEMP_SENSOR_2 != 0 //3 extruder preheat + MENU_ITEM(function, MSG_PREHEAT_PLA2, lcd_preheat_pla2); +#endif //3 extruder preheat +#if TEMP_SENSOR_1 != 0 || TEMP_SENSOR_2 != 0 //all extruder preheat + MENU_ITEM(function, MSG_PREHEAT_PLA012, lcd_preheat_pla012); +#endif //2 extruder preheat +#if TEMP_SENSOR_BED != 0 + MENU_ITEM(function, MSG_PREHEAT_PLA_BEDONLY, lcd_preheat_pla_bedonly); +#endif + END_MENU(); +} + +static void lcd_preheat_abs_menu() +{ + START_MENU(); + MENU_ITEM(back, MSG_PREPARE, lcd_prepare_menu); + MENU_ITEM(function, MSG_PREHEAT_ABS0, lcd_preheat_abs0); +#if TEMP_SENSOR_1 != 0 //2 extruder preheat + MENU_ITEM(function, MSG_PREHEAT_ABS1, lcd_preheat_abs1); +#endif //2 extruder preheat +#if TEMP_SENSOR_2 != 0 //3 extruder preheat + MENU_ITEM(function, MSG_PREHEAT_ABS2, lcd_preheat_abs2); +#endif //3 extruder preheat +#if TEMP_SENSOR_1 != 0 || TEMP_SENSOR_2 != 0 //all extruder preheat + MENU_ITEM(function, MSG_PREHEAT_ABS012, lcd_preheat_abs012); +#endif //2 extruder preheat +#if TEMP_SENSOR_BED != 0 + MENU_ITEM(function, MSG_PREHEAT_ABS_BEDONLY, lcd_preheat_abs_bedonly); +#endif + END_MENU(); +} + +void lcd_cooldown() +{ + setTargetHotend0(0); + setTargetHotend1(0); + setTargetHotend2(0); + setTargetBed(0); + fanSpeed = 0; + lcd_return_to_status(); +} + static void lcd_prepare_menu() { START_MENU(); MENU_ITEM(back, MSG_MAIN, lcd_main_menu); #ifdef SDSUPPORT - //MENU_ITEM(function, MSG_AUTOSTART, lcd_autostart_sd); + #ifdef MENU_ADDAUTOSTART + MENU_ITEM(function, MSG_AUTOSTART, lcd_autostart_sd); + #endif #endif MENU_ITEM(gcode, MSG_DISABLE_STEPPERS, PSTR("M84")); MENU_ITEM(gcode, MSG_AUTO_HOME, PSTR("G28")); //MENU_ITEM(gcode, MSG_SET_ORIGIN, PSTR("G92 X0 Y0 Z0")); - MENU_ITEM(function, MSG_PREHEAT_PLA, lcd_preheat_pla); - MENU_ITEM(function, MSG_PREHEAT_ABS, lcd_preheat_abs); +#if TEMP_SENSOR_0 != 0 + #if TEMP_SENSOR_1 != 0 || TEMP_SENSOR_2 != 0 || TEMP_SENSOR_BED != 0 + MENU_ITEM(submenu, MSG_PREHEAT_PLA, lcd_preheat_pla_menu); + MENU_ITEM(submenu, MSG_PREHEAT_ABS, lcd_preheat_abs_menu); + #else + MENU_ITEM(function, MSG_PREHEAT_PLA, lcd_preheat_pla0); + MENU_ITEM(function, MSG_PREHEAT_ABS, lcd_preheat_abs0); + #endif +#endif MENU_ITEM(function, MSG_COOLDOWN, lcd_cooldown); #if PS_ON_PIN > -1 if (powersupply) @@ -368,13 +595,19 @@ static void lcd_move_x() { if (encoderPosition != 0) { + refresh_cmd_timeout(); current_position[X_AXIS] += float((int)encoderPosition) * move_menu_scale; if (min_software_endstops && current_position[X_AXIS] < X_MIN_POS) current_position[X_AXIS] = X_MIN_POS; if (max_software_endstops && current_position[X_AXIS] > X_MAX_POS) current_position[X_AXIS] = X_MAX_POS; encoderPosition = 0; - plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 600, active_extruder); + #ifdef DELTA + calculate_delta(current_position); + plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS], manual_feedrate[X_AXIS]/60, active_extruder); + #else + plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], manual_feedrate[X_AXIS]/60, active_extruder); + #endif lcdDrawUpdate = 1; } if (lcdDrawUpdate) @@ -392,13 +625,19 @@ static void lcd_move_y() { if (encoderPosition != 0) { + refresh_cmd_timeout(); current_position[Y_AXIS] += float((int)encoderPosition) * move_menu_scale; if (min_software_endstops && current_position[Y_AXIS] < Y_MIN_POS) current_position[Y_AXIS] = Y_MIN_POS; if (max_software_endstops && current_position[Y_AXIS] > Y_MAX_POS) current_position[Y_AXIS] = Y_MAX_POS; encoderPosition = 0; - plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 600, active_extruder); + #ifdef DELTA + calculate_delta(current_position); + plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS], manual_feedrate[Y_AXIS]/60, active_extruder); + #else + plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], manual_feedrate[Y_AXIS]/60, active_extruder); + #endif lcdDrawUpdate = 1; } if (lcdDrawUpdate) @@ -416,13 +655,19 @@ static void lcd_move_z() { if (encoderPosition != 0) { + refresh_cmd_timeout(); current_position[Z_AXIS] += float((int)encoderPosition) * move_menu_scale; if (min_software_endstops && current_position[Z_AXIS] < Z_MIN_POS) current_position[Z_AXIS] = Z_MIN_POS; if (max_software_endstops && current_position[Z_AXIS] > Z_MAX_POS) current_position[Z_AXIS] = Z_MAX_POS; encoderPosition = 0; - plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], homing_feedrate[Z_AXIS]/60, active_extruder); + #ifdef DELTA + calculate_delta(current_position); + plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS], manual_feedrate[Z_AXIS]/60, active_extruder); + #else + plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], manual_feedrate[Z_AXIS]/60, active_extruder); + #endif lcdDrawUpdate = 1; } if (lcdDrawUpdate) @@ -442,7 +687,12 @@ static void lcd_move_e() { current_position[E_AXIS] += float((int)encoderPosition) * move_menu_scale; encoderPosition = 0; - plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 20, active_extruder); + #ifdef DELTA + calculate_delta(current_position); + plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS], manual_feedrate[E_AXIS]/60, active_extruder); + #else + plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], manual_feedrate[E_AXIS]/60, active_extruder); + #endif lcdDrawUpdate = 1; } if (lcdDrawUpdate) @@ -461,12 +711,12 @@ static void lcd_move_menu_axis() { START_MENU(); MENU_ITEM(back, MSG_MOVE_AXIS, lcd_move_menu); - MENU_ITEM(submenu, "Move X", lcd_move_x); - MENU_ITEM(submenu, "Move Y", lcd_move_y); + MENU_ITEM(submenu, MSG_MOVE_X, lcd_move_x); + MENU_ITEM(submenu, MSG_MOVE_Y, lcd_move_y); if (move_menu_scale < 10.0) { - MENU_ITEM(submenu, "Move Z", lcd_move_z); - MENU_ITEM(submenu, "Extruder", lcd_move_e); + MENU_ITEM(submenu, MSG_MOVE_Z, lcd_move_z); + MENU_ITEM(submenu, MSG_MOVE_E, lcd_move_e); } END_MENU(); } @@ -491,9 +741,9 @@ static void lcd_move_menu() { START_MENU(); MENU_ITEM(back, MSG_PREPARE, lcd_prepare_menu); - MENU_ITEM(submenu, "Move 10mm", lcd_move_menu_10mm); - MENU_ITEM(submenu, "Move 1mm", lcd_move_menu_1mm); - MENU_ITEM(submenu, "Move 0.1mm", lcd_move_menu_01mm); + MENU_ITEM(submenu, MSG_MOVE_10MM, lcd_move_menu_10mm); + MENU_ITEM(submenu, MSG_MOVE_1MM, lcd_move_menu_1mm); + MENU_ITEM(submenu, MSG_MOVE_01MM, lcd_move_menu_01mm); //TODO:X,Y,Z,E END_MENU(); } @@ -594,6 +844,9 @@ static void lcd_control_motion_menu() { START_MENU(); MENU_ITEM(back, MSG_CONTROL, lcd_control_menu); +#ifdef ENABLE_AUTO_BED_LEVELING + MENU_ITEM_EDIT(float32, MSG_ZPROBE_ZOFFSET, &zprobe_zoffset, 0.5, 50); +#endif MENU_ITEM_EDIT(float5, MSG_ACC, &acceleration, 500, 99000); MENU_ITEM_EDIT(float3, MSG_VXY_JERK, &max_xy_jerk, 1, 990); MENU_ITEM_EDIT(float52, MSG_VZ_JERK, &max_z_jerk, 0.1, 990); @@ -612,9 +865,9 @@ static void lcd_control_motion_menu() MENU_ITEM_EDIT(float52, MSG_XSTEPS, &axis_steps_per_unit[X_AXIS], 5, 9999); MENU_ITEM_EDIT(float52, MSG_YSTEPS, &axis_steps_per_unit[Y_AXIS], 5, 9999); MENU_ITEM_EDIT(float51, MSG_ZSTEPS, &axis_steps_per_unit[Z_AXIS], 5, 9999); - MENU_ITEM_EDIT(float51, MSG_ESTEPS, &axis_steps_per_unit[E_AXIS], 5, 9999); + MENU_ITEM_EDIT(float51, MSG_ESTEPS, &axis_steps_per_unit[E_AXIS], 5, 9999); #ifdef ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED - MENU_ITEM_EDIT(bool, "Endstop abort", &abort_on_endstop_hit); + MENU_ITEM_EDIT(bool, MSG_ENDSTOP_ABORT, &abort_on_endstop_hit); #endif END_MENU(); } @@ -633,7 +886,7 @@ static void lcd_set_contrast() } if (lcdDrawUpdate) { - lcd_implementation_drawedit(PSTR("Contrast"), itostr2(lcd_contrast)); + lcd_implementation_drawedit(PSTR(MSG_CONTRAST), itostr2(lcd_contrast)); } if (LCD_CLICKED) { @@ -674,6 +927,8 @@ static void lcd_sd_updir() void lcd_sdcard_menu() { + if (lcdDrawUpdate == 0 && LCD_CLICKED == 0) + return; // nothing to do (so don't thrash the SD card) uint16_t fileCnt = card.getnrfilenames(); START_MENU(); MENU_ITEM(back, MSG_MAIN, lcd_main_menu); @@ -686,12 +941,16 @@ void lcd_sdcard_menu() }else{ MENU_ITEM(function, LCD_STR_FOLDER "..", lcd_sd_updir); } - + for(uint16_t i=0;i 0 - pinMode(BTN_ENC,INPUT); + pinMode(BTN_ENC,INPUT); WRITE(BTN_ENC,HIGH); - #endif + #endif #ifdef REPRAPWORLD_KEYPAD pinMode(SHIFT_CLK,OUTPUT); pinMode(SHIFT_LD,OUTPUT); @@ -884,42 +1142,56 @@ void lcd_init() WRITE(SHIFT_OUT,HIGH); WRITE(SHIFT_LD,HIGH); #endif -#else - pinMode(SHIFT_CLK,OUTPUT); - pinMode(SHIFT_LD,OUTPUT); - pinMode(SHIFT_EN,OUTPUT); - pinMode(SHIFT_OUT,INPUT); - WRITE(SHIFT_OUT,HIGH); - WRITE(SHIFT_LD,HIGH); - WRITE(SHIFT_EN,LOW); +#else // Not NEWPANEL + #ifdef SR_LCD_2W_NL // Non latching 2 wire shift register + pinMode (SR_DATA_PIN, OUTPUT); + pinMode (SR_CLK_PIN, OUTPUT); + #elif defined(SHIFT_CLK) + pinMode(SHIFT_CLK,OUTPUT); + pinMode(SHIFT_LD,OUTPUT); + pinMode(SHIFT_EN,OUTPUT); + pinMode(SHIFT_OUT,INPUT); + WRITE(SHIFT_OUT,HIGH); + WRITE(SHIFT_LD,HIGH); + WRITE(SHIFT_EN,LOW); + #else + #ifdef ULTIPANEL + #error ULTIPANEL requires an encoder + #endif + #endif // SR_LCD_2W_NL #endif//!NEWPANEL -#if (SDCARDDETECT > 0) + +#if defined (SDSUPPORT) && defined(SDCARDDETECT) && (SDCARDDETECT > 0) + pinMode(SDCARDDETECT,INPUT); WRITE(SDCARDDETECT, HIGH); lcd_oldcardstatus = IS_SD_INSERTED; #endif//(SDCARDDETECT > 0) +#ifdef LCD_HAS_SLOW_BUTTONS + slow_buttons = 0; +#endif lcd_buttons_update(); -#ifdef ULTIPANEL +#ifdef ULTIPANEL encoderDiff = 0; -#endif +#endif } void lcd_update() { static unsigned long timeoutToStatus = 0; - - lcd_buttons_update(); - + #ifdef LCD_HAS_SLOW_BUTTONS - buttons |= lcd_implementation_read_slow_buttons(); // buttons which take too long to read in interrupt context + slow_buttons = lcd_implementation_read_slow_buttons(); // buttons which take too long to read in interrupt context #endif - + + lcd_buttons_update(); + #if (SDCARDDETECT > 0) if((IS_SD_INSERTED != lcd_oldcardstatus)) { lcdDrawUpdate = 2; lcd_oldcardstatus = IS_SD_INSERTED; - lcd_implementation_init(); // to maybe revive the lcd if static electricty killed it. - + lcd_implementation_init(); // to maybe revive the LCD if static electricity killed it. + if(lcd_oldcardstatus) { card.initsd(); @@ -932,7 +1204,7 @@ void lcd_update() } } #endif//CARDINSERTED - + if (lcd_next_update_millis < millis()) { #ifdef ULTIPANEL @@ -959,10 +1231,10 @@ void lcd_update() reprapworld_keypad_move_home(); } #endif - if (encoderDiff) + if (abs(encoderDiff) >= ENCODER_PULSES_PER_STEP) { lcdDrawUpdate = 1; - encoderPosition += encoderDiff; + encoderPosition += encoderDiff / ENCODER_PULSES_PER_STEP; encoderDiff = 0; timeoutToStatus = millis() + LCD_TIMEOUT_TO_STATUS; } @@ -973,7 +1245,7 @@ void lcd_update() #ifdef DOGLCD // Changes due to different driver architecture of the DOGM display blink++; // Variable for fan animation and alive dot u8g.firstPage(); - do + do { u8g.setFont(u8g_font_6x10_marlin); u8g.setPrintPos(125,0); @@ -983,7 +1255,7 @@ void lcd_update() (*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 +#else (*currentMenu)(); #endif @@ -1037,7 +1309,7 @@ void lcd_reset_alert_level() void lcd_setcontrast(uint8_t value) { lcd_contrast = value & 63; - u8g.setContrast(lcd_contrast); + u8g.setContrast(lcd_contrast); } #endif @@ -1054,6 +1326,9 @@ void lcd_buttons_update() newbutton |= EN_C; #endif buttons = newbutton; + #ifdef LCD_HAS_SLOW_BUTTONS + buttons |= slow_buttons; + #endif #ifdef REPRAPWORLD_KEYPAD // for the reprapworld_keypad uint8_t newbutton_reprapworld_keypad=0; @@ -1074,7 +1349,7 @@ void lcd_buttons_update() WRITE(SHIFT_LD,HIGH); unsigned char tmp_buttons=0; for(int8_t i=0;i<8;i++) - { + { newbutton = newbutton>>1; if(READ(SHIFT_OUT)) newbutton|=(1<<7); @@ -1124,14 +1399,14 @@ void lcd_buttons_update() } void lcd_buzz(long duration, uint16_t freq) -{ +{ #ifdef LCD_USE_I2C_BUZZER lcd.buzz(duration,freq); -#endif +#endif } -bool lcd_clicked() -{ +bool lcd_clicked() +{ return LCD_CLICKED; } #endif//ULTIPANEL @@ -1330,7 +1605,7 @@ char *ftostr52(const float &x) } // Callback for after editing PID i value -// grab the pid i value out of the temp variable; scale it; then update the PID driver +// grab the PID i value out of the temp variable; scale it; then update the PID driver void copy_and_scalePID_i() { #ifdef PIDTEMP @@ -1340,7 +1615,7 @@ void copy_and_scalePID_i() } // Callback for after editing PID d value -// grab the pid d value out of the temp variable; scale it; then update the PID driver +// grab the PID d value out of the temp variable; scale it; then update the PID driver void copy_and_scalePID_d() { #ifdef PIDTEMP diff --git a/Marlin/ultralcd.h b/Marlin/ultralcd.h index d6fa0fdcf..9bf685805 100644 --- a/Marlin/ultralcd.h +++ b/Marlin/ultralcd.h @@ -17,7 +17,7 @@ void lcd_setcontrast(uint8_t value); #endif - static unsigned char blink = 0; // Variable for visualisation of fan rotation in GLCD + static unsigned char blink = 0; // Variable for visualization of fan rotation in GLCD #define LCD_MESSAGEPGM(x) lcd_setstatuspgm(PSTR(x)) #define LCD_ALERTMESSAGEPGM(x) lcd_setalertstatuspgm(PSTR(x)) @@ -29,7 +29,7 @@ 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 + extern volatile uint8_t buttons_reprapworld_keypad; // to store the keypad shift register values #endif #else FORCE_INLINE void lcd_buttons_update() {} @@ -42,6 +42,8 @@ extern int absPreheatHotendTemp; extern int absPreheatHPBTemp; extern int absPreheatFanSpeed; + + extern bool cancel_heatup; void lcd_buzz(long duration,uint16_t freq); bool lcd_clicked(); @@ -72,7 +74,7 @@ #define REPRAPWORLD_KEYPAD_MOVE_HOME (buttons_reprapworld_keypad&EN_REPRAPWORLD_KEYPAD_MIDDLE) #endif //REPRAPWORLD_KEYPAD #else - //atomatic, do not change + //atomic, do not change #define B_LE (1< -1 - // encoder click is directly connected - #define BLEN_C 2 - #define EN_C (1< -1 - // the pause/stop/restart button is connected to BTN_ENC when used - #define B_ST (EN_C) // Map the pause/stop/resume button into its normalized functional name - #define LCD_CLICKED (buttons&(B_MI|B_RI|B_ST)) // pause/stop button also acts as click until we implement proper pause/stop. - #else - #define LCD_CLICKED (buttons&(B_MI|B_RI)) - #endif - - // I2C buttons take too long to read inside an interrupt context and so we read them during lcd_update - #define LCD_HAS_SLOW_BUTTONS - -#elif defined(LCD_I2C_PANELOLU2) - // encoder click can be read through I2C if not directly connected - #if BTN_ENC <= 0 - #define B_I2C_BTN_OFFSET 3 // (the first three bit positions reserved for EN_A, EN_B, EN_C) - - #define B_MI (PANELOLU2_ENCODER_C< - #include - #include - #define LCD_CLASS LiquidCrystal_I2C - LCD_CLASS lcd(LCD_I2C_ADDRESS,LCD_I2C_PIN_EN,LCD_I2C_PIN_RW,LCD_I2C_PIN_RS,LCD_I2C_PIN_D4,LCD_I2C_PIN_D5,LCD_I2C_PIN_D6,LCD_I2C_PIN_D7); - -#elif defined(LCD_I2C_TYPE_MCP23017) - //for the LED indicators (which maybe mapped to different things in lcd_implementation_update_indicators()) - #define LED_A 0x04 //100 - #define LED_B 0x02 //010 - #define LED_C 0x01 //001 - - #define LCD_HAS_STATUS_INDICATORS - - #include - #include - #define LCD_CLASS LiquidTWI2 - LCD_CLASS lcd(LCD_I2C_ADDRESS); - -#elif defined(LCD_I2C_TYPE_MCP23008) - #include - #include - #define LCD_CLASS LiquidTWI2 - LCD_CLASS lcd(LCD_I2C_ADDRESS); - -#elif defined(LCD_I2C_TYPE_PCA8574) - #include - #define LCD_CLASS LiquidCrystal_I2C - LCD_CLASS lcd(LCD_I2C_ADDRESS, LCD_WIDTH, LCD_HEIGHT); - -#else - // Standard directly connected LCD implementations - #if LANGUAGE_CHOICE == 6 - #include "LiquidCrystalRus.h" - #define LCD_CLASS LiquidCrystalRus - #else - #include - #define LCD_CLASS LiquidCrystal - #endif - LCD_CLASS lcd(LCD_PINS_RS, LCD_PINS_ENABLE, LCD_PINS_D4, LCD_PINS_D5,LCD_PINS_D6,LCD_PINS_D7); //RS,Enable,D4,D5,D6,D7 -#endif - -/* Custom characters defined in the first 8 characters of the LCD */ -#define LCD_STR_BEDTEMP "\x00" -#define LCD_STR_DEGREE "\x01" -#define LCD_STR_THERMOMETER "\x02" -#define LCD_STR_UPLEVEL "\x03" -#define LCD_STR_REFRESH "\x04" -#define LCD_STR_FOLDER "\x05" -#define LCD_STR_FEEDRATE "\x06" -#define LCD_STR_CLOCK "\x07" -#define LCD_STR_ARROW_RIGHT "\x7E" /* from the default character set */ - -static void lcd_implementation_init() -{ - byte bedTemp[8] = - { - B00000, - B11111, - B10101, - B10001, - B10101, - B11111, - B00000, - B00000 - }; //thanks Sonny Mounicou - byte degree[8] = - { - B01100, - B10010, - B10010, - B01100, - B00000, - B00000, - B00000, - B00000 - }; - byte thermometer[8] = - { - B00100, - B01010, - B01010, - B01010, - B01010, - B10001, - B10001, - B01110 - }; - byte uplevel[8]={ - B00100, - B01110, - B11111, - B00100, - B11100, - B00000, - B00000, - B00000 - }; //thanks joris - byte refresh[8]={ - B00000, - B00110, - B11001, - B11000, - B00011, - B10011, - B01100, - B00000, - }; //thanks joris - byte folder [8]={ - B00000, - B11100, - B11111, - B10001, - B10001, - B11111, - B00000, - B00000 - }; //thanks joris - byte feedrate [8]={ - B11100, - B10000, - B11000, - B10111, - B00101, - B00110, - B00101, - B00000 - }; //thanks Sonny Mounicou - byte clock [8]={ - B00000, - B01110, - B10011, - B10101, - B10001, - B01110, - B00000, - B00000 - }; //thanks Sonny Mounicou - -#if defined(LCDI2C_TYPE_PCF8575) - lcd.begin(LCD_WIDTH, LCD_HEIGHT); - #ifdef LCD_I2C_PIN_BL - lcd.setBacklightPin(LCD_I2C_PIN_BL,POSITIVE); - lcd.setBacklight(HIGH); - #endif - -#elif defined(LCD_I2C_TYPE_MCP23017) - lcd.setMCPType(LTI_TYPE_MCP23017); - lcd.begin(LCD_WIDTH, LCD_HEIGHT); - lcd.setBacklight(0); //set all the LEDs off to begin with - -#elif defined(LCD_I2C_TYPE_MCP23008) - lcd.setMCPType(LTI_TYPE_MCP23008); - lcd.begin(LCD_WIDTH, LCD_HEIGHT); - -#elif defined(LCD_I2C_TYPE_PCA8574) - lcd.init(); - lcd.backlight(); - -#else - lcd.begin(LCD_WIDTH, LCD_HEIGHT); -#endif - - lcd.createChar(LCD_STR_BEDTEMP[0], bedTemp); - lcd.createChar(LCD_STR_DEGREE[0], degree); - lcd.createChar(LCD_STR_THERMOMETER[0], thermometer); - lcd.createChar(LCD_STR_UPLEVEL[0], uplevel); - lcd.createChar(LCD_STR_REFRESH[0], refresh); - lcd.createChar(LCD_STR_FOLDER[0], folder); - lcd.createChar(LCD_STR_FEEDRATE[0], feedrate); - lcd.createChar(LCD_STR_CLOCK[0], clock); - lcd.clear(); -} -static void lcd_implementation_clear() -{ - lcd.clear(); -} -/* Arduino < 1.0.0 is missing a function to print PROGMEM strings, so we need to implement our own */ -static void lcd_printPGM(const char* str) -{ - char c; - while((c = pgm_read_byte(str++)) != '\0') - { - lcd.write(c); - } -} -/* -Possible status screens: -16x2 |0123456789012345| - |000/000 B000/000| - |Status line.....| - -16x4 |0123456789012345| - |000/000 B000/000| - |SD100% Z000.0| - |F100% T--:--| - |Status line.....| - -20x2 |01234567890123456789| - |T000/000D B000/000D | - |Status line.........| - -20x4 |01234567890123456789| - |T000/000D B000/000D | - |X+000.0 Y+000.0 Z+000.0| - |F100% SD100% T--:--| - |Status line.........| - -20x4 |01234567890123456789| - |T000/000D B000/000D | - |T000/000D Z000.0| - |F100% SD100% T--:--| - |Status line.........| -*/ -static void lcd_implementation_status_screen() -{ - int tHotend=int(degHotend(0) + 0.5); - int tTarget=int(degTargetHotend(0) + 0.5); - -#if LCD_WIDTH < 20 - lcd.setCursor(0, 0); - lcd.print(itostr3(tHotend)); - lcd.print('/'); - lcd.print(itostr3left(tTarget)); - -# if EXTRUDERS > 1 || TEMP_SENSOR_BED != 0 - //If we have an 2nd extruder or heated bed, show that in the top right corner - lcd.setCursor(8, 0); -# if EXTRUDERS > 1 - tHotend = int(degHotend(1) + 0.5); - tTarget = int(degTargetHotend(1) + 0.5); - lcd.print(LCD_STR_THERMOMETER[0]); -# else//Heated bed - tHotend=int(degBed() + 0.5); - tTarget=int(degTargetBed() + 0.5); - lcd.print(LCD_STR_BEDTEMP[0]); -# endif - lcd.print(itostr3(tHotend)); - lcd.print('/'); - lcd.print(itostr3left(tTarget)); -# endif//EXTRUDERS > 1 || TEMP_SENSOR_BED != 0 - -#else//LCD_WIDTH > 19 - lcd.setCursor(0, 0); - lcd.print(LCD_STR_THERMOMETER[0]); - lcd.print(itostr3(tHotend)); - lcd.print('/'); - lcd.print(itostr3left(tTarget)); - lcd_printPGM(PSTR(LCD_STR_DEGREE " ")); - if (tTarget < 10) - lcd.print(' '); - -# if EXTRUDERS > 1 || TEMP_SENSOR_BED != 0 - //If we have an 2nd extruder or heated bed, show that in the top right corner - lcd.setCursor(10, 0); -# if EXTRUDERS > 1 - tHotend = int(degHotend(1) + 0.5); - tTarget = int(degTargetHotend(1) + 0.5); - lcd.print(LCD_STR_THERMOMETER[0]); -# else//Heated bed - tHotend=int(degBed() + 0.5); - tTarget=int(degTargetBed() + 0.5); - lcd.print(LCD_STR_BEDTEMP[0]); -# endif - lcd.print(itostr3(tHotend)); - lcd.print('/'); - lcd.print(itostr3left(tTarget)); - lcd_printPGM(PSTR(LCD_STR_DEGREE " ")); - if (tTarget < 10) - lcd.print(' '); -# endif//EXTRUDERS > 1 || TEMP_SENSOR_BED != 0 -#endif//LCD_WIDTH > 19 - -#if LCD_HEIGHT > 2 -//Lines 2 for 4 line LCD -# if LCD_WIDTH < 20 -# ifdef SDSUPPORT - lcd.setCursor(0, 2); - lcd_printPGM(PSTR("SD")); - if (IS_SD_PRINTING) - lcd.print(itostr3(card.percentDone())); - else - lcd_printPGM(PSTR("---")); - lcd.print('%'); -# endif//SDSUPPORT -# else//LCD_WIDTH > 19 -# if EXTRUDERS > 1 && TEMP_SENSOR_BED != 0 - //If we both have a 2nd extruder and a heated bed, show the heated bed temp on the 2nd line on the left, as the first line is filled with extruder temps - tHotend=int(degBed() + 0.5); - tTarget=int(degTargetBed() + 0.5); - - lcd.setCursor(0, 1); - lcd.print(LCD_STR_BEDTEMP[0]); - lcd.print(itostr3(tHotend)); - lcd.print('/'); - lcd.print(itostr3left(tTarget)); - lcd_printPGM(PSTR(LCD_STR_DEGREE " ")); - if (tTarget < 10) - lcd.print(' '); -# else - lcd.setCursor(0,1); - lcd.print('X'); - lcd.print(ftostr3(current_position[X_AXIS])); - lcd_printPGM(PSTR(" Y")); - lcd.print(ftostr3(current_position[Y_AXIS])); -# endif//EXTRUDERS > 1 || TEMP_SENSOR_BED != 0 -# endif//LCD_WIDTH > 19 - lcd.setCursor(LCD_WIDTH - 8, 1); - lcd.print('Z'); - lcd.print(ftostr32(current_position[Z_AXIS])); -#endif//LCD_HEIGHT > 2 - -#if LCD_HEIGHT > 3 - lcd.setCursor(0, 2); - lcd.print(LCD_STR_FEEDRATE[0]); - lcd.print(itostr3(feedmultiply)); - lcd.print('%'); -# if LCD_WIDTH > 19 -# ifdef SDSUPPORT - lcd.setCursor(7, 2); - lcd_printPGM(PSTR("SD")); - if (IS_SD_PRINTING) - lcd.print(itostr3(card.percentDone())); - else - lcd_printPGM(PSTR("---")); - lcd.print('%'); -# endif//SDSUPPORT -# endif//LCD_WIDTH > 19 - lcd.setCursor(LCD_WIDTH - 6, 2); - lcd.print(LCD_STR_CLOCK[0]); - if(starttime != 0) - { - uint16_t time = millis()/60000 - starttime/60000; - lcd.print(itostr2(time/60)); - lcd.print(':'); - lcd.print(itostr2(time%60)); - }else{ - lcd_printPGM(PSTR("--:--")); - } -#endif - - //Status message line on the last line - lcd.setCursor(0, LCD_HEIGHT - 1); - lcd.print(lcd_status_message); -} -static void lcd_implementation_drawmenu_generic(uint8_t row, const char* pstr, char pre_char, char post_char) -{ - char c; - //Use all characters in narrow LCDs - #if LCD_WIDTH < 20 - uint8_t n = LCD_WIDTH - 1 - 1; - #else - uint8_t n = LCD_WIDTH - 1 - 2; - #endif - lcd.setCursor(0, row); - lcd.print(pre_char); - while( ((c = pgm_read_byte(pstr)) != '\0') && (n>0) ) - { - lcd.print(c); - pstr++; - n--; - } - while(n--) - lcd.print(' '); - lcd.print(post_char); - lcd.print(' '); -} -static void lcd_implementation_drawmenu_setting_edit_generic(uint8_t row, const char* pstr, char pre_char, char* data) -{ - char c; - //Use all characters in narrow LCDs - #if LCD_WIDTH < 20 - uint8_t n = LCD_WIDTH - 1 - 1 - strlen(data); - #else - uint8_t n = LCD_WIDTH - 1 - 2 - strlen(data); - #endif - lcd.setCursor(0, row); - lcd.print(pre_char); - while( ((c = pgm_read_byte(pstr)) != '\0') && (n>0) ) - { - lcd.print(c); - pstr++; - n--; - } - lcd.print(':'); - while(n--) - lcd.print(' '); - lcd.print(data); -} -static void lcd_implementation_drawmenu_setting_edit_generic_P(uint8_t row, const char* pstr, char pre_char, const char* data) -{ - char c; - //Use all characters in narrow LCDs - #if LCD_WIDTH < 20 - uint8_t n = LCD_WIDTH - 1 - 1 - strlen_P(data); - #else - uint8_t n = LCD_WIDTH - 1 - 2 - strlen_P(data); - #endif - lcd.setCursor(0, row); - lcd.print(pre_char); - while( ((c = pgm_read_byte(pstr)) != '\0') && (n>0) ) - { - lcd.print(c); - pstr++; - n--; - } - lcd.print(':'); - while(n--) - lcd.print(' '); - lcd_printPGM(data); -} -#define lcd_implementation_drawmenu_setting_edit_int3_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', itostr3(*(data))) -#define lcd_implementation_drawmenu_setting_edit_int3(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', itostr3(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float3_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr3(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float3(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr3(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float32_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr32(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float32(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr32(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float5_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float5(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float52_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr52(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float52(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr52(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float51_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr51(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float51(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr51(*(data))) -#define lcd_implementation_drawmenu_setting_edit_long5_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data))) -#define lcd_implementation_drawmenu_setting_edit_long5(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data))) -#define lcd_implementation_drawmenu_setting_edit_bool_selected(row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, '>', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) -#define lcd_implementation_drawmenu_setting_edit_bool(row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, ' ', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) - -//Add version for callback functions -#define lcd_implementation_drawmenu_setting_edit_callback_int3_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', itostr3(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_int3(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', itostr3(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float3_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr3(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float3(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr3(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float32_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr32(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float32(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr32(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float5_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float5(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float52_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr52(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float52(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr52(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float51_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr51(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float51(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr51(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_long5_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_long5(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_bool_selected(row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, '>', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) -#define lcd_implementation_drawmenu_setting_edit_callback_bool(row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, ' ', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) - - -void lcd_implementation_drawedit(const char* pstr, char* value) -{ - lcd.setCursor(1, 1); - lcd_printPGM(pstr); - lcd.print(':'); - #if LCD_WIDTH < 20 - lcd.setCursor(LCD_WIDTH - strlen(value), 1); - #else - lcd.setCursor(LCD_WIDTH -1 - strlen(value), 1); - #endif - lcd.print(value); -} -static void lcd_implementation_drawmenu_sdfile_selected(uint8_t row, const char* pstr, const char* filename, char* longFilename) -{ - char c; - uint8_t n = LCD_WIDTH - 1; - lcd.setCursor(0, row); - lcd.print('>'); - if (longFilename[0] != '\0') - { - filename = longFilename; - longFilename[LCD_WIDTH-1] = '\0'; - } - while( ((c = *filename) != '\0') && (n>0) ) - { - lcd.print(c); - filename++; - n--; - } - while(n--) - lcd.print(' '); -} -static void lcd_implementation_drawmenu_sdfile(uint8_t row, const char* pstr, const char* filename, char* longFilename) -{ - char c; - uint8_t n = LCD_WIDTH - 1; - lcd.setCursor(0, row); - lcd.print(' '); - if (longFilename[0] != '\0') - { - filename = longFilename; - longFilename[LCD_WIDTH-1] = '\0'; - } - while( ((c = *filename) != '\0') && (n>0) ) - { - lcd.print(c); - filename++; - n--; - } - while(n--) - lcd.print(' '); -} -static void lcd_implementation_drawmenu_sddirectory_selected(uint8_t row, const char* pstr, const char* filename, char* longFilename) -{ - char c; - uint8_t n = LCD_WIDTH - 2; - lcd.setCursor(0, row); - lcd.print('>'); - lcd.print(LCD_STR_FOLDER[0]); - if (longFilename[0] != '\0') - { - filename = longFilename; - longFilename[LCD_WIDTH-2] = '\0'; - } - while( ((c = *filename) != '\0') && (n>0) ) - { - lcd.print(c); - filename++; - n--; - } - while(n--) - lcd.print(' '); -} -static void lcd_implementation_drawmenu_sddirectory(uint8_t row, const char* pstr, const char* filename, char* longFilename) -{ - char c; - uint8_t n = LCD_WIDTH - 2; - lcd.setCursor(0, row); - lcd.print(' '); - lcd.print(LCD_STR_FOLDER[0]); - if (longFilename[0] != '\0') - { - filename = longFilename; - longFilename[LCD_WIDTH-2] = '\0'; - } - while( ((c = *filename) != '\0') && (n>0) ) - { - lcd.print(c); - filename++; - n--; - } - while(n--) - lcd.print(' '); -} -#define lcd_implementation_drawmenu_back_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0]) -#define lcd_implementation_drawmenu_back(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', LCD_STR_UPLEVEL[0]) -#define lcd_implementation_drawmenu_submenu_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, '>', LCD_STR_ARROW_RIGHT[0]) -#define lcd_implementation_drawmenu_submenu(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', LCD_STR_ARROW_RIGHT[0]) -#define lcd_implementation_drawmenu_gcode_selected(row, pstr, gcode) lcd_implementation_drawmenu_generic(row, pstr, '>', ' ') -#define lcd_implementation_drawmenu_gcode(row, pstr, gcode) lcd_implementation_drawmenu_generic(row, pstr, ' ', ' ') -#define lcd_implementation_drawmenu_function_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, '>', ' ') -#define lcd_implementation_drawmenu_function(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', ' ') - -static void lcd_implementation_quick_feedback() -{ -#ifdef LCD_USE_I2C_BUZZER - lcd.buzz(60,1000/6); -#elif defined(BEEPER) && BEEPER > -1 - SET_OUTPUT(BEEPER); - for(int8_t i=0;i<10;i++) - { - WRITE(BEEPER,HIGH); - delayMicroseconds(100); - WRITE(BEEPER,LOW); - delayMicroseconds(100); - } -#endif -} - -#ifdef LCD_HAS_STATUS_INDICATORS -static void lcd_implementation_update_indicators() -{ - #if defined(LCD_I2C_PANELOLU2) || defined(LCD_I2C_VIKI) - //set the LEDS - referred to as backlights by the LiquidTWI2 library - static uint8_t ledsprev = 0; - uint8_t leds = 0; - if (target_temperature_bed > 0) leds |= LED_A; - if (target_temperature[0] > 0) leds |= LED_B; - if (fanSpeed) leds |= LED_C; - #if EXTRUDERS > 1 - if (target_temperature[1] > 0) leds |= LED_C; - #endif - if (leds != ledsprev) { - lcd.setBacklight(leds); - ledsprev = leds; - } - #endif -} -#endif - -#ifdef LCD_HAS_SLOW_BUTTONS -static uint8_t lcd_implementation_read_slow_buttons() -{ - #ifdef LCD_I2C_TYPE_MCP23017 - // Reading these buttons this is likely to be too slow to call inside interrupt context - // so they are called during normal lcd_update - return lcd.readButtons() << B_I2C_BTN_OFFSET; - #endif -} -#endif - -#endif//ULTRA_LCD_IMPLEMENTATION_HITACHI_HD44780_H +#ifndef ULTRA_LCD_IMPLEMENTATION_HITACHI_HD44780_H +#define ULTRA_LCD_IMPLEMENTATION_HITACHI_HD44780_H + +/** +* Implementation of the LCD display routines for a Hitachi HD44780 display. These are common LCD character displays. +* When selecting the Russian language, a slightly different LCD implementation is used to handle UTF8 characters. +**/ + +#ifndef REPRAPWORLD_KEYPAD +extern volatile uint8_t buttons; //the last checked buttons in a bit array. +#else +extern volatile uint16_t buttons; //an extended version of the last checked buttons in a bit array. +#endif + +//////////////////////////////////// +// Setup button and encode mappings for each panel (into 'buttons' variable +// +// This is just to map common functions (across different panels) onto the same +// macro name. The mapping is independent of whether the button is directly connected or +// via a shift/i2c register. + +#ifdef ULTIPANEL +// All UltiPanels might have an encoder - so this is always be mapped onto first two bits +#define BLEN_B 1 +#define BLEN_A 0 + +#define EN_B (1< -1 + // encoder click is directly connected + #define BLEN_C 2 + #define EN_C (1< -1 + // the pause/stop/restart button is connected to BTN_ENC when used + #define B_ST (EN_C) // Map the pause/stop/resume button into its normalized functional name + #define LCD_CLICKED (buttons&(B_MI|B_RI|B_ST)) // pause/stop button also acts as click until we implement proper pause/stop. + #else + #define LCD_CLICKED (buttons&(B_MI|B_RI)) + #endif + + // I2C buttons take too long to read inside an interrupt context and so we read them during lcd_update + #define LCD_HAS_SLOW_BUTTONS + +#elif defined(LCD_I2C_PANELOLU2) + // encoder click can be read through I2C if not directly connected + #if BTN_ENC <= 0 + #define B_I2C_BTN_OFFSET 3 // (the first three bit positions reserved for EN_A, EN_B, EN_C) + + #define B_MI (PANELOLU2_ENCODER_C< + #include + #include + #define LCD_CLASS LiquidCrystal_I2C + LCD_CLASS lcd(LCD_I2C_ADDRESS,LCD_I2C_PIN_EN,LCD_I2C_PIN_RW,LCD_I2C_PIN_RS,LCD_I2C_PIN_D4,LCD_I2C_PIN_D5,LCD_I2C_PIN_D6,LCD_I2C_PIN_D7); + +#elif defined(LCD_I2C_TYPE_MCP23017) + //for the LED indicators (which maybe mapped to different things in lcd_implementation_update_indicators()) + #define LED_A 0x04 //100 + #define LED_B 0x02 //010 + #define LED_C 0x01 //001 + + #define LCD_HAS_STATUS_INDICATORS + + #include + #include + #define LCD_CLASS LiquidTWI2 + LCD_CLASS lcd(LCD_I2C_ADDRESS); + +#elif defined(LCD_I2C_TYPE_MCP23008) + #include + #include + #define LCD_CLASS LiquidTWI2 + LCD_CLASS lcd(LCD_I2C_ADDRESS); + +#elif defined(LCD_I2C_TYPE_PCA8574) + #include + #define LCD_CLASS LiquidCrystal_I2C + LCD_CLASS lcd(LCD_I2C_ADDRESS, LCD_WIDTH, LCD_HEIGHT); + +// 2 wire Non-latching LCD SR from: +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/schematics#!shiftregister-connection +#elif defined(SR_LCD_2W_NL) + + #include + #include + #define LCD_CLASS LiquidCrystal_SR + LCD_CLASS lcd(SR_DATA_PIN, SR_CLK_PIN); + +#else + // Standard directly connected LCD implementations + #if LANGUAGE_CHOICE == 6 + #include "LiquidCrystalRus.h" + #define LCD_CLASS LiquidCrystalRus + #else + #include + #define LCD_CLASS LiquidCrystal + #endif + LCD_CLASS lcd(LCD_PINS_RS, LCD_PINS_ENABLE, LCD_PINS_D4, LCD_PINS_D5,LCD_PINS_D6,LCD_PINS_D7); //RS,Enable,D4,D5,D6,D7 +#endif + +/* Custom characters defined in the first 8 characters of the LCD */ +#define LCD_STR_BEDTEMP "\x00" +#define LCD_STR_DEGREE "\x01" +#define LCD_STR_THERMOMETER "\x02" +#define LCD_STR_UPLEVEL "\x03" +#define LCD_STR_REFRESH "\x04" +#define LCD_STR_FOLDER "\x05" +#define LCD_STR_FEEDRATE "\x06" +#define LCD_STR_CLOCK "\x07" +#define LCD_STR_ARROW_RIGHT "\x7E" /* from the default character set */ + +static void lcd_implementation_init() +{ + byte bedTemp[8] = + { + B00000, + B11111, + B10101, + B10001, + B10101, + B11111, + B00000, + B00000 + }; //thanks Sonny Mounicou + byte degree[8] = + { + B01100, + B10010, + B10010, + B01100, + B00000, + B00000, + B00000, + B00000 + }; + byte thermometer[8] = + { + B00100, + B01010, + B01010, + B01010, + B01010, + B10001, + B10001, + B01110 + }; + byte uplevel[8]={ + B00100, + B01110, + B11111, + B00100, + B11100, + B00000, + B00000, + B00000 + }; //thanks joris + byte refresh[8]={ + B00000, + B00110, + B11001, + B11000, + B00011, + B10011, + B01100, + B00000, + }; //thanks joris + byte folder [8]={ + B00000, + B11100, + B11111, + B10001, + B10001, + B11111, + B00000, + B00000 + }; //thanks joris + byte feedrate [8]={ + B11100, + B10000, + B11000, + B10111, + B00101, + B00110, + B00101, + B00000 + }; //thanks Sonny Mounicou + byte clock [8]={ + B00000, + B01110, + B10011, + B10101, + B10001, + B01110, + B00000, + B00000 + }; //thanks Sonny Mounicou + +#if defined(LCD_I2C_TYPE_PCF8575) + lcd.begin(LCD_WIDTH, LCD_HEIGHT); + #ifdef LCD_I2C_PIN_BL + lcd.setBacklightPin(LCD_I2C_PIN_BL,POSITIVE); + lcd.setBacklight(HIGH); + #endif + +#elif defined(LCD_I2C_TYPE_MCP23017) + lcd.setMCPType(LTI_TYPE_MCP23017); + lcd.begin(LCD_WIDTH, LCD_HEIGHT); + lcd.setBacklight(0); //set all the LEDs off to begin with + +#elif defined(LCD_I2C_TYPE_MCP23008) + lcd.setMCPType(LTI_TYPE_MCP23008); + lcd.begin(LCD_WIDTH, LCD_HEIGHT); + +#elif defined(LCD_I2C_TYPE_PCA8574) + lcd.init(); + lcd.backlight(); + +#else + lcd.begin(LCD_WIDTH, LCD_HEIGHT); +#endif + + lcd.createChar(LCD_STR_BEDTEMP[0], bedTemp); + lcd.createChar(LCD_STR_DEGREE[0], degree); + lcd.createChar(LCD_STR_THERMOMETER[0], thermometer); + lcd.createChar(LCD_STR_UPLEVEL[0], uplevel); + lcd.createChar(LCD_STR_REFRESH[0], refresh); + lcd.createChar(LCD_STR_FOLDER[0], folder); + lcd.createChar(LCD_STR_FEEDRATE[0], feedrate); + lcd.createChar(LCD_STR_CLOCK[0], clock); + lcd.clear(); +} +static void lcd_implementation_clear() +{ + lcd.clear(); +} +/* Arduino < 1.0.0 is missing a function to print PROGMEM strings, so we need to implement our own */ +static void lcd_printPGM(const char* str) +{ + char c; + while((c = pgm_read_byte(str++)) != '\0') + { + lcd.write(c); + } +} +/* +Possible status screens: +16x2 |0123456789012345| + |000/000 B000/000| + |Status line.....| + +16x4 |0123456789012345| + |000/000 B000/000| + |SD100% Z000.0| + |F100% T--:--| + |Status line.....| + +20x2 |01234567890123456789| + |T000/000D B000/000D | + |Status line.........| + +20x4 |01234567890123456789| + |T000/000D B000/000D | + |X+000.0 Y+000.0 Z+000.0| + |F100% SD100% T--:--| + |Status line.........| + +20x4 |01234567890123456789| + |T000/000D B000/000D | + |T000/000D Z000.0| + |F100% SD100% T--:--| + |Status line.........| +*/ +static void lcd_implementation_status_screen() +{ + int tHotend=int(degHotend(0) + 0.5); + int tTarget=int(degTargetHotend(0) + 0.5); + +#if LCD_WIDTH < 20 + lcd.setCursor(0, 0); + lcd.print(itostr3(tHotend)); + lcd.print('/'); + lcd.print(itostr3left(tTarget)); + +# if EXTRUDERS > 1 || TEMP_SENSOR_BED != 0 + //If we have an 2nd extruder or heated bed, show that in the top right corner + lcd.setCursor(8, 0); +# if EXTRUDERS > 1 + tHotend = int(degHotend(1) + 0.5); + tTarget = int(degTargetHotend(1) + 0.5); + lcd.print(LCD_STR_THERMOMETER[0]); +# else//Heated bed + tHotend=int(degBed() + 0.5); + tTarget=int(degTargetBed() + 0.5); + lcd.print(LCD_STR_BEDTEMP[0]); +# endif + lcd.print(itostr3(tHotend)); + lcd.print('/'); + lcd.print(itostr3left(tTarget)); +# endif//EXTRUDERS > 1 || TEMP_SENSOR_BED != 0 + +#else//LCD_WIDTH > 19 + lcd.setCursor(0, 0); + lcd.print(LCD_STR_THERMOMETER[0]); + lcd.print(itostr3(tHotend)); + lcd.print('/'); + lcd.print(itostr3left(tTarget)); + lcd_printPGM(PSTR(LCD_STR_DEGREE " ")); + if (tTarget < 10) + lcd.print(' '); + +# if EXTRUDERS > 1 || TEMP_SENSOR_BED != 0 + //If we have an 2nd extruder or heated bed, show that in the top right corner + lcd.setCursor(10, 0); +# if EXTRUDERS > 1 + tHotend = int(degHotend(1) + 0.5); + tTarget = int(degTargetHotend(1) + 0.5); + lcd.print(LCD_STR_THERMOMETER[0]); +# else//Heated bed + tHotend=int(degBed() + 0.5); + tTarget=int(degTargetBed() + 0.5); + lcd.print(LCD_STR_BEDTEMP[0]); +# endif + lcd.print(itostr3(tHotend)); + lcd.print('/'); + lcd.print(itostr3left(tTarget)); + lcd_printPGM(PSTR(LCD_STR_DEGREE " ")); + if (tTarget < 10) + lcd.print(' '); +# endif//EXTRUDERS > 1 || TEMP_SENSOR_BED != 0 +#endif//LCD_WIDTH > 19 + +#if LCD_HEIGHT > 2 +//Lines 2 for 4 line LCD +# if LCD_WIDTH < 20 +# ifdef SDSUPPORT + lcd.setCursor(0, 2); + lcd_printPGM(PSTR("SD")); + if (IS_SD_PRINTING) + lcd.print(itostr3(card.percentDone())); + else + lcd_printPGM(PSTR("---")); + lcd.print('%'); +# endif//SDSUPPORT +# else//LCD_WIDTH > 19 +# if EXTRUDERS > 1 && TEMP_SENSOR_BED != 0 + //If we both have a 2nd extruder and a heated bed, show the heated bed temp on the 2nd line on the left, as the first line is filled with extruder temps + tHotend=int(degBed() + 0.5); + tTarget=int(degTargetBed() + 0.5); + + lcd.setCursor(0, 1); + lcd.print(LCD_STR_BEDTEMP[0]); + lcd.print(itostr3(tHotend)); + lcd.print('/'); + lcd.print(itostr3left(tTarget)); + lcd_printPGM(PSTR(LCD_STR_DEGREE " ")); + if (tTarget < 10) + lcd.print(' '); +# else + lcd.setCursor(0,1); + lcd.print('X'); + lcd.print(ftostr3(current_position[X_AXIS])); + lcd_printPGM(PSTR(" Y")); + lcd.print(ftostr3(current_position[Y_AXIS])); +# endif//EXTRUDERS > 1 || TEMP_SENSOR_BED != 0 +# endif//LCD_WIDTH > 19 + lcd.setCursor(LCD_WIDTH - 8, 1); + lcd.print('Z'); + lcd.print(ftostr32(current_position[Z_AXIS])); +#endif//LCD_HEIGHT > 2 + +#if LCD_HEIGHT > 3 + lcd.setCursor(0, 2); + lcd.print(LCD_STR_FEEDRATE[0]); + lcd.print(itostr3(feedmultiply)); + lcd.print('%'); +# if LCD_WIDTH > 19 +# ifdef SDSUPPORT + lcd.setCursor(7, 2); + lcd_printPGM(PSTR("SD")); + if (IS_SD_PRINTING) + lcd.print(itostr3(card.percentDone())); + else + lcd_printPGM(PSTR("---")); + lcd.print('%'); +# endif//SDSUPPORT +# endif//LCD_WIDTH > 19 + lcd.setCursor(LCD_WIDTH - 6, 2); + lcd.print(LCD_STR_CLOCK[0]); + if(starttime != 0) + { + uint16_t time = millis()/60000 - starttime/60000; + lcd.print(itostr2(time/60)); + lcd.print(':'); + lcd.print(itostr2(time%60)); + }else{ + lcd_printPGM(PSTR("--:--")); + } +#endif + + //Status message line on the last line + lcd.setCursor(0, LCD_HEIGHT - 1); + lcd.print(lcd_status_message); +} +static void lcd_implementation_drawmenu_generic(uint8_t row, const char* pstr, char pre_char, char post_char) +{ + char c; + //Use all characters in narrow LCDs + #if LCD_WIDTH < 20 + uint8_t n = LCD_WIDTH - 1 - 1; + #else + uint8_t n = LCD_WIDTH - 1 - 2; + #endif + lcd.setCursor(0, row); + lcd.print(pre_char); + while( ((c = pgm_read_byte(pstr)) != '\0') && (n>0) ) + { + lcd.print(c); + pstr++; + n--; + } + while(n--) + lcd.print(' '); + lcd.print(post_char); + lcd.print(' '); +} +static void lcd_implementation_drawmenu_setting_edit_generic(uint8_t row, const char* pstr, char pre_char, char* data) +{ + char c; + //Use all characters in narrow LCDs + #if LCD_WIDTH < 20 + uint8_t n = LCD_WIDTH - 1 - 1 - strlen(data); + #else + uint8_t n = LCD_WIDTH - 1 - 2 - strlen(data); + #endif + lcd.setCursor(0, row); + lcd.print(pre_char); + while( ((c = pgm_read_byte(pstr)) != '\0') && (n>0) ) + { + lcd.print(c); + pstr++; + n--; + } + lcd.print(':'); + while(n--) + lcd.print(' '); + lcd.print(data); +} +static void lcd_implementation_drawmenu_setting_edit_generic_P(uint8_t row, const char* pstr, char pre_char, const char* data) +{ + char c; + //Use all characters in narrow LCDs + #if LCD_WIDTH < 20 + uint8_t n = LCD_WIDTH - 1 - 1 - strlen_P(data); + #else + uint8_t n = LCD_WIDTH - 1 - 2 - strlen_P(data); + #endif + lcd.setCursor(0, row); + lcd.print(pre_char); + while( ((c = pgm_read_byte(pstr)) != '\0') && (n>0) ) + { + lcd.print(c); + pstr++; + n--; + } + lcd.print(':'); + while(n--) + lcd.print(' '); + lcd_printPGM(data); +} +#define lcd_implementation_drawmenu_setting_edit_int3_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', itostr3(*(data))) +#define lcd_implementation_drawmenu_setting_edit_int3(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', itostr3(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float3_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr3(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float3(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr3(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float32_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr32(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float32(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr32(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float5_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float5(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float52_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr52(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float52(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr52(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float51_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr51(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float51(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr51(*(data))) +#define lcd_implementation_drawmenu_setting_edit_long5_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data))) +#define lcd_implementation_drawmenu_setting_edit_long5(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data))) +#define lcd_implementation_drawmenu_setting_edit_bool_selected(row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, '>', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) +#define lcd_implementation_drawmenu_setting_edit_bool(row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, ' ', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) + +//Add version for callback functions +#define lcd_implementation_drawmenu_setting_edit_callback_int3_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', itostr3(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_int3(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', itostr3(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float3_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr3(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float3(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr3(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float32_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr32(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float32(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr32(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float5_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float5(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float52_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr52(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float52(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr52(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float51_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr51(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float51(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr51(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_long5_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_long5(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_bool_selected(row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, '>', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) +#define lcd_implementation_drawmenu_setting_edit_callback_bool(row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, ' ', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) + + +void lcd_implementation_drawedit(const char* pstr, char* value) +{ + lcd.setCursor(1, 1); + lcd_printPGM(pstr); + lcd.print(':'); + #if LCD_WIDTH < 20 + lcd.setCursor(LCD_WIDTH - strlen(value), 1); + #else + lcd.setCursor(LCD_WIDTH -1 - strlen(value), 1); + #endif + lcd.print(value); +} +static void lcd_implementation_drawmenu_sdfile_selected(uint8_t row, const char* pstr, const char* filename, char* longFilename) +{ + char c; + uint8_t n = LCD_WIDTH - 1; + lcd.setCursor(0, row); + lcd.print('>'); + if (longFilename[0] != '\0') + { + filename = longFilename; + longFilename[LCD_WIDTH-1] = '\0'; + } + while( ((c = *filename) != '\0') && (n>0) ) + { + lcd.print(c); + filename++; + n--; + } + while(n--) + lcd.print(' '); +} +static void lcd_implementation_drawmenu_sdfile(uint8_t row, const char* pstr, const char* filename, char* longFilename) +{ + char c; + uint8_t n = LCD_WIDTH - 1; + lcd.setCursor(0, row); + lcd.print(' '); + if (longFilename[0] != '\0') + { + filename = longFilename; + longFilename[LCD_WIDTH-1] = '\0'; + } + while( ((c = *filename) != '\0') && (n>0) ) + { + lcd.print(c); + filename++; + n--; + } + while(n--) + lcd.print(' '); +} +static void lcd_implementation_drawmenu_sddirectory_selected(uint8_t row, const char* pstr, const char* filename, char* longFilename) +{ + char c; + uint8_t n = LCD_WIDTH - 2; + lcd.setCursor(0, row); + lcd.print('>'); + lcd.print(LCD_STR_FOLDER[0]); + if (longFilename[0] != '\0') + { + filename = longFilename; + longFilename[LCD_WIDTH-2] = '\0'; + } + while( ((c = *filename) != '\0') && (n>0) ) + { + lcd.print(c); + filename++; + n--; + } + while(n--) + lcd.print(' '); +} +static void lcd_implementation_drawmenu_sddirectory(uint8_t row, const char* pstr, const char* filename, char* longFilename) +{ + char c; + uint8_t n = LCD_WIDTH - 2; + lcd.setCursor(0, row); + lcd.print(' '); + lcd.print(LCD_STR_FOLDER[0]); + if (longFilename[0] != '\0') + { + filename = longFilename; + longFilename[LCD_WIDTH-2] = '\0'; + } + while( ((c = *filename) != '\0') && (n>0) ) + { + lcd.print(c); + filename++; + n--; + } + while(n--) + lcd.print(' '); +} +#define lcd_implementation_drawmenu_back_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0]) +#define lcd_implementation_drawmenu_back(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', LCD_STR_UPLEVEL[0]) +#define lcd_implementation_drawmenu_submenu_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, '>', LCD_STR_ARROW_RIGHT[0]) +#define lcd_implementation_drawmenu_submenu(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', LCD_STR_ARROW_RIGHT[0]) +#define lcd_implementation_drawmenu_gcode_selected(row, pstr, gcode) lcd_implementation_drawmenu_generic(row, pstr, '>', ' ') +#define lcd_implementation_drawmenu_gcode(row, pstr, gcode) lcd_implementation_drawmenu_generic(row, pstr, ' ', ' ') +#define lcd_implementation_drawmenu_function_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, '>', ' ') +#define lcd_implementation_drawmenu_function(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', ' ') + +static void lcd_implementation_quick_feedback() +{ +#ifdef LCD_USE_I2C_BUZZER + #if !defined(LCD_FEEDBACK_FREQUENCY_HZ) || !defined(LCD_FEEDBACK_FREQUENCY_DURATION_MS) + lcd_buzz(1000/6,100); + #else + lcd_buzz(LCD_FEEDBACK_FREQUENCY_DURATION_MS,LCD_FEEDBACK_FREQUENCY_HZ); + #endif +#elif defined(BEEPER) && BEEPER > -1 + SET_OUTPUT(BEEPER); + #if !defined(LCD_FEEDBACK_FREQUENCY_HZ) || !defined(LCD_FEEDBACK_FREQUENCY_DURATION_MS) + for(int8_t i=0;i<10;i++) + { + WRITE(BEEPER,HIGH); + delayMicroseconds(100); + WRITE(BEEPER,LOW); + delayMicroseconds(100); + } + #else + for(int8_t i=0;i<(LCD_FEEDBACK_FREQUENCY_DURATION_MS / (1000 / LCD_FEEDBACK_FREQUENCY_HZ));i++) + { + WRITE(BEEPER,HIGH); + delayMicroseconds(1000000 / LCD_FEEDBACK_FREQUENCY_HZ / 2); + WRITE(BEEPER,LOW); + delayMicroseconds(1000000 / LCD_FEEDBACK_FREQUENCY_HZ / 2); + } + #endif +#endif +} + +#ifdef LCD_HAS_STATUS_INDICATORS +static void lcd_implementation_update_indicators() +{ + #if defined(LCD_I2C_PANELOLU2) || defined(LCD_I2C_VIKI) + //set the LEDS - referred to as backlights by the LiquidTWI2 library + static uint8_t ledsprev = 0; + uint8_t leds = 0; + if (target_temperature_bed > 0) leds |= LED_A; + if (target_temperature[0] > 0) leds |= LED_B; + if (fanSpeed) leds |= LED_C; + #if EXTRUDERS > 1 + if (target_temperature[1] > 0) leds |= LED_C; + #endif + if (leds != ledsprev) { + lcd.setBacklight(leds); + ledsprev = leds; + } + #endif +} +#endif + +#ifdef LCD_HAS_SLOW_BUTTONS +extern uint32_t blocking_enc; + +static uint8_t lcd_implementation_read_slow_buttons() +{ + #ifdef LCD_I2C_TYPE_MCP23017 + uint8_t slow_buttons; + // Reading these buttons this is likely to be too slow to call inside interrupt context + // so they are called during normal lcd_update + slow_buttons = lcd.readButtons() << B_I2C_BTN_OFFSET; + #if defined(LCD_I2C_VIKI) + if(slow_buttons & (B_MI|B_RI)) { //LCD clicked + if(blocking_enc > millis()) { + slow_buttons &= ~(B_MI|B_RI); // Disable LCD clicked buttons if screen is updated + } + } + #endif + return slow_buttons; + #endif +} +#endif + +#endif//ULTRA_LCD_IMPLEMENTATION_HITACHI_HD44780_H diff --git a/Marlin/ultralcd_st7920_u8glib_rrd.h b/Marlin/ultralcd_st7920_u8glib_rrd.h index e198a858a..386e312e5 100644 --- a/Marlin/ultralcd_st7920_u8glib_rrd.h +++ b/Marlin/ultralcd_st7920_u8glib_rrd.h @@ -12,8 +12,8 @@ #define ST7920_DAT_PIN LCD_PINS_ENABLE #define ST7920_CS_PIN LCD_PINS_RS -//#define PAGE_HEIGHT 8 //128 byte frambuffer -//#define PAGE_HEIGHT 16 //256 byte frambuffer +//#define PAGE_HEIGHT 8 //128 byte framebuffer +//#define PAGE_HEIGHT 16 //256 byte framebuffer #define PAGE_HEIGHT 32 //512 byte framebuffer #define WIDTH 128 @@ -59,8 +59,8 @@ uint8_t u8g_dev_rrd_st7920_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, vo ST7920_SET_CMD(); ST7920_WRITE_BYTE(0x08); //display off, cursor+blink off ST7920_WRITE_BYTE(0x01); //clear CGRAM ram - u8g_Delay(10); //delay for cgram clear - ST7920_WRITE_BYTE(0x3E); //extended mode + gdram active + u8g_Delay(10); //delay for CGRAM clear + ST7920_WRITE_BYTE(0x3E); //extended mode + GDRAM active for(y=0;y +#include "Marlin.h" + +#ifdef ENABLE_AUTO_BED_LEVELING +#include "vector_3.h" + +vector_3::vector_3() : x(0), y(0), z(0) { } + +vector_3::vector_3(float x_, float y_, float z_) : x(x_), y(y_), z(z_) { } + +vector_3 vector_3::cross(vector_3 left, vector_3 right) +{ + return vector_3(left.y * right.z - left.z * right.y, + left.z * right.x - left.x * right.z, + left.x * right.y - left.y * right.x); +} + +vector_3 vector_3::operator+(vector_3 v) +{ + return vector_3((x + v.x), (y + v.y), (z + v.z)); +} + +vector_3 vector_3::operator-(vector_3 v) +{ + return vector_3((x - v.x), (y - v.y), (z - v.z)); +} + +vector_3 vector_3::get_normal() +{ + vector_3 normalized = vector_3(x, y, z); + normalized.normalize(); + return normalized; +} + +float vector_3::get_length() +{ + float length = sqrt((x * x) + (y * y) + (z * z)); + return length; +} + +void vector_3::normalize() +{ + float length = get_length(); + x /= length; + y /= length; + z /= length; +} + +void vector_3::apply_rotation(matrix_3x3 matrix) +{ + float resultX = x * matrix.matrix[3*0+0] + y * matrix.matrix[3*1+0] + z * matrix.matrix[3*2+0]; + float resultY = x * matrix.matrix[3*0+1] + y * matrix.matrix[3*1+1] + z * matrix.matrix[3*2+1]; + float resultZ = x * matrix.matrix[3*0+2] + y * matrix.matrix[3*1+2] + z * matrix.matrix[3*2+2]; + + x = resultX; + y = resultY; + z = resultZ; +} + +void vector_3::debug(char* title) +{ + SERIAL_PROTOCOL(title); + SERIAL_PROTOCOLPGM(" x: "); + SERIAL_PROTOCOL(x); + SERIAL_PROTOCOLPGM(" y: "); + SERIAL_PROTOCOL(y); + SERIAL_PROTOCOLPGM(" z: "); + SERIAL_PROTOCOL(z); + SERIAL_PROTOCOLPGM("\n"); +} + +void apply_rotation_xyz(matrix_3x3 matrix, float &x, float& y, float& z) +{ + vector_3 vector = vector_3(x, y, z); + vector.apply_rotation(matrix); + x = vector.x; + y = vector.y; + z = vector.z; +} + +matrix_3x3 matrix_3x3::create_from_rows(vector_3 row_0, vector_3 row_1, vector_3 row_2) +{ + //row_0.debug("row_0"); + //row_1.debug("row_1"); + //row_2.debug("row_2"); + matrix_3x3 new_matrix; + new_matrix.matrix[0] = row_0.x; new_matrix.matrix[1] = row_0.y; new_matrix.matrix[2] = row_0.z; + new_matrix.matrix[3] = row_1.x; new_matrix.matrix[4] = row_1.y; new_matrix.matrix[5] = row_1.z; + new_matrix.matrix[6] = row_2.x; new_matrix.matrix[7] = row_2.y; new_matrix.matrix[8] = row_2.z; + //new_matrix.debug("new_matrix"); + + return new_matrix; +} + +void matrix_3x3::set_to_identity() +{ + matrix[0] = 1; matrix[1] = 0; matrix[2] = 0; + matrix[3] = 0; matrix[4] = 1; matrix[5] = 0; + matrix[6] = 0; matrix[7] = 0; matrix[8] = 1; +} + +matrix_3x3 matrix_3x3::create_look_at(vector_3 target) +{ + vector_3 z_row = target.get_normal(); + vector_3 x_row = vector_3(1, 0, -target.x/target.z).get_normal(); + vector_3 y_row = vector_3(0, 1, -target.y/target.z).get_normal(); + + // x_row.debug("x_row"); + // y_row.debug("y_row"); + // z_row.debug("z_row"); + + + // create the matrix already correctly transposed + matrix_3x3 rot = matrix_3x3::create_from_rows(x_row, y_row, z_row); + + // rot.debug("rot"); + return rot; +} + + +matrix_3x3 matrix_3x3::transpose(matrix_3x3 original) +{ + matrix_3x3 new_matrix; + new_matrix.matrix[0] = original.matrix[0]; new_matrix.matrix[1] = original.matrix[3]; new_matrix.matrix[2] = original.matrix[6]; + new_matrix.matrix[3] = original.matrix[1]; new_matrix.matrix[4] = original.matrix[4]; new_matrix.matrix[5] = original.matrix[7]; + new_matrix.matrix[6] = original.matrix[2]; new_matrix.matrix[7] = original.matrix[5]; new_matrix.matrix[8] = original.matrix[8]; + return new_matrix; +} + +void matrix_3x3::debug(char* title) +{ + SERIAL_PROTOCOL(title); + SERIAL_PROTOCOL("\n"); + int count = 0; + for(int i=0; i<3; i++) + { + for(int j=0; j<3; j++) + { + SERIAL_PROTOCOL(matrix[count]); + SERIAL_PROTOCOLPGM(" "); + count++; + } + + SERIAL_PROTOCOLPGM("\n"); + } +} + +#endif // #ifdef ENABLE_AUTO_BED_LEVELING + diff --git a/Marlin/vector_3.h b/Marlin/vector_3.h new file mode 100644 index 000000000..0b9decafa --- /dev/null +++ b/Marlin/vector_3.h @@ -0,0 +1,62 @@ +/* + vector_3.cpp - Vector library for bed leveling + Copyright (c) 2012 Lars Brubaker. 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 +*/ +#ifndef VECTOR_3_H +#define VECTOR_3_H + +#ifdef ENABLE_AUTO_BED_LEVELING +class matrix_3x3; + +struct vector_3 +{ + float x, y, z; + + vector_3(); + vector_3(float x, float y, float z); + + static vector_3 cross(vector_3 a, vector_3 b); + + vector_3 operator+(vector_3 v); + vector_3 operator-(vector_3 v); + void normalize(); + float get_length(); + vector_3 get_normal(); + + void debug(char* title); + + void apply_rotation(matrix_3x3 matrix); +}; + +struct matrix_3x3 +{ + float matrix[9]; + + static matrix_3x3 create_from_rows(vector_3 row_0, vector_3 row_1, vector_3 row_2); + static matrix_3x3 create_look_at(vector_3 target); + static matrix_3x3 transpose(matrix_3x3 original); + + void set_to_identity(); + + void debug(char* title); +}; + + +void apply_rotation_xyz(matrix_3x3 rotationMatrix, float &x, float& y, float& z); +#endif // ENABLE_AUTO_BED_LEVELING + +#endif // VECTOR_3_H diff --git a/Marlin/watchdog.h b/Marlin/watchdog.h index 7f7845353..a73f3a846 100644 --- a/Marlin/watchdog.h +++ b/Marlin/watchdog.h @@ -4,9 +4,9 @@ #include "Marlin.h" #ifdef USE_WATCHDOG - // intialise watch dog with a 1 sec interrupt time + // initialize watch dog with a 1 sec interrupt time void watchdog_init(); - // pad the dog/reset watchdog. MUST be called at least every second after the first watchdog_init or avr will go into emergency procedures.. + // pad the dog/reset watchdog. MUST be called at least every second after the first watchdog_init or AVR will go into emergency procedures.. void watchdog_reset(); #else //If we do not have a watchdog, then we can have empty functions which are optimized away. diff --git a/README.md b/README.md index 014871739..17e920ec0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ ========================== Marlin 3D Printer Firmware ========================== +[![Coverity Scan Build Status](https://scan.coverity.com/projects/2224/badge.svg)](https://scan.coverity.com/projects/2224) + +Marlin has a GPL license because I believe in open development. +Please do not use this code in products (3D printers, CNC etc) that are closed source or are crippled by a patent. [![Flattr this git repo](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=ErikZalm&url=https://github.com/ErikZalm/Marlin&title=Marlin&language=&tags=github&category=software) @@ -17,6 +21,7 @@ Lampmaker, Bradley Feldman, and others... Features: +========= * Interrupt based movement with real linear acceleration * High steprate @@ -46,6 +51,7 @@ Features: * Configurable serial port to support connection of wireless adaptors. * Automatic operation of extruder/cold-end cooling fans based on nozzle temperature * RC Servo Support, specify angle or duration for continuous rotation servos. +* Bed Auto Leveling. 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. @@ -53,7 +59,8 @@ The default baudrate is 250000. This baudrate has less jitter and hence errors t Differences and additions to the already good Sprinter firmware: ================================================================ -*Look-ahead:* +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, @@ -61,23 +68,26 @@ so that the change in vectorial velocity magnitude is less than the xy_jerk_velo 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:* +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:* +Temperature Oversampling: +------------------------- To reduce noise and make the PID-differential term more useful, 16 ADC conversion results are averaged. -*AutoTemp:* +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 T F you enter the autotemp mode. +By calling M109 S B F 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]. @@ -85,36 +95,42 @@ The wanted temperature then will be set to t=tempmin+factor*maxerate, while bein 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:* +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:* +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:* +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:* +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:* +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:* +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. @@ -124,7 +140,8 @@ In the serial communication, a #define based level of abstraction was enforced, some transfer is information (usually beginning with "echo:"), an error "error:", or just normal protocol, necessary for backwards compatibility. -*Interrupt based temperature measurements:* +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. @@ -140,6 +157,8 @@ Implemented G Codes: * G10 - retract filament according to settings of M207 * G11 - retract recover filament according to settings of M208 * G28 - Home all Axis +* G29 - Detailed Z-Probe, probes the bed at 3 points. You must de at the home position for this to work correctly. +* G30 - Single Z Probe, probes bed at current XY location. * G90 - Use Absolute Coordinates * G91 - Use Relative Coordinates * G92 - Set current position to cordinates given @@ -176,6 +195,7 @@ M Codes * M107 - Fan off * M109 - Sxxx Wait for extruder current temp to reach target temp. Waits only when heating * Rxxx Wait for extruder current temp to reach target temp. Waits when heating and cooling +* M112 - Emergency stop * M114 - Output current position to serial port * M115 - Capabilities string * M117 - display message @@ -187,15 +207,15 @@ M Codes * M140 - Set bed target temp * M190 - Sxxx Wait for bed current temp to reach target temp. Waits only when heating * Rxxx Wait for bed current temp to reach target temp. Waits when heating and cooling -* M200 - Set filament diameter +* M200 D- set filament diameter and set E axis units to cubic millimeters (use S0 to set back to millimeters). * M201 - Set max acceleration in units/s^2 for print moves (M201 X1000 Y1000) * 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 * M205 - advanced settings: minimum travel speed S=while printing T=travel only, B=minimum segment time X= maximum xy jerk, Z=maximum Z jerk, E=maximum E jerk * M206 - set additional homeing offset -* M207 - set retract length S[positive mm] F[feedrate mm/sec] Z[additional zlift/hop] -* M208 - set recover=unretract length S[positive mm surplus to the M207 S*] F[feedrate mm/sec] +* M207 - set retract length S[positive mm] F[feedrate mm/min] Z[additional zlift/hop], stays in mm regardless of M200 setting +* M208 - set recover=unretract length S[positive mm surplus to the M207 S*] F[feedrate mm/min] * M209 - S<1=true/0=false> enable automatic retract detect if the slicer did not support G10/11: every normal extrude-only move will be classified as retract depending on the direction. * M218 - set hotend offset (in mm): T X Y * M220 S- set speed factor override percentage @@ -208,6 +228,8 @@ M Codes * M303 - PID relay autotune S sets the target temperature. (default target temperature = 150C) * M304 - Set bed PID parameters P I and D * M400 - Finish all moves +* M401 - Lower z-probe if present +* M402 - Raise z-probe if present * M500 - stores paramters in EEPROM * 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. @@ -228,13 +250,13 @@ 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 +Download the Marlin firmware + https://github.com/ErikZalm/Marlin/tree/Marlin_v1 + Use the "Download Zip" button on the right. + 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 \hardware\Sanguino -Copy the 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 @@ -247,6 +269,78 @@ If all goes well the firmware is uploading That's ok. Enjoy Silky Smooth Printing. +=============================================== +Instructions for configuring Bed Auto Leveling +=============================================== +Uncomment the "ENABLE_AUTO_BED_LEVELING" define (commented by default) + +You will probably need a swivel Z-MIN endstop in the extruder. A rc servo do a great job. +Check the system working here: http://www.youtube.com/watch?v=3IKMeOYz-1Q (Enable English subtitles) +Teasing ;-) video: http://www.youtube.com/watch?v=x8eqSQNAyro + +In order to get the servo working, you need to enable: + +* \#define NUM_SERVOS 1 // Servo index starts with 0 for M280 command + +* \#define SERVO_ENDSTOPS {-1, -1, 0} // Servo index for X, Y, Z. Disable with -1 + +* \#define SERVO_ENDSTOP_ANGLES {0,0, 0,0, 165,60} // X,Y,Z Axis Extend and Retract angles + + +The first define tells firmware how many servos you have. +The second tells what axis this servo will be attached to. In the example above, we have a servo in Z axis. +The third one tells the angle in 2 situations: Probing (165º) and resting (60º). Check this with command M280 P0 S{angle} (example: M280 P0 S60 moves the servo to 60º) + +For RAMPS users: +---------------- + +By default, RAMPS have no power on servo bus (if you happen to have a multimeter, check the voltage on servo power pins). +In order to get the servo working, you need to supply 5V to 5V pin.. You can do it using your power supply (if it has a 5V output) or jumping the "Vcc" from Arduino to the 5V RAMPS rail. +These 2 pins are located just between the Reset Button and the yellow fuses... There are marks in the board showing 5V and VCC.. just connect them.. +If jumping the arduino Vcc do RAMPS 5V rail, take care to not use a power hungry servo, otherwise you will cause a blackout in the arduino board ;-) + + +Next you need to define the Z endstop (probe) offset from hotend. +My preferred method: + +* a) Make a small mark in the bed with a marker/felt-tip pen. +* b) Place the hotend tip as *exactly* as possible on the mark, touching the bed. Raise the hotend 0.1mm (a regular paper thickness) and zero all axis (G92 X0 Y0 Z0); +* d) Raise the hotend 10mm (or more) for probe clearance, lower the Z probe (Z-Endstop) with M401 and place it just on that mark by moving X, Y and Z; +* e) Lower the Z in 0.1mm steps, with the probe always touching the mark (it may be necessary to adjust X and Y as well) until you hear the "click" meaning the mechanical endstop was trigged. You can confirm with M119; +* f) Now you have the probe in the same place as your hotend tip was before. Perform a M114 and write down the values, for example: X:24.3 Y:-31.4 Z:5.1; +* g) You can raise the z probe with M402 command; +* h) Fill the defines bellow multiplying the values by "-1" (just change the signal) + + +* \#define X_PROBE_OFFSET_FROM_EXTRUDER -24.3 +* \#define Y_PROBE_OFFSET_FROM_EXTRUDER 31.4 +* \#define Z_PROBE_OFFSET_FROM_EXTRUDER -5.1 + + +The following options define the probing positions. These are good starting values. +I recommend to keep a better clearance from borders in the first run and then make the probes as close as possible to borders: + +* \#define LEFT_PROBE_BED_POSITION 30 +* \#define RIGHT_PROBE_BED_POSITION 140 +* \#define BACK_PROBE_BED_POSITION 140 +* \#define FRONT_PROBE_BED_POSITION 30 + +A few more options: + +* \#define XY_TRAVEL_SPEED 6000 + +X and Y axis travel speed between probes, in mm/min. +Bear in mind that really fast moves may render step skipping. 6000 mm/min (100mm/s) is a good value. + +* \#define Z_RAISE_BEFORE_PROBING 10 +* \#define Z_RAISE_BETWEEN_PROBINGS 10 + +The Z axis is lifted when traveling to the first probe point by Z_RAISE_BEFORE_PROBING value +and then lifted when traveling from first to second and second to third point by Z_RAISE_BETWEEN_PROBINGS. +All values are in mm as usual. + +That's it.. enjoy never having to calibrate your Z endstop neither leveling your bed by hand anymore ;-) +