├── Wangsamas ├── logo.h ├── Commands.h ├── Events.h ├── Drivers.h ├── Drivers.cpp ├── gcode.h ├── Extruder.h ├── Communication.h ├── FatStructs.h ├── Wangsamas.ino ├── SDCard.cpp ├── uiconfig.h ├── Eeprom.h ├── motion.h └── HAL.h ├── BACAini.txt ├── README.txt └── SCARA calibration guide.txt /Wangsamas/logo.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // File generated by LCD Assistant 3 | // http://en.radzio.dxp.pl/bitmap_converter/ 4 | //------------------------------------------------------------------------------ 5 | 6 | #ifndef CUSTOM_LOGO 7 | #define LOGO_WIDTH 60 8 | #define LOGO_HEIGHT 64 9 | 10 | const unsigned char logo[] PROGMEM = { //AVR-GCC, WinAVR 11 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124, 0, 15, 128, 3, 192, 0, 1, 255, 0, 31, 192, 7, 240, 0, 1, 255, 128, 63, 224, 15, 248, 0, 3, 255, 128, 127, 240, 31, 252, 0, 7, 255, 192, 255, 248, 63, 252, 0, 7, 255, 193, 255, 248, 127, 254, 0, 7, 255, 195, 255, 248, 255, 254, 0, 7, 255, 199, 255, 249, 255, 252, 0, 7, 255, 207, 255, 243, 255, 252, 0, 3, 255, 223, 255, 247, 255, 248, 0, 3, 255, 191, 255, 239, 255, 248, 0, 1, 255, 127, 255, 223, 255, 240, 0, 0, 254, 255, 255, 191, 255, 224, 0, 0, 1, 255, 255, 127, 255, 192, 0, 0, 3, 255, 254, 255, 255, 128, 0, 0, 7, 255, 253, 255, 255, 0, 0, 0, 15, 255, 251, 255, 254, 0, 0, 0, 31, 255, 247, 255, 252, 0, 0, 0, 31, 255, 231, 255, 248, 0, 0, 0, 31, 255, 207, 255, 240, 0, 0, 0, 31, 255, 143, 255, 224, 0, 0, 0, 31, 255, 7, 255, 192, 0, 0, 0, 31, 254, 7, 255, 128, 0, 0, 0, 15, 252, 195, 255, 48, 0, 0, 0, 7, 251, 249, 254, 252, 0, 0, 0, 1, 247, 252, 249, 254, 0, 0, 0, 0, 15, 252, 3, 255, 0, 0, 0, 0, 31, 254, 7, 255, 128, 0, 0, 0, 63, 254, 15, 255, 128, 0, 0, 0, 127, 255, 31, 255, 128, 0, 0, 0, 255, 255, 63, 255, 128, 0, 0, 1, 255, 254, 127, 255, 128, 0, 0, 3, 255, 254, 255, 255, 128, 0, 0, 7, 255, 253, 255, 255, 0, 0, 0, 15, 255, 251, 255, 254, 0, 0, 0, 31, 255, 247, 255, 252, 0, 0, 0, 63, 255, 239, 255, 251, 224, 0, 0, 127, 255, 223, 255, 247, 240, 0, 0, 255, 255, 191, 255, 239, 248, 0, 1, 255, 255, 127, 255, 223, 252, 0, 3, 255, 254, 255, 255, 191, 254, 0, 3, 255, 252, 255, 255, 63, 254, 0, 7, 255, 249, 255, 254, 63, 254, 0, 7, 255, 241, 255, 252, 63, 254, 0, 3, 255, 225, 255, 248, 63, 254, 0, 3, 255, 192, 255, 240, 63, 252, 0, 1, 255, 128, 255, 224, 31, 252, 0, 0, 255, 0, 127, 192, 15, 248, 0, 0, 126, 0, 63, 128, 7, 240, 0, 0, 60, 0, 15, 0, 3, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 72, 72, 227, 136, 68, 67, 128, 38, 140, 73, 20, 76, 68, 100, 64, 22, 148, 106, 3, 20, 108, 163, 0, 26, 158, 90, 48, 222, 108, 240, 192, 25, 162, 89, 20, 98, 117, 20, 64, 9, 34, 73, 243, 226, 85, 19, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 12 | }; 13 | #else 14 | LOGO_BITMAP 15 | #endif 16 | -------------------------------------------------------------------------------- /Wangsamas/Commands.h: -------------------------------------------------------------------------------- 1 | /* 2 | Berkas ini adalah bagian dari Wangsamas-Firmware oleh Kusuma Ruslan. 3 | 4 | Wangsamas-Firmware adalah perangkat lunak bebas: 5 | Anda dapat mendistribusikannya dan/atau mengubahnya 6 | dengan syarat dan ketentuan GNU General Public License 7 | yang dipublikasikan oleh Free Software Foundation, 8 | baik ijin versi 3, atau (menurut pilihanmu) versi yang terbaru. 9 | 10 | Wangsamas-Firmware didistribusikan dengan harapan agar dapat bermanfaat, 11 | tetapi TANPA JAMINAN; bahkan tanpa jaminan tersirat PERDAGANGAN atau 12 | KECOCOKAN UNTUK TUJUAN TERTENTU. Lihat GNU General Public License 13 | untuk keterangan lebih lanjut. 14 | 15 | Anda seharusnya sudah menerima salinan GNU General Public License bersamaan 16 | dengan Wangsamas-Firmware. Jika tidak, lihat . 17 | 18 | Firmware ini berdasarkan Repetier-Firmware yang berdasarkan Sprinter firmware 19 | yang berdasarkan Tonokip Reprap firmware yang berdasarkan Hydra-mmm firmware. 20 | 21 | --------------------- 22 | 23 | This file is part of Wangsamas-Firmware by Kusuma Ruslan. 24 | 25 | Wangsamas-Firmware is free software: you can redistribute it and/or modify 26 | it under the terms of the GNU General Public License as published by 27 | the Free Software Foundation, either version 3 of the License, or 28 | (at your option) any later version. 29 | 30 | Wangsamas-Firmware is distributed in the hope that it will be useful, 31 | but WITHOUT ANY WARRANTY; without even the implied warranty of 32 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 33 | GNU General Public License for more details. 34 | 35 | You should have received a copy of the GNU General Public License 36 | along with Wangsamas-Firmware. If not, see . 37 | 38 | This firmware is based on Repetier-Firmware which based on sprinter firmware 39 | which based on Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware. 40 | 41 | Functions in this file are used to communicate using ascii or repetier protocol. 42 | */ 43 | 44 | #ifndef COMMANDS_H_INCLUDED 45 | #define COMMANDS_H_INCLUDED 46 | 47 | class Commands 48 | { 49 | public: 50 | static void commandLoop(); 51 | static void checkForPeriodicalActions(bool allowNewMoves); 52 | static void processArc(GCode *com); 53 | static void processGCode(GCode *com); 54 | static void processMCode(GCode *com); 55 | static void executeGCode(GCode *com); 56 | static void waitUntilEndOfAllMoves(); 57 | static void waitUntilEndOfAllBuffers(); 58 | static void printCurrentPosition(FSTRINGPARAM(s)); 59 | static void printTemperatures(bool showRaw = false); 60 | static void setFanSpeed(int speed, bool immediately = false); /// Set fan speed 0..255 61 | static void setFan2Speed(int speed); /// Set fan speed 0..255 62 | static void changeFeedrateMultiply(int factorInPercent); 63 | static void changeFlowrateMultiply(int factorInPercent); 64 | static void reportPrinterUsage(); 65 | static void emergencyStop(); 66 | static void checkFreeMemory(); 67 | static void writeLowestFreeRAM(); 68 | private: 69 | static int lowestRAMValue; 70 | static int lowestRAMValueSend; 71 | }; 72 | 73 | #endif // COMMANDS_H_INCLUDED 74 | -------------------------------------------------------------------------------- /BACAini.txt: -------------------------------------------------------------------------------- 1 | Petunjuk penggunaan: 2 | 3 | 1. Install Arduino IDE 4 | Dapatkan Arduino IDE terbaru di sini: 5 | http://arduino.cc/en/Main/Software 6 | Anda butuh setidaknya 1.0 untuk PCB berbasis Atmel AVR dan 1.5 untuk PCB berbasis ARM. 7 | 2. Pastikan semua serial driver terpasang pada PCB. Arduino IDE mengandung penanda driver untuk PCB Arduino. 8 | Mungkin Anda butuh driver yang berbeda tergantung PCB Anda. Untuk Linux dan Mac terkadang tidak perlu tambahan driver. 9 | Jika belum jelas, tanya pemasok printer/PCB Anda driver mana yang Anda butuhkan. 10 | 3. Beberapa PCB bukan PCB Arduino asli tidak 100% cocok, butuh tambahan terpisah ke Arduino IDE. Install juga 11 | 4. Mulai Arduino IDE dan buka berkas "Wangsamas.ino" 12 | 5. Pilih PCB dan port untuk upload di Arduino IDE. 13 | 6. Buka Configuration.h, baca petunjuk apakah ada yang perlu diperiksa atau dimodifikasi agar cocok dengan printer anda 14 | 7. Upload Wangsamas Firmware dengan tombol upload (Panah ke kanan di toolbar) 15 | 16 | Jika Anda menggunakan PCB mega 2560 yang normal atau cocok, Anda bisa gunakan codeblocks untuk Arduino selain Arduino IDE: 17 | http://arduinodev.com/codeblocks/ 18 | Buka berkas Wangsamas.cbp dan mulai dengan nomor 6. 19 | 20 | MOTHERBOARD LIST 21 | 3D Master pin assignment = 12 22 | Arduino Diecimila AVR_ATmega168 = 0 23 | Arduino Mega RAMPS_V_1_3 = 33 24 | Arduino Mega RAMPS_V_1_3 AZTEEG_X3 = 34 25 | Arduino Mega RAMPS_V_1_3 AZTEEG_X3_PRO =35 26 | Duemilanove w/ ATMega328P pin assignment = 4 27 | FELIXprinters = 101 28 | Gen3 PLUS for RepRap Motherboard V1.2 AVR_ATmega644P = 3 29 | Gen6 deluxe assignment = 51 30 | Gen6 pin assignment = 5 31 | Gen7 1.1 and above pin assignment 7 32 | Gen7 1.4.1 pin assignment 71 33 | MegaTronics = 70 34 | MegaTronics v2.0 = 701 35 | MegaTronics v3.0 = 703 36 | Melzi pin assignment = 63 37 | Minitronics v1.0 = 702 38 | NOOOOOO RS485/EXTRUDER CONTROLLER AVR_ATmega644P = 2 39 | OpenHardware.co.za FrontPrint Controller 1.0 = 73 40 | PiBot = 314 41 | PiBot_V_1_6, PiBot_HD_VERSION "Rev1.6" = 315 42 | PiBot_V_2_0, PiBot_HD_VERSION "Rev2.0" = 316 43 | Printrboard Rev. B pin assingments (ATMEGA90USB1286) = 9 44 | Printrboard Rev. F pin assingments (ATMEGA90USB1286) = 92 45 | RAMBo Pin Assignments = 301 46 | RUMBA pin assignment = 80 47 | Sanguino/RepRap Motherboard with direct-drive extruders AVR_ATmega644P = 1 48 | Sanguinololu pin assignment = 6 49 | SANGUINOLOLU_V_1_2 = 62 50 | SANGUINOLOLU_V_1_2 AZTEEG_X1 = 65 51 | Sanguish Beta pin assignment = 501 52 | Sethi 3D_1 Extruder = 72 53 | Teensylu 0.7 pin assingments (ATMEGA90USB) = 8 54 | Ultimaker Shield pin assignment v1.5.7 = 37 55 | Unique One rev. A pin assingments (ATMEGA90USB) = 88 56 | 57 | PETUNJUK: Jika Anda menyalakan EEPROM, upload pertama akan menyalin data dari configuration.h ke EEPROM. 58 | Upload berikutnya TIDAK akan menimpa data EEPROM. 59 | Untuk mengubah nilai, hubungkan printer menggunakan repetier host dan buka pengubah EEPROM. 60 | Jalan lain adalah dengan mengirim perintah M502 M500 untuk menyalin nilai baru ke EEPROM. 61 | 62 | PENTING UNTUK BEBERAPA PENGGUNA 63 | Ada tambahan berkas AdditionalArduinoFiles dengan readme yang terpisah yang menjelaskan bagaimana agar watchdog bekerja. 64 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | Compilation instructions 2 | 3 | 4 | 1. Install Arduino IDE 5 | 6 | You get the latest Arduino IDE here: 7 | 8 | http://arduino.cc/en/Main/Software 9 | 10 | 11 | You need at least 1.0 for the Atmel AVR based boards and 1.5 for the ARM based boards like the due. 12 | 13 | 14 | 2. Make sure the serial driver for your printer board is installed. The Arduino IDE contains signed drivers 15 | 16 | for the Arduino boards. Depending on your board you might need different drivers then these. For Linux and Mac 17 | 18 | you often do not need any additional drivers. Ask your printer/board vendor which driver you need, 19 | 20 | if that is not clear to you. 21 | 22 | 23 | 3. Some boards that are not original arduino boards and not 100% compatible to them, need separate extensions 24 | 25 | to the Arduino IDE. Install them. 26 | 27 | 28 | 4. Start Arduino IDE and open the file "Wangsamas.ino" 29 | 30 | 31 | 5. Select the board and port for upload in the arduino ide. 32 | 33 | 34 | 6. Check Configuration.h for hints, if something needs to be checked or modified. 35 | 36 | 37 | 7. Upload the firmware with the upload button (right arrow in toolbar). 38 | 39 | 40 | If you have a normal mega 2560 compatible board, you can use codeblocks for arduino instead of the arduino ide: 41 | 42 | http://arduinodev.com/codeblocks/ 43 | Open the Wangsamas.cbp file instead of the ino file and start with 6. 44 | 45 | 46 | 47 | MOTHERBOARD LIST 48 | 49 | 3D Master pin assignment = 12 50 | 51 | Arduino Diecimila AVR_ATmega168 = 0 52 | 53 | Arduino Mega RAMPS_V_1_3 = 33 54 | 55 | Arduino Mega RAMPS_V_1_3 AZTEEG_X3 = 34 56 | 57 | Arduino Mega RAMPS_V_1_3 AZTEEG_X3_PRO =35 58 | 59 | Duemilanove w/ ATMega328P pin assignment = 4 60 | 61 | FELIXprinters = 101 62 | 63 | Gen3 PLUS for RepRap Motherboard V1.2 AVR_ATmega644P = 3 64 | 65 | Gen6 deluxe assignment = 51 66 | 67 | Gen6 pin assignment = 5 68 | 69 | Gen7 1.1 and above pin assignment 7 70 | 71 | Gen7 1.4.1 pin assignment 71 72 | MegaTronics = 70 73 | 74 | MegaTronics v2.0 = 701 75 | 76 | MegaTronics v3.0 = 703 77 | 78 | Melzi pin assignment = 63 79 | 80 | Minitronics v1.0 = 702 81 | 82 | NOOOOOO RS485/EXTRUDER CONTROLLER AVR_ATmega644P = 2 83 | O 84 | penHardware.co.za FrontPrint Controller 1.0 = 73 85 | 86 | PiBot = 314 87 | 88 | PiBot_V_1_6, PiBot_HD_VERSION "Rev1.6" = 315 89 | 90 | PiBot_V_2_0, PiBot_HD_VERSION "Rev2.0" = 316 91 | 92 | Printrboard Rev. B pin assingments (ATMEGA90USB1286) = 9 93 | P 94 | rintrboard Rev. F pin assingments (ATMEGA90USB1286) = 92 95 | 96 | RAMBo Pin Assignments = 301 97 | 98 | RUMBA pin assignment = 80 99 | 100 | Sanguino/RepRap Motherboard with direct-drive extruders AVR_ATmega644P = 1 101 | 102 | Sanguinololu pin assignment = 6 103 | 104 | SANGUINOLOLU_V_1_2 = 62 105 | 106 | SANGUINOLOLU_V_1_2 AZTEEG_X1 = 65 107 | 108 | Sanguish Beta pin assignment = 501 109 | 110 | Sethi 3D_1 Extruder = 72 111 | 112 | Teensylu 0.7 pin assingments (ATMEGA90USB) = 8 113 | 114 | Ultimaker Shield pin assignment v1.5.7 = 37 115 | 116 | Unique One rev. A pin assingments (ATMEGA90USB) = 88 117 | 118 | 119 | 120 | 121 | HINT: It you have enabled eeprom support, the first upload will copy the configurations into the eeprom. 122 | Later 123 | uploads will NOT overwrite these settings! Connect with Repetier-Host to your printer and open the eeprom editor 124 | to change these values. 125 | Alternatively, send the commands 126 | M502 127 | M500 128 | to copy the new values in Configuration.h to eeprom. 129 | 130 | 131 | 132 | IMPORTANT FOR DUE USERS 133 | 134 | There is an additional folder AdditionalArduinoFiles with separate readme that describes how to get 135 | watchdog working. 136 | It is a very good idea to compile with working watchdog!!! 137 | -------------------------------------------------------------------------------- /Wangsamas/Events.h: -------------------------------------------------------------------------------- 1 | #ifndef EVENTS_H_INCLUDED 2 | #define EVENTS_H_INCLUDED 3 | 4 | /* 5 | Event system in a nutshell: 6 | 7 | All printers are different and my need additions in th eone or other place. 8 | It is not very convenient to add these code parts across the firmware. For this 9 | reason Wangsamas-firmware uses a simple event system that comes at no cost if 10 | a event is not used. 11 | 12 | - simple: Only one subscriber is possible 13 | - cost effective: Macros work as event caller. By default all macros are empty 14 | 15 | How to use the system: 16 | 17 | 1. In Configuration.h add 18 | #define CUSTOM_EVENTS 19 | 2. Add a file "CustomEvents.h" which overrides all event macros you need. 20 | It shoudl also include the function declarations used. 21 | 3. Add a file "CustomEventsImpl.h" which includes all function definitions. 22 | Also it is named .h it will be included inside a cpp file only once. 23 | This is to compile only when selected and still keep ArduinoIDE happy. 24 | 25 | Each of the following events describe the parameter and when it is called. 26 | */ 27 | 28 | // Catch heating events. id is extruder id or -1 for heated bed. 29 | #define EVENT_WAITING_HEATER(id) {} 30 | #define EVENT_HEATING_FINISHED(id) {} 31 | 32 | // This gets called every 0.1 second 33 | #define EVENT_TIMER_100MS {} 34 | // This gets called every 0.5 second 35 | #define EVENT_TIMER_500MS {} 36 | // Gets called on a regular basis as time allows 37 | #define EVENT_PERIODICAL {} 38 | // Gets called when kill gets called. only_steppes = true -> we only want to disable steppers, not everything. 39 | #define EVENT_KILL(only_steppers) {} 40 | // Gets called when a jam was detected. 41 | #define EVENT_JAM_DETECTED {} 42 | // Gets called every time the jam detection signal switches. Steps are the extruder steps since last change. 43 | #define EVENT_JAM_SIGNAL_CHANGED(extruderId,steps) {} 44 | // Gets called if a heater decoupling is detected. 45 | #define EVENT_HEATER_DECOUPLED(id) {} 46 | // Gets called if a missing/shorted thermistor is detected. 47 | #define EVENT_HEATER_DEFECT(id) {} 48 | // Gets called if a action in ui.cpp okAction gets executed. 49 | #define EVENT_START_UI_ACTION(shortAction) {} 50 | // Gets called if a nextPrevius actions gets executed. 51 | #define EVENT_START_NEXTPREVIOUS(action,increment) {} 52 | // Gets called before a move is queued. Gives the ability to limit moves. 53 | #define EVENT_CONTRAIN_DESTINATION_COORDINATES 54 | // Gets called when a fatal error occurs and all actions should be stopped 55 | #define EVENT_FATAL_ERROR_OCCURED 56 | // Gets called after a M999 to continue from fatal errors 57 | #define EVENT_CONTINUE_FROM_FATAL_ERROR 58 | 59 | // Called to initialize laser pins. Return false to prevent default initialization. 60 | #define EVENT_INITALIZE_LASER true 61 | // Set laser to intensity level 0 = off, 255 = full. Return false if you have overridden the setting routine. 62 | // with true the default solution will set it as digital value. 63 | #define EVENT_SET_LASER(intensity) true 64 | 65 | // Called to initialize CNC pins. Return false to prevent default initialization. 66 | #define EVENT_INITALIZE_CNC true 67 | // Turn off spindle 68 | #define EVENT_SPINDLE_OFF true 69 | // Turn spindle clockwise 70 | #define EVENT_SPINDLE_CW(rpm) true 71 | // Turn spindle counter clockwise 72 | #define EVENT_SPINDLE_CCW(rpm) true 73 | 74 | // Allow adding new G and M codes. To implement it create a function 75 | // bool eventUnhandledGCode(GCode *com) 76 | // that returns true if it handled the code, otherwise false. 77 | // Event define would then be 78 | // #define EVENT_UNHANDLED_G_CODE(c) eventUnhandledGCode(c) 79 | #define EVENT_UNHANDLED_G_CODE(c) false 80 | #define EVENT_UNHANDLED_M_CODE(c) false 81 | 82 | // This gets called every time the user has saved a value to eeprom 83 | // or any other reason why dependent values may need recomputation. 84 | #define EVENT_UPDATE_DERIVED {} 85 | 86 | // This gets called after the basic firmware functions have initialized. 87 | // Use this to initalize your hardware etc. 88 | #define EVENT_INITIALIZE {} 89 | 90 | #endif // EVENTS_H_INCLUDED 91 | -------------------------------------------------------------------------------- /SCARA calibration guide.txt: -------------------------------------------------------------------------------- 1 | /* SCARA CALIBRATION 2 | 3 | SINGLE SCARA 4 | 1. Calibrate forearm length & steps per unit using 3 points marked on a paper (Make sure your paper stick to bed & mark exactly from you nozzle) 5 | a. Home using G28 command 6 | b. Rotate forearm to the maximum angle as possible on bed use G5 Y___ command. Mark on paper point A and enter G50 P1 command 7 | c. Rotate forearm to approximately on bed center use G5 Y___ command. Mark on paper point B and enter G50 P2 command 8 | d. Rotate forearm to the minimum angle as possible on bed use G5 Y___ command. Mark on paper point C and enter G50 P3 command 9 | e. Measure distance point A to B (X), point B to C (Y), point A to C (Z) 10 | f. Enter G50 X___ Y___ Z___ S1 command. 11 | g. Read the calculated forearm length and steps per unit. if it doesn't make sense, repeat the steps. if it make sense enter G50 S11 command to save. 12 | h. Repeat step 1b & 1c, measure distance point A to B. Enter G50 P5 command, check if the value and measured distance are the same. 13 | i. If you cannot tolerate with the difference, repeat the calibration or you can manually edit from EEPROM. (suggestion 0.0x tolerance) 14 | 2. Calibrate arm steps per unit using 6 points marked on a paper 15 | a. Home using G28 command 16 | b. Rotate arm to the maximum angle as possible on bed use G5 X___ command. Mark on paper point A and enter G50 P1 command 17 | c. Rotate arm to approximately on bed center use G5 X___ command. Mark on paper point B and enter G50 P2 command 18 | d. Rotate arm to the minimum angle as possible on bed use G5 X___ command. Mark on paper point C and enter G50 P3 command 19 | e. Measure distance point A to B (X), point B to C (Y), point A to C (Z) 20 | f. Enter G50 X___ Y___ Z___ S21 command. 21 | g. Rotate forearm away from arm use G5 Y___ command to get another 3 points different from the first 3. 22 | h. Rotate arm to the maximum angle as possible on bed use G5 X___ command. Mark on paper point A and enter G50 P1 command 23 | i. Rotate arm to approximately on bed center use G5 X___ command. Mark on paper point B and enter G50 P2 command 24 | j. Rotate arm to the minimum angle as possible on bed use G5 X___ command. Mark on paper point C and enter G50 P3 command 25 | k. Measure distance point A to B (X), point B to C (Y), point A to C (Z) 26 | l. Enter G50 X___ Y___ Z___ S22 command. 27 | m. Compare steps per unit result from step 2f and 2l. It suppose to be the same. Repeat the steps if you are not satisfy. 28 | 3. Calibrate arm length and elbow angle. 29 | a. Enter G50 S23, you will get 2 options for your arm length and elbow angle. choose the one you think right. 30 | b. Enter G50 S231 if you choose the 1st option, enter G232 if you choose the 2nd option to save you calibration. 31 | c. If you did it all right, your calibration is done. 32 | 33 | PARALEL SCARA 34 | 1. Calibrate forearm length & steps per unit using 3 points marked on a paper (Make sure your paper stick to bed & mark exactly from you nozzle) 35 | a. Home using G28 command 36 | b. Rotate forearm to the maximum angle as possible on bed use G5 Y___ command. Mark on paper point A and enter G50 P1 command 37 | c. Rotate forearm to approximately on bed center use G5 Y___ command. Mark on paper point B and enter G50 P2 command 38 | d. Rotate forearm to the minimum angle as possible on bed use G5 Y___ command. Mark on paper point C and enter G50 P3 command 39 | e. Measure distance point A to B (X), point B to C (Y), point A to C (Z) 40 | f. Enter G50 X___ Y___ Z___ S1 command. 41 | g. Read the calculated forearm length and steps per unit. if it doesn't make sense, repeat the steps. if it make sense enter G50 S11 command to save. 42 | h. Repeat step 1b & 1c, measure distance point A to B. Enter G50 P5 command, check if the value and measured distance are the same. 43 | i. If you cannot tolerate with the difference, repeat the calibration or you can manually edit from EEPROM. (suggestion 0.0x tolerance) 44 | 2. Calibrate forearm length & steps per unit using 3 points marked on a paper 45 | a. Home using G28 command 46 | b. Rotate arm to the maximum angle as possible on bed use G5 X___ command. Mark on paper point A and enter G50 P1 command 47 | c. Rotate arm to approximately on bed center use G5 X___ command. Mark on paper point B and enter G50 P2 command 48 | d. Rotate arm to the minimum angle as possible on bed use G5 X___ command. Mark on paper point C and enter G50 P3 command 49 | e. Measure distance point A to B (X), point B to C (Y), point A to C (Z) 50 | f. Enter G50 X___ Y___ Z___ S2 command. 51 | g. Read the calculated forearm length and steps per unit. if it doesn't make sense, repeat the steps. if it make sense enter G50 S21 command to save. 52 | h. Repeat step 2b & 2c, measure distance point A to B. Enter G50 P5 command, check if the value and measured distance are the same. 53 | i. If you cannot tolerate with the difference, repeat the calibration or you can manually edit from EEPROM. (suggestion 0.0x tolerance) 54 | 3. Calibrate angles 55 | a. Home using G28 command 56 | b. Move to approximatelly at bed center use G1 X___ Y___ command. Mark on paper point A and enter G50 P1 command 57 | c. Move to somewhere else on bed use G1 X___ Y___ command. Mark on paper point B and enter G50 P2 command 58 | d. Measure distance point A to B (X) 59 | e. Enter G50 X___ S3 command. 60 | f. Repeat step 3b & 3c, measure distance point A to B. Enter G50 P5 command, check if the value and measured distance are the same. 61 | g. If they are the same, your calibration is done. 62 | */ -------------------------------------------------------------------------------- /Wangsamas/Drivers.h: -------------------------------------------------------------------------------- 1 | #ifndef DRIVERS_H_INCLUDED 2 | #define DRIVERS_H_INCLUDED 3 | 4 | /** 5 | For some special printers you need to control extra motors. Possible reasons are 6 | - Extruder switches 7 | - Clearing surface 8 | - Leveling 9 | 10 | Wangsamas-Firmware supports up to 4 extra motors that can be controlled by 11 | G201 P X - Go to position X with motor X 12 | G202 P X - Mark current position as X 13 | G203 P - Report current motor position 14 | G204 P S<0/1> - Enable/disable motor 15 | 16 | These motors are already special and there might be different types, so we can not assume 17 | one class fits all needs. So to keep it simple, the firmware defines this general 18 | interface whcih a motor must implement. That way we can handle any type without changing 19 | the main code. 20 | */ 21 | class MotorDriverInterface 22 | { 23 | public: 24 | virtual void initialize() = 0; 25 | virtual float getPosition() = 0; 26 | virtual void setCurrentAs(float newPos) = 0; 27 | virtual void gotoPosition(float newPos) = 0; 28 | virtual void enable() = 0; 29 | virtual void disable() = 0; 30 | }; 31 | 32 | /** 33 | Simple class to drive a stepper motor with fixed speed. 34 | */ 35 | template 36 | class StepperDriver : public MotorDriverInterface 37 | { 38 | int32_t position; 39 | int32_t delayUS; 40 | float StepsPerUnit; 41 | public: 42 | StepperDriver(float _StepsPerUnit,float speed) 43 | { 44 | StepsPerUnit = _StepsPerUnit; 45 | delayUS = 500000 / (speed * StepsPerUnit); 46 | } 47 | void initialize() { 48 | HAL::pinMode(enablePin, OUTPUT); 49 | HAL::pinMode(stepPin, OUTPUT); 50 | HAL::pinMode(dirPin, OUTPUT); 51 | HAL::digitalWrite(enablePin, !invertEnable); 52 | } 53 | float getPosition() 54 | { 55 | return position / StepsPerUnit; 56 | } 57 | void setCurrentAs(float newPos) 58 | { 59 | position = floor(newPos * StepsPerUnit + 0.5f); 60 | } 61 | void gotoPosition(float newPos) 62 | { 63 | enable(); 64 | int32_t target = floor(newPos * StepsPerUnit + 0.5f) - position; 65 | position += target; 66 | if(target > 0) { 67 | HAL::digitalWrite(dirPin, !invertDir); 68 | } else { 69 | target = -target; 70 | HAL::digitalWrite(dirPin, invertDir); 71 | } 72 | while(target) { 73 | HAL::digitalWrite(stepPin, HIGH); 74 | HAL::delayMicroseconds(delayUS); 75 | HAL::digitalWrite(stepPin, LOW); 76 | HAL::delayMicroseconds(delayUS); 77 | target--; 78 | HAL::pingWatchdog(); 79 | if((target & 127) == 0) 80 | Commands::checkForPeriodicalActions(false); 81 | } 82 | } 83 | void enable() 84 | { 85 | HAL::digitalWrite(enablePin, invertEnable); 86 | } 87 | void disable() 88 | { 89 | HAL::digitalWrite(enablePin, !invertEnable); 90 | } 91 | }; 92 | 93 | #if defined(NUM_MOTOR_DRIVERS) && NUM_MOTOR_DRIVERS > 0 94 | class GCode; 95 | extern void commandG201(GCode &code); 96 | extern void commandG202(GCode &code); 97 | extern void commandG203(GCode &code); 98 | extern void commandG204(GCode &code); 99 | extern void disableAllMotorDrivers(); 100 | extern MotorDriverInterface *getMotorDriver(int idx); 101 | extern void initializeAllMotorDrivers(); 102 | #endif 103 | 104 | 105 | #if defined(SUPPORT_LASER) && SUPPORT_LASER 106 | /** 107 | With laser support you can exchange a extruder by a laser. A laser gets controlled by a digital pin. 108 | By default all intensities > 200 are always on, and lower values are always off. You can overwrite 109 | this with a programmed event EVENT_SET_LASER(intensity) that return false to signal the default 110 | implementation that it has set it's value already. 111 | EVENT_INITALIZE_LASER should return false to prevent default initialization. 112 | */ 113 | class LaserDriver { 114 | public: 115 | static uint8_t intensity; // Intensity to use for next move queued. This is NOT the current value! 116 | static bool laserOn; // Enabled by M3? 117 | static void initialize(); 118 | static void changeIntensity(uint8_t newIntensity); 119 | }; 120 | #endif 121 | 122 | #if defined(SUPPORT_CNC) && SUPPORT_CNC 123 | /** 124 | The CNC driver differs a bit from laser driver. Here only M3,M4,M5 have an influence on the spindle. 125 | The motor also keeps running for G0 moves. M3 and M4 wait for old moves to be finished and then enables 126 | the motor. It then waits CNC_WAIT_ON_ENABLE milliseconds for the spindle to reach target speed. 127 | */ 128 | class CNCDriver { 129 | public: 130 | static int8_t direction; 131 | /** Initialize cnc pins. EVENT_INITALIZE_CNC should return false to prevent default initalization.*/ 132 | static void initialize(); 133 | /** Turns off spindle. For event override implement 134 | EVENT_SPINDLE_OFF 135 | returning false. 136 | */ 137 | static void spindleOff(); 138 | /** Turns spindle on. Default implementation uses a enable pin CNC_ENABLE_PIN. If 139 | CNC_DIRECTION_PIN is not -1 it sets direction to CNC_DIRECTION_CW. rpm is ignored. 140 | To override with event system, return false for the event 141 | EVENT_SPINDLE_CW(rpm) 142 | */ 143 | static void spindleOnCW(int32_t rpm); 144 | /** Turns spindle on. Default implementation uses a enable pin CNC_ENABLE_PIN. If 145 | CNC_DIRECTION_PIN is not -1 it sets direction to !CNC_DIRECTION_CW. rpm is ignored. 146 | To override with event system, return false for the event 147 | EVENT_SPINDLE_CCW(rpm) 148 | */ 149 | static void spindleOnCCW(int32_t rpm); 150 | }; 151 | #endif 152 | 153 | #endif // DRIVERS_H_INCLUDED 154 | -------------------------------------------------------------------------------- /Wangsamas/Drivers.cpp: -------------------------------------------------------------------------------- 1 | #include "Wangsamas.h" 2 | 3 | #if defined(NUM_MOTOR_DRIVERS) && NUM_MOTOR_DRIVERS > 0 4 | MOTOR_DRIVER_1(motorDriver1); 5 | #if NUM_MOTOR_DRIVERS > 1 6 | MOTOR_DRIVER_2(motorDriver2); 7 | #endif 8 | #if NUM_MOTOR_DRIVERS > 2 9 | MOTOR_DRIVER_3(motorDriver3); 10 | #endif 11 | #if NUM_MOTOR_DRIVERS > 3 12 | MOTOR_DRIVER_4(motorDriver4); 13 | #endif 14 | #if NUM_MOTOR_DRIVERS > 4 15 | MOTOR_DRIVER_5(motorDriver5); 16 | #endif 17 | #if NUM_MOTOR_DRIVERS > 5 18 | MOTOR_DRIVER_6(motorDriver6); 19 | #endif 20 | 21 | MotorDriverInterface *motorDrivers[NUM_MOTOR_DRIVERS] = 22 | { 23 | &motorDriver1 24 | #if NUM_MOTOR_DRIVERS > 1 25 | , &motorDriver2 26 | #endif 27 | #if NUM_MOTOR_DRIVERS > 2 28 | , &motorDriver3 29 | #endif 30 | #if NUM_MOTOR_DRIVERS > 3 31 | , &motorDriver4 32 | #endif 33 | #if NUM_MOTOR_DRIVERS > 4 34 | , &motorDriver5 35 | #endif 36 | #if NUM_MOTOR_DRIVERS > 5 37 | , &motorDriver6 38 | #endif 39 | }; 40 | 41 | MotorDriverInterface *getMotorDriver(int idx) 42 | { 43 | return motorDrivers[idx]; 44 | } 45 | 46 | /** 47 | Run motor P until it is at position X 48 | */ 49 | void commandG201(GCode &code) 50 | { 51 | int id = 0; 52 | if(code.hasP()) 53 | id = code.P; 54 | if(id < 0) id = 0; 55 | if(id >= NUM_MOTOR_DRIVERS) id = 0; 56 | if(!code.hasX()) return; 57 | motorDrivers[id]->gotoPosition(code.X); 58 | } 59 | 60 | //G202 P X - Mark current position as X 61 | void commandG202(GCode &code) 62 | { 63 | int id = 0; 64 | if(code.hasP()) 65 | id = code.P; 66 | if(id < 0) id = 0; 67 | if(id >= NUM_MOTOR_DRIVERS) id = 0; 68 | if(!code.hasX()) return; 69 | motorDrivers[id]->setCurrentAs(code.X); 70 | } 71 | //G203 P - Report current motor position 72 | void commandG203(GCode &code) 73 | { 74 | int id = 0; 75 | if(code.hasP()) 76 | id = code.P; 77 | if(id < 0) id = 0; 78 | if(id >= NUM_MOTOR_DRIVERS) id = 0; 79 | Com::printF(PSTR("Motor"),id); 80 | Com::printFLN(PSTR("Pos:"),motorDrivers[id]->getPosition()); 81 | } 82 | //G204 P S<0/1> - Enable/disable motor 83 | void commandG204(GCode &code) 84 | { 85 | int id = 0; 86 | if(code.hasP()) 87 | id = code.P; 88 | if(id < 0) id = 0; 89 | if(id >= NUM_MOTOR_DRIVERS) id = 0; 90 | if(!code.hasS()) return; 91 | if(code.S) 92 | motorDrivers[id]->enable(); 93 | else 94 | motorDrivers[id]->disable(); 95 | } 96 | 97 | void disableAllMotorDrivers() 98 | { 99 | for(int i = 0; i < NUM_MOTOR_DRIVERS; i++) 100 | motorDrivers[i]->disable(); 101 | } 102 | void initializeAllMotorDrivers() 103 | { 104 | for(int i = 0; i < NUM_MOTOR_DRIVERS; i++) 105 | motorDrivers[i]->initialize(); 106 | } 107 | 108 | #endif // NUM_MOTOR_DRIVERS 109 | 110 | #if defined(SUPPORT_LASER) && SUPPORT_LASER 111 | uint8_t LaserDriver::intensity = 255; // Intensity to use for next move queued if we want lasers. This is NOT the current value! 112 | bool LaserDriver::laserOn = false; 113 | void LaserDriver::initialize() 114 | { 115 | if(EVENT_INITALIZE_LASER) 116 | { 117 | #if LASER_PIN > -1 118 | SET_OUTPUT(LASER_PIN); 119 | #endif 120 | } 121 | changeIntensity(0); 122 | } 123 | void LaserDriver::changeIntensity(uint8_t newIntensity) 124 | { 125 | if(EVENT_SET_LASER(newIntensity)) 126 | { 127 | // Default implementation 128 | #if LASER_PIN > -1 129 | WRITE(LASER_PIN,(LASER_ON_HIGH ? newIntensity > 199 : newIntensity < 200)); 130 | #endif 131 | } 132 | } 133 | #endif // SUPPORT_LASER 134 | 135 | #if defined(SUPPORT_CNC) && SUPPORT_CNC 136 | /** 137 | The CNC driver differs a bit from laser driver. Here only M3,M4,M5 have an influence on the spindle. 138 | The motor also keeps running for G0 moves. M3 and M4 wait for old moves to be finished and then enables 139 | the motor. It then waits CNC_WAIT_ON_ENABLE milliseconds for the spindle to reach target speed. 140 | */ 141 | 142 | int8_t CNCDriver::direction = 0; 143 | /** Initialize cnc pins. EVENT_INITALIZE_CNC should return false to prevent default initalization.*/ 144 | void CNCDriver::initialize() 145 | { 146 | if(EVENT_INITALIZE_CNC) 147 | { 148 | #if CNC_ENABLE_PIN > -1 149 | SET_OUTPUT(CNC_ENABLE_PIN); 150 | WRITE(CNC_ENABLE_PIN,!CNC_ENABLE_WITH); 151 | #endif 152 | #if CNC_DIRECTION_PIN > -1 153 | SET_OUTPUT(CNC_DIRECTION_PIN); 154 | #endif 155 | } 156 | } 157 | /** Turns off spindle. For event override implement 158 | EVENT_SPINDLE_OFF 159 | returning false. 160 | */ 161 | void CNCDriver::spindleOff() 162 | { 163 | if(direction == 0) return; // already off 164 | if(EVENT_SPINDLE_OFF) 165 | { 166 | #if CNC_ENABLE_PIN > -1 167 | WRITE(CNC_ENABLE_PIN,!CNC_ENABLE_WITH); 168 | #endif 169 | } 170 | HAL::delayMilliseconds(CNC_WAIT_ON_DISABLE); 171 | direction = 0; 172 | } 173 | /** Turns spindle on. Default implementation uses a enable pin CNC_ENABLE_PIN. If 174 | CNC_DIRECTION_PIN is not -1 it sets direction to CNC_DIRECTION_CW. rpm is ignored. 175 | To override with event system, return false for the event 176 | EVENT_SPINDLE_CW(rpm) 177 | */ 178 | void CNCDriver::spindleOnCW(int32_t rpm) 179 | { 180 | if(direction == 1) 181 | return; 182 | spindleOff(); 183 | direction = 1; 184 | if(EVENT_SPINDLE_CW(rpm)) { 185 | #if CNC_DIRECTION_PIN > -1 186 | WRITE(CNC_DIRECTION_PIN, CNC_DIRECTION_CW); 187 | #endif 188 | #if CNC_ENABLE_PIN > -1 189 | WRITE(CNC_ENABLE_PIN, CNC_ENABLE_WITH); 190 | #endif 191 | } 192 | HAL::delayMilliseconds(CNC_WAIT_ON_ENABLE); 193 | } 194 | /** Turns spindle on. Default implementation uses a enable pin CNC_ENABLE_PIN. If 195 | CNC_DIRECTION_PIN is not -1 it sets direction to !CNC_DIRECTION_CW. rpm is ignored. 196 | To override with event system, return false for the event 197 | EVENT_SPINDLE_CCW(rpm) 198 | */ 199 | void CNCDriver::spindleOnCCW(int32_t rpm) 200 | { 201 | if(direction == -1) 202 | return; 203 | spindleOff(); 204 | direction = -1; 205 | if(EVENT_SPINDLE_CW(rpm)) { 206 | #if CNC_DIRECTION_PIN > -1 207 | WRITE(CNC_DIRECTION_PIN, !CNC_DIRECTION_CW); 208 | #endif 209 | #if CNC_ENABLE_PIN > -1 210 | WRITE(CNC_ENABLE_PIN, CNC_ENABLE_WITH); 211 | #endif 212 | } 213 | HAL::delayMilliseconds(CNC_WAIT_ON_ENABLE); 214 | } 215 | #endif 216 | -------------------------------------------------------------------------------- /Wangsamas/gcode.h: -------------------------------------------------------------------------------- 1 | /* 2 | Berkas ini adalah bagian dari Wangsamas-Firmware oleh Kusuma Ruslan. 3 | 4 | Wangsamas-Firmware adalah perangkat lunak bebas: 5 | Anda dapat mendistribusikannya dan/atau mengubahnya 6 | dengan syarat dan ketentuan GNU General Public License 7 | yang dipublikasikan oleh Free Software Foundation, 8 | baik ijin versi 3, atau (menurut pilihanmu) versi yang terbaru. 9 | 10 | Wangsamas-Firmware didistribusikan dengan harapan agar dapat bermanfaat, 11 | tetapi TANPA JAMINAN; bahkan tanpa jaminan tersirat PERDAGANGAN atau 12 | KECOCOKAN UNTUK TUJUAN TERTENTU. Lihat GNU General Public License 13 | untuk keterangan lebih lanjut. 14 | 15 | Anda seharusnya sudah menerima salinan GNU General Public License bersamaan 16 | dengan Wangsamas-Firmware. Jika tidak, lihat . 17 | 18 | Firmware ini berdasarkan Repetier-Firmware yang berdasarkan Sprinter firmware 19 | yang berdasarkan Tonokip Reprap firmware yang berdasarkan Hydra-mmm firmware. 20 | 21 | --------------------- 22 | 23 | This file is part of Wangsamas-Firmware by Kusuma Ruslan. 24 | 25 | Wangsamas-Firmware is free software: you can redistribute it and/or modify 26 | it under the terms of the GNU General Public License as published by 27 | the Free Software Foundation, either version 3 of the License, or 28 | (at your option) any later version. 29 | 30 | Wangsamas-Firmware is distributed in the hope that it will be useful, 31 | but WITHOUT ANY WARRANTY; without even the implied warranty of 32 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 33 | GNU General Public License for more details. 34 | 35 | You should have received a copy of the GNU General Public License 36 | along with Wangsamas-Firmware. If not, see . 37 | 38 | This firmware is based on Repetier-Firmware which based on sprinter firmware 39 | which based on Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware. 40 | 41 | */ 42 | #ifndef _GCODE_H 43 | #define _GCODE_H 44 | 45 | #define MAX_CMD_SIZE 96 46 | #define ARRAY_SIZE(_x) (sizeof(_x)/sizeof(_x[0])) 47 | class SDCard; 48 | class GCode // 52 uint8_ts per command needed 49 | { 50 | uint16_t params; 51 | uint16_t params2; 52 | public: 53 | uint16_t N; // Line number 54 | uint16_t M; 55 | uint16_t G; 56 | float X; 57 | float Y; 58 | float Z; 59 | float E; 60 | float F; 61 | int32_t S; 62 | int32_t P; 63 | float I; 64 | float J; 65 | float R; 66 | float D; 67 | float C; 68 | float H; 69 | float A; 70 | float B; 71 | float K; 72 | float L; 73 | float O; 74 | 75 | char *text; //text[17]; 76 | //moved the byte to the end and aligned ints on short boundary 77 | // Old habit from PC, which require alignments for data types such as int and long to be on 2 or 4 byte boundary 78 | // Otherwise, the compiler adds padding, wasted space. 79 | uint8_t T; // This may not matter on any of these controllers, but it can't hurt 80 | // True if origin did not come from serial console. That way we can send status messages to 81 | // a host only if he would normally not know about the mode switch. 82 | bool internalCommand; 83 | inline bool hasM() 84 | { 85 | return ((params & 2)!=0); 86 | } 87 | inline bool hasN() 88 | { 89 | return ((params & 1)!=0); 90 | } 91 | inline bool hasG() 92 | { 93 | return ((params & 4)!=0); 94 | } 95 | inline bool hasX() 96 | { 97 | return ((params & 8)!=0); 98 | } 99 | inline bool hasY() 100 | { 101 | return ((params & 16)!=0); 102 | } 103 | inline bool hasZ() 104 | { 105 | return ((params & 32)!=0); 106 | } 107 | inline bool hasNoXYZ() 108 | { 109 | return ((params & 56)==0); 110 | } 111 | inline bool hasE() 112 | { 113 | return ((params & 64)!=0); 114 | } 115 | inline bool hasF() 116 | { 117 | return ((params & 256)!=0); 118 | } 119 | inline bool hasT() 120 | { 121 | return ((params & 512)!=0); 122 | } 123 | inline bool hasS() 124 | { 125 | return ((params & 1024)!=0); 126 | } 127 | inline bool hasP() 128 | { 129 | return ((params & 2048)!=0); 130 | } 131 | inline bool isV2() 132 | { 133 | return ((params & 4096)!=0); 134 | } 135 | inline bool hasString() 136 | { 137 | return ((params & 32768)!=0); 138 | } 139 | inline bool hasI() 140 | { 141 | return ((params2 & 1)!=0); 142 | } 143 | inline bool hasJ() 144 | { 145 | return ((params2 & 2)!=0); 146 | } 147 | inline bool hasR() 148 | { 149 | return ((params2 & 4)!=0); 150 | } 151 | inline bool hasD() 152 | { 153 | return ((params2 & 8)!=0); 154 | } 155 | inline bool hasC() 156 | { 157 | return ((params2 & 16)!=0); 158 | } 159 | inline bool hasH() 160 | { 161 | return ((params2 & 32)!=0); 162 | } 163 | inline bool hasA() 164 | { 165 | return ((params2 & 64)!=0); 166 | } 167 | inline bool hasB() 168 | { 169 | return ((params2 & 128)!=0); 170 | } 171 | inline bool hasK() 172 | { 173 | return ((params2 & 256)!=0); 174 | } 175 | inline bool hasL() 176 | { 177 | return ((params2 & 512)!=0); 178 | } 179 | inline bool hasO() 180 | { 181 | return ((params2 & 1024)!=0); 182 | } 183 | inline long getS(long def) 184 | { 185 | return (hasS() ? S : def); 186 | } 187 | inline long getP(long def) 188 | { 189 | return (hasP() ? P : def); 190 | } 191 | inline void setFormatError() { 192 | params2 |= 32768; 193 | } 194 | inline bool hasFormatError() { 195 | return ((params2 & 32768)!=0); 196 | } 197 | void printCommand(); 198 | bool parseBinary(uint8_t *buffer,bool fromSerial); 199 | bool parseAscii(char *line,bool fromSerial); 200 | void popCurrentCommand(); 201 | void echoCommand(); 202 | /** Get next command in command buffer. After the command is processed, call gcode_command_finished() */ 203 | static GCode *peekCurrentCommand(); 204 | /** Frees the cache used by the last command fetched. */ 205 | static void readFromSerial(); 206 | static void pushCommand(); 207 | static void executeFString(FSTRINGPARAM(cmd)); 208 | static uint8_t computeBinarySize(char *ptr); 209 | static void fatalError(FSTRINGPARAM(message)); 210 | static void reportFatalError(); 211 | static void resetFatalError(); 212 | inline static bool hasFatalError() { 213 | return fatalErrorMsg != NULL; 214 | } 215 | friend class SDCard; 216 | friend class UIDisplay; 217 | private: 218 | void debugCommandBuffer(); 219 | void checkAndPushCommand(); 220 | static void requestResend(); 221 | inline float parseFloatValue(char *s) 222 | { 223 | char *endPtr; 224 | while(*s == 32) s++; // skip spaces 225 | float f = (strtod(s, &endPtr)); 226 | if(s == endPtr) f=0.0; // treat empty string "x " as "x0" 227 | return f; 228 | } 229 | inline long parseLongValue(char *s) 230 | { 231 | char *endPtr; 232 | while(*s == 32) s++; // skip spaces 233 | long l = (strtol(s, &endPtr, 10)); 234 | if(s == endPtr) l=0; // treat empty string argument "p " as "p0" 235 | return l; 236 | } 237 | 238 | static FSTRINGPARAM(fatalErrorMsg); 239 | static GCode commandsBuffered[GCODE_BUFFER_SIZE]; ///< Buffer for received commands. 240 | static uint8_t bufferReadIndex; ///< Read position in gcode_buffer. 241 | static uint8_t bufferWriteIndex; ///< Write position in gcode_buffer. 242 | static uint8_t commandReceiving[MAX_CMD_SIZE]; ///< Current received command. 243 | static uint8_t commandsReceivingWritePosition; ///< Writing position in gcode_transbuffer. 244 | static uint8_t sendAsBinary; ///< Flags the command as binary input. 245 | static uint8_t wasLastCommandReceivedAsBinary; ///< Was the last successful command in binary mode? 246 | static uint8_t commentDetected; ///< Flags true if we are reading the comment part of a command. 247 | static uint8_t binaryCommandSize; ///< Expected size of the incoming binary command. 248 | static bool waitUntilAllCommandsAreParsed; ///< Don't read until all commands are parsed. Needed if gcode_buffer is misused as storage for strings. 249 | static uint32_t lastLineNumber; ///< Last line number received. 250 | static uint32_t actLineNumber; ///< Line number of current command. 251 | static int8_t waitingForResend; ///< Waiting for line to be resend. -1 = no wait. 252 | static volatile uint8_t bufferLength; ///< Number of commands stored in gcode_buffer 253 | static millis_t timeOfLastDataPacket; ///< Time, when we got the last data packet. Used to detect missing uint8_ts. 254 | static uint8_t formatErrors; ///< Number of sequential format errors 255 | }; 256 | 257 | #if JSON_OUTPUT 258 | #include "SdFat.h" 259 | // Struct to hold Gcode file information 32 bytes 260 | #define GENBY_SIZE 16 261 | class GCodeFileInfo { 262 | public: 263 | void init(SdBaseFile &file); 264 | 265 | unsigned long fileSize; 266 | float objectHeight; 267 | float layerHeight; 268 | float filamentNeeded; 269 | char generatedBy[GENBY_SIZE]; 270 | 271 | bool findGeneratedBy(char *buf, char *genBy); 272 | bool findLayerHeight(char *buf, float &layerHeight); 273 | bool findFilamentNeed(char *buf, float &filament); 274 | bool findTotalHeight(char *buf, float &objectHeight); 275 | }; 276 | #endif 277 | 278 | #endif 279 | 280 | -------------------------------------------------------------------------------- /Wangsamas/Extruder.h: -------------------------------------------------------------------------------- 1 | #ifndef EXTRUDER_H_INCLUDED 2 | #define EXTRUDER_H_INCLUDED 3 | 4 | #define CELSIUS_EXTRA_BITS 3 5 | #define VIRTUAL_EXTRUDER 16 // don't change this to more then 16 without modifying the eeprom positions 6 | 7 | //#if TEMP_PID 8 | //extern uint8_t current_extruder_out; 9 | //#endif 10 | 11 | // Updates the temperature of all extruders and heated bed if it's time. 12 | // Toggles the heater power if necessary. 13 | extern bool reportTempsensorError(); ///< Report defect sensors 14 | extern uint8_t manageMonitor; 15 | #define HTR_OFF 0 16 | #define HTR_PID 1 17 | #define HTR_SLOWBANG 2 18 | #define HTR_DEADTIME 3 19 | 20 | #define TEMPERATURE_CONTROLLER_FLAG_ALARM 1 21 | #define TEMPERATURE_CONTROLLER_FLAG_DECOUPLE_FULL 2 //< Full heating enabled 22 | #define TEMPERATURE_CONTROLLER_FLAG_DECOUPLE_HOLD 4 //< Holding target temperature 23 | #define TEMPERATURE_CONTROLLER_FLAG_SENSDEFECT 8 //< Indicating sensor defect 24 | #define TEMPERATURE_CONTROLLER_FLAG_SENSDECOUPLED 16 //< Indicating sensor decoupling 25 | #define TEMPERATURE_CONTROLLER_FLAG_JAM 32 //< Indicates a jammed filament 26 | #define TEMPERATURE_CONTROLLER_FLAG_SLOWDOWN 64 //< Indicates a slowed down extruder 27 | 28 | /** TemperatureController manages one heater-temperature sensor loop. You can have up to 29 | 4 loops allowing pid/bang bang for up to 3 extruder and the heated bed. 30 | 31 | */ 32 | class TemperatureController 33 | { 34 | public: 35 | uint8_t pwmIndex; ///< pwm index for output control. 0-2 = Extruder, 3 = Fan, 4 = Heated Bed 36 | uint8_t sensorType; ///< Type of temperature sensor. 37 | uint8_t sensorPin; ///< Pin to read extruder temperature. 38 | int8_t heatManager; ///< How is temperature controlled. 0 = on/off, 1 = PID-Control, 3 = dead time control 39 | int16_t currentTemperature; ///< Current temperature value read from sensor. 40 | //int16_t targetTemperature; ///< Target temperature value in units of sensor. 41 | float currentTemperatureC; ///< Current temperature in degC. 42 | float targetTemperatureC; ///< Target temperature in degC. 43 | uint32_t lastTemperatureUpdate; ///< Time in millis of the last temperature update. 44 | #if TEMP_PID 45 | float tempIState; ///< Temp. var. for PID computation. 46 | uint8_t pidDriveMax; ///< Used for windup in PID calculation. 47 | uint8_t pidDriveMin; ///< Used for windup in PID calculation. 48 | #define deadTime pidPGain 49 | // deadTime is logically different value but physically overlays pidPGain for saving space 50 | float pidPGain; ///< Pgain (proportional gain) for PID temperature control [0,01 Units]. 51 | float pidIGain; ///< Igain (integral) for PID temperature control [0,01 Units]. 52 | float pidDGain; ///< Dgain (damping) for PID temperature control [0,01 Units]. 53 | uint8_t pidMax; ///< Maximum PWM value, the heater should be set. 54 | float tempIStateLimitMax; 55 | float tempIStateLimitMin; 56 | uint8_t tempPointer; 57 | float tempArray[4]; 58 | #endif 59 | uint8_t flags; 60 | millis_t lastDecoupleTest; ///< Last time of decoupling sensor-heater test 61 | float lastDecoupleTemp; ///< Temperature on last test 62 | millis_t decoupleTestPeriod; ///< Time between setting and testing decoupling. 63 | 64 | void setTargetTemperature(float target); 65 | void updateCurrentTemperature(); 66 | void updateTempControlVars(); 67 | inline bool isAlarm() 68 | { 69 | return flags & TEMPERATURE_CONTROLLER_FLAG_ALARM; 70 | } 71 | inline void setAlarm(bool on) 72 | { 73 | if(on) flags |= TEMPERATURE_CONTROLLER_FLAG_ALARM; 74 | else flags &= ~TEMPERATURE_CONTROLLER_FLAG_ALARM; 75 | } 76 | inline bool isDecoupleFull() 77 | { 78 | return flags & TEMPERATURE_CONTROLLER_FLAG_DECOUPLE_FULL; 79 | } 80 | inline void removeErrorStates() { 81 | flags &= ~(TEMPERATURE_CONTROLLER_FLAG_ALARM | TEMPERATURE_CONTROLLER_FLAG_SENSDEFECT | TEMPERATURE_CONTROLLER_FLAG_SENSDECOUPLED); 82 | } 83 | inline bool isDecoupleFullOrHold() 84 | { 85 | return flags & (TEMPERATURE_CONTROLLER_FLAG_DECOUPLE_FULL | TEMPERATURE_CONTROLLER_FLAG_DECOUPLE_HOLD); 86 | } 87 | inline void setDecoupleFull(bool on) 88 | { 89 | flags &= ~(TEMPERATURE_CONTROLLER_FLAG_DECOUPLE_FULL | TEMPERATURE_CONTROLLER_FLAG_DECOUPLE_HOLD); 90 | if(on) flags |= TEMPERATURE_CONTROLLER_FLAG_DECOUPLE_FULL; 91 | } 92 | inline bool isDecoupleHold() 93 | { 94 | return flags & TEMPERATURE_CONTROLLER_FLAG_DECOUPLE_HOLD; 95 | } 96 | inline void setDecoupleHold(bool on) 97 | { 98 | flags &= ~(TEMPERATURE_CONTROLLER_FLAG_DECOUPLE_FULL | TEMPERATURE_CONTROLLER_FLAG_DECOUPLE_HOLD); 99 | if(on) flags |= TEMPERATURE_CONTROLLER_FLAG_DECOUPLE_HOLD; 100 | } 101 | inline void startFullDecouple(millis_t &t) 102 | { 103 | if(isDecoupleFull()) return; 104 | lastDecoupleTest = t; 105 | lastDecoupleTemp = currentTemperatureC; 106 | setDecoupleFull(true); 107 | } 108 | inline void startHoldDecouple(millis_t &t) 109 | { 110 | if(isDecoupleHold()) return; 111 | if(fabs(currentTemperatureC - targetTemperatureC) + 1 > DECOUPLING_TEST_MAX_HOLD_VARIANCE) return; 112 | lastDecoupleTest = t; 113 | lastDecoupleTemp = targetTemperatureC; 114 | setDecoupleHold(true); 115 | } 116 | inline void stopDecouple() 117 | { 118 | setDecoupleFull(false); 119 | } 120 | inline bool isSensorDefect() 121 | { 122 | return flags & TEMPERATURE_CONTROLLER_FLAG_SENSDEFECT; 123 | } 124 | inline bool isSensorDecoupled() 125 | { 126 | return flags & TEMPERATURE_CONTROLLER_FLAG_SENSDECOUPLED; 127 | } 128 | static void resetAllErrorStates(); 129 | #if EXTRUDER_JAM_CONTROL 130 | inline bool isJammed() 131 | { 132 | return flags & TEMPERATURE_CONTROLLER_FLAG_JAM; 133 | } 134 | void setJammed(bool on); 135 | inline bool isSlowedDown() 136 | { 137 | return flags & TEMPERATURE_CONTROLLER_FLAG_SLOWDOWN; 138 | } 139 | inline void setSlowedDown(bool on) 140 | { 141 | flags &= ~TEMPERATURE_CONTROLLER_FLAG_SLOWDOWN; 142 | if(on) flags |= TEMPERATURE_CONTROLLER_FLAG_SLOWDOWN; 143 | } 144 | 145 | #endif 146 | void waitForTargetTemperature(); 147 | #if TEMP_PID 148 | void autotunePID(float temp,uint8_t controllerId,int maxCycles,bool storeResult); 149 | #endif 150 | }; 151 | class Extruder; 152 | extern Extruder extruder[]; 153 | 154 | #if EXTRUDER_JAM_CONTROL 155 | #if JAM_METHOD == 1 156 | #define _TEST_EXTRUDER_JAM(x,pin) {\ 157 | uint8_t sig = READ(pin);extruder[x].jamStepsSinceLastSignal += extruder[x].jamLastDir;\ 158 | if(extruder[x].jamLastSignal != sig && abs(extruder[x].jamStepsSinceLastSignal - extruder[x].jamLastChangeAt) > JAM_MIN_STEPS) {\ 159 | if(sig) {extruder[x].resetJamSteps();} \ 160 | extruder[x].jamLastSignal = sig;extruder[x].jamLastChangeAt = extruder[x].jamStepsSinceLastSignal;\ 161 | } else if(abs(extruder[x].jamStepsSinceLastSignal) > JAM_ERROR_STEPS && !Printer::isDebugJamOrDisabled() && !extruder[x].tempControl.isJammed()) \ 162 | extruder[x].tempControl.setJammed(true);\ 163 | } 164 | #define RESET_EXTRUDER_JAM(x,dir) extruder[x].jamLastDir = dir ? 1 : -1; 165 | #elif JAM_METHOD == 2 166 | #define _TEST_EXTRUDER_JAM(x,pin) {\ 167 | uint8_t sig = READ(pin);\ 168 | if(sig){extruder[x].tempControl.setJammed(true);} else if(!Printer::isDebugJamOrDisabled() && !extruder[x].tempControl.isJammed()) {extruder[x].resetJamSteps();}} 169 | #define RESET_EXTRUDER_JAM(x,dir) 170 | #elif JAM_METHOD == 3 171 | #define _TEST_EXTRUDER_JAM(x,pin) {\ 172 | uint8_t sig = !READ(pin);\ 173 | if(sig){extruder[x].tempControl.setJammed(true);} else if(!Printer::isDebugJamOrDisabled() && !extruder[x].tempControl.isJammed()) {extruder[x].resetJamSteps();}} 174 | #define RESET_EXTRUDER_JAM(x,dir) 175 | #else 176 | #error Unknown value for JAM_METHOD 177 | #endif 178 | #define ___TEST_EXTRUDER_JAM(x,y) _TEST_EXTRUDER_JAM(x,y) 179 | #define __TEST_EXTRUDER_JAM(x) ___TEST_EXTRUDER_JAM(x,EXT ## x ## _JAM_PIN) 180 | #define TEST_EXTRUDER_JAM(x) __TEST_EXTRUDER_JAM(x) 181 | #else 182 | #define TEST_EXTRUDER_JAM(x) 183 | #define RESET_EXTRUDER_JAM(x,dir) 184 | #endif 185 | 186 | #define EXTRUDER_FLAG_RETRACTED 1 187 | #define EXTRUDER_FLAG_WAIT_JAM_STARTCOUNT 2 ///< Waiting for the first signal to start counting 188 | 189 | /** \brief Data to drive one extruder. 190 | 191 | This structure contains all definitions for an extruder and all 192 | current state variables, like current temperature, feeder position etc. 193 | */ 194 | class Extruder // Size: 12*1 Byte+12*4 Byte+4*2Byte = 68 Byte 195 | { 196 | public: 197 | static Extruder *current; 198 | #if FEATURE_DITTO_PRINTING 199 | static uint8_t dittoMode; 200 | #endif 201 | #if MIXING_EXTRUDER > 0 202 | static int mixingS; ///< Sum of all weights 203 | static uint8_t mixingDir; ///< Direction flag 204 | static uint8_t activeMixingExtruder; 205 | static void recomputeMixingExtruderSteps(); 206 | #endif 207 | uint8_t id; 208 | int32_t xOffset; 209 | int32_t yOffset; 210 | int32_t zOffset; 211 | float StepsPerUnit; ///< steps per unit. 212 | int8_t enablePin; ///< Pin to enable extruder stepper motor. 213 | // uint8_t directionPin; ///< Pin number to assign the direction. 214 | // uint8_t stepPin; ///< Pin number for a step. 215 | uint8_t enableOn; 216 | // uint8_t invertDir; ///< 1 if the direction of the extruder should be inverted. 217 | float maxFeedrate; ///< Maximum feedrate in mm/s. 218 | float maxAcceleration; ///< Maximum acceleration in mm/s^2. 219 | float maxStartFeedrate; ///< Maximum start feedrate in mm/s. 220 | int32_t extrudePosition; ///< Current extruder position in steps. 221 | int16_t watchPeriod; ///< Time in seconds, a M109 command will wait to stabalize temperature 222 | int16_t waitRetractTemperature; ///< Temperature to retract the filament when waiting for heatup 223 | int16_t waitRetractUnits; ///< Units to retract the filament when waiting for heatup 224 | #if USE_ADVANCE 225 | #if ENABLE_QUADRATIC_ADVANCE 226 | float advanceK; ///< Koefficient for advance algorithm. 0 = off 227 | #endif 228 | float advanceL; 229 | int16_t advanceBacklash; 230 | #endif // USE_ADVANCE 231 | #if MIXING_EXTRUDER > 0 232 | int mixingW; ///< Weight for this extruder when mixing steps 233 | int mixingE; ///< Cumulated error for this step. 234 | int virtualWeights[VIRTUAL_EXTRUDER]; // Virtual extruder weights 235 | #endif // MIXING_EXTRUDER > 0 236 | TemperatureController tempControl; 237 | const char * PROGMEM selectCommands; 238 | const char * PROGMEM deselectCommands; 239 | uint8_t coolerSpeed; ///< Speed to use when enabled 240 | uint8_t coolerPWM; ///< current PWM setting 241 | float diameter; 242 | uint8_t flags; 243 | #if EXTRUDER_JAM_CONTROL 244 | int16_t jamStepsSinceLastSignal; // when was the last signal 245 | uint8_t jamLastSignal; // what was the last signal 246 | int8_t jamLastDir; 247 | int16_t jamStepsOnSignal; 248 | int16_t jamLastChangeAt; 249 | #endif 250 | 251 | // Methods here 252 | 253 | #if EXTRUDER_JAM_CONTROL 254 | inline bool isWaitJamStartcount() 255 | { 256 | return flags & EXTRUDER_FLAG_WAIT_JAM_STARTCOUNT; 257 | } 258 | inline void setWaitJamStartcount(bool on) 259 | { 260 | if(on) flags |= EXTRUDER_FLAG_WAIT_JAM_STARTCOUNT; 261 | else flags &= ~(EXTRUDER_FLAG_WAIT_JAM_STARTCOUNT); 262 | } 263 | static void markAllUnjammed(); 264 | void resetJamSteps(); 265 | #endif 266 | #if MIXING_EXTRUDER > 0 267 | static void setMixingWeight(uint8_t extr,int weight); 268 | #endif 269 | static void step(); 270 | static void unstep(); 271 | static void setDirection(uint8_t dir); 272 | static void enable(); 273 | #if FEATURE_RETRACTION 274 | inline bool isRetracted() {return (flags & EXTRUDER_FLAG_RETRACTED) != 0;} 275 | inline void setRetracted(bool on) { 276 | flags = (flags & (255 - EXTRUDER_FLAG_RETRACTED)) | (on ? EXTRUDER_FLAG_RETRACTED : 0); 277 | } 278 | void retract(bool isRetract,bool isLong); 279 | void retractDistance(float dist); 280 | #endif 281 | static void manageTemperatures(); 282 | static void disableCurrentExtruderMotor(); 283 | static void disableAllExtruderMotors(); 284 | static void selectExtruderById(uint8_t extruderId); 285 | static void disableAllHeater(); 286 | static void initExtruder(); 287 | static void initHeatedBed(); 288 | static void setHeatedBedTemperature(float temp_celsius,bool beep = false); 289 | static float getHeatedBedTemperature(); 290 | static void setTemperatureForExtruder(float temp_celsius,uint8_t extr,bool beep = false,bool wait = false); 291 | static void pauseExtruders(); 292 | static void unpauseExtruders(); 293 | }; 294 | 295 | #if HAVE_HEATED_BED 296 | #define HEATED_BED_INDEX NUM_EXTRUDER 297 | extern TemperatureController heatedBedController; 298 | #else 299 | #define HEATED_BED_INDEX NUM_EXTRUDER-1 300 | #endif 301 | #if FAN_THERMO_PIN > -1 302 | #define THERMO_CONTROLLER_INDEX HEATED_BED_INDEX+1 303 | extern TemperatureController thermoController; 304 | #else 305 | #define THERMO_CONTROLLER_INDEX HEATED_BED_INDEX 306 | #endif 307 | #define NUM_TEMPERATURE_LOOPS THERMO_CONTROLLER_INDEX+1 308 | 309 | #define TEMP_INT_TO_FLOAT(temp) ((float)(temp)/(float)(1< 0 314 | extern TemperatureController *tempController[NUM_TEMPERATURE_LOOPS]; 315 | #endif 316 | extern uint8_t autotuneIndex; 317 | 318 | 319 | #endif // EXTRUDER_H_INCLUDED 320 | -------------------------------------------------------------------------------- /Wangsamas/Communication.h: -------------------------------------------------------------------------------- 1 | /* 2 | Berkas ini adalah bagian dari Wangsamas-Firmware oleh Kusuma Ruslan. 3 | 4 | Wangsamas-Firmware adalah perangkat lunak bebas: 5 | Anda dapat mendistribusikannya dan/atau mengubahnya 6 | dengan syarat dan ketentuan GNU General Public License 7 | yang dipublikasikan oleh Free Software Foundation, 8 | baik ijin versi 3, atau (menurut pilihanmu) versi yang terbaru. 9 | 10 | Wangsamas-Firmware didistribusikan dengan harapan agar dapat bermanfaat, 11 | tetapi TANPA JAMINAN; bahkan tanpa jaminan tersirat PERDAGANGAN atau 12 | KECOCOKAN UNTUK TUJUAN TERTENTU. Lihat GNU General Public License 13 | untuk keterangan lebih lanjut. 14 | 15 | Anda seharusnya sudah menerima salinan GNU General Public License bersamaan 16 | dengan Wangsamas-Firmware. Jika tidak, lihat . 17 | 18 | Firmware ini berdasarkan Repetier-Firmware yang berdasarkan Sprinter firmware 19 | yang berdasarkan Tonokip Reprap firmware yang berdasarkan Hydra-mmm firmware. 20 | 21 | --------------------- 22 | 23 | This file is part of Wangsamas-Firmware by Kusuma Ruslan. 24 | 25 | Wangsamas-Firmware is free software: you can redistribute it and/or modify 26 | it under the terms of the GNU General Public License as published by 27 | the Free Software Foundation, either version 3 of the License, or 28 | (at your option) any later version. 29 | 30 | Wangsamas-Firmware is distributed in the hope that it will be useful, 31 | but WITHOUT ANY WARRANTY; without even the implied warranty of 32 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 33 | GNU General Public License for more details. 34 | 35 | You should have received a copy of the GNU General Public License 36 | along with Wangsamas-Firmware. If not, see . 37 | 38 | This firmware is based on Repetier-Firmware which based on sprinter firmware 39 | which based on Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware. 40 | */ 41 | 42 | #ifndef COMMUNICATION_H 43 | #define COMMUNICATION_H 44 | 45 | class Com 46 | { 47 | public: 48 | FSTRINGVAR(tDebug) 49 | FSTRINGVAR(tFirmware) 50 | FSTRINGVAR(tOk) 51 | FSTRINGVAR(tNewline) 52 | FSTRINGVAR(tNAN) 53 | FSTRINGVAR(tINF) 54 | FSTRINGVAR(tError) 55 | FSTRINGVAR(tInfo) 56 | FSTRINGVAR(tWarning) 57 | FSTRINGVAR(tResend) 58 | FSTRINGVAR(tEcho) 59 | FSTRINGVAR(tOkSpace) 60 | FSTRINGVAR(tWrongChecksum) 61 | FSTRINGVAR(tMissingChecksum) 62 | FSTRINGVAR(tFormatError) 63 | FSTRINGVAR(tDonePrinting) 64 | FSTRINGVAR(tX) 65 | FSTRINGVAR(tY) 66 | FSTRINGVAR(tZ) 67 | FSTRINGVAR(tE) 68 | FSTRINGVAR(tF) 69 | FSTRINGVAR(tS) 70 | FSTRINGVAR(tP) 71 | FSTRINGVAR(tI) 72 | FSTRINGVAR(tJ) 73 | FSTRINGVAR(tR) 74 | FSTRINGVAR(tSDReadError) 75 | FSTRINGVAR(tExpectedLine) 76 | FSTRINGVAR(tGot) 77 | FSTRINGVAR(tSkip) 78 | FSTRINGVAR(tBLK) 79 | FSTRINGVAR(tStart) 80 | FSTRINGVAR(tPowerUp) 81 | FSTRINGVAR(tExternalReset) 82 | FSTRINGVAR(tBrownOut) 83 | FSTRINGVAR(tWatchdog) 84 | FSTRINGVAR(tSoftwareReset) 85 | FSTRINGVAR(tUnknownCommand) 86 | FSTRINGVAR(tFreeRAM) 87 | FSTRINGVAR(tXColon) 88 | FSTRINGVAR(tSlash) 89 | FSTRINGVAR(tSpaceSlash) 90 | FSTRINGVAR(tFatal) 91 | #if JSON_OUTPUT 92 | FSTRINGVAR(tJSONDir) 93 | FSTRINGVAR(tJSONFiles) 94 | FSTRINGVAR(tJSONArrayEnd) 95 | FSTRINGVAR(tJSONErrorStart) 96 | FSTRINGVAR(tJSONErrorEnd) 97 | FSTRINGVAR(tJSONFileInfoStart) 98 | FSTRINGVAR(tJSONFileInfoHeight) 99 | FSTRINGVAR(tJSONFileInfoLayerHeight) 100 | FSTRINGVAR(tJSONFileInfoFilament) 101 | FSTRINGVAR(tJSONFileInfoGeneratedBy) 102 | FSTRINGVAR(tJSONFileInfoName) 103 | #endif 104 | FSTRINGVAR(tSpaceXColon) 105 | FSTRINGVAR(tSpaceYColon) 106 | FSTRINGVAR(tSpaceZColon) 107 | FSTRINGVAR(tSpaceEColon) 108 | FSTRINGVAR(tTColon) 109 | FSTRINGVAR(tSpaceBColon) 110 | FSTRINGVAR(tSpaceAtColon) 111 | FSTRINGVAR(tSpaceT) 112 | FSTRINGVAR(tSpaceRaw) 113 | FSTRINGVAR(tSpaceAt) 114 | FSTRINGVAR(tSpaceBAtColon) 115 | FSTRINGVAR(tColon) 116 | FSTRINGVAR(tSpeedMultiply) 117 | FSTRINGVAR(tFlowMultiply) 118 | FSTRINGVAR(tFanspeed) 119 | FSTRINGVAR(tFan2speed) 120 | FSTRINGVAR(tPrintedFilament) 121 | FSTRINGVAR(tPrintingTime) 122 | FSTRINGVAR(tSpacem) 123 | FSTRINGVAR(tSpaceDaysSpace) 124 | FSTRINGVAR(tSpaceHoursSpace) 125 | FSTRINGVAR(tSpaceMin) 126 | FSTRINGVAR(tInvalidArc) 127 | FSTRINGVAR(tComma) 128 | FSTRINGVAR(tSpace) 129 | FSTRINGVAR(tYColon) 130 | FSTRINGVAR(tZColon) 131 | FSTRINGVAR(tE0Colon) 132 | FSTRINGVAR(tE1Colon) 133 | FSTRINGVAR(tMS1MS2Pins) 134 | FSTRINGVAR(tSetOutputSpace) 135 | FSTRINGVAR(tGetInputSpace) 136 | FSTRINGVAR(tSpaceToSpace) 137 | FSTRINGVAR(tSpaceIsSpace) 138 | FSTRINGVAR(tHSpace) 139 | FSTRINGVAR(tLSpace) 140 | FSTRINGVAR(tXMinColon) 141 | FSTRINGVAR(tXMaxColon) 142 | FSTRINGVAR(tYMinColon) 143 | FSTRINGVAR(tYMaxColon) 144 | FSTRINGVAR(tZMinColon) 145 | FSTRINGVAR(tZ2MinMaxColon) 146 | FSTRINGVAR(tZMaxColon) 147 | FSTRINGVAR(tJerkColon) 148 | FSTRINGVAR(tZJerkColon) 149 | FSTRINGVAR(tLinearStepsColon) 150 | FSTRINGVAR(tQuadraticStepsColon) 151 | FSTRINGVAR(tCommaSpeedEqual) 152 | FSTRINGVAR(tLinearLColon) 153 | FSTRINGVAR(tQuadraticKColon) 154 | FSTRINGVAR(tEEPROMUpdated) 155 | FSTRINGVAR(tFilamentSlipping) 156 | FSTRINGVAR(tPauseCommunication) 157 | FSTRINGVAR(tContinueCommunication) 158 | #if NONLINEAR_SYSTEM 159 | FSTRINGVAR(tInvalidDeltaCoordinate) 160 | FSTRINGVAR(tDBGDeltaNoMoveinDSegment) 161 | #endif 162 | #if DRIVE_SYSTEM == DELTA 163 | FSTRINGVAR(tMeasurementReset) 164 | FSTRINGVAR(tMeasureDeltaSteps) 165 | FSTRINGVAR(tMeasureDelta) 166 | FSTRINGVAR(tMeasureOriginReset) 167 | FSTRINGVAR(tMeasurementAbortedOrigin) 168 | FSTRINGVAR(tLevelingCalc) 169 | FSTRINGVAR(tTower1) 170 | FSTRINGVAR(tTower2) 171 | FSTRINGVAR(tTower3) 172 | FSTRINGVAR(tDeltaAlphaA) 173 | FSTRINGVAR(tDeltaAlphaB) 174 | FSTRINGVAR(tDeltaAlphaC) 175 | FSTRINGVAR(tDeltaRadiusCorrectionA) 176 | FSTRINGVAR(tDeltaRadiusCorrectionB) 177 | FSTRINGVAR(tDeltaRadiusCorrectionC) 178 | FSTRINGVAR(tDeltaDiagonalCorrectionA) 179 | FSTRINGVAR(tDeltaDiagonalCorrectionB) 180 | FSTRINGVAR(tDeltaDiagonalCorrectionC) 181 | FSTRINGVAR(tEPRDeltaMaxRadius) 182 | #endif // DRIVE_SYSTEM 183 | #if DRIVE_SYSTEM==TUGA 184 | FSTRINGVAR(tEPRDiagonalRodLength) 185 | #endif 186 | #ifdef DEBUG_GENERIC 187 | FSTRINGVAR(tGenTemp) 188 | #endif // DEBUG_GENERICFSTRINGVALUE(Com::,"") 189 | FSTRINGVAR(tTargetExtr) 190 | FSTRINGVAR(tTargetBedColon) 191 | FSTRINGVAR(tPIDAutotuneStart) 192 | FSTRINGVAR(tAPIDBias) 193 | FSTRINGVAR(tAPIDD) 194 | FSTRINGVAR(tAPIDMin) 195 | FSTRINGVAR(tAPIDMax) 196 | FSTRINGVAR(tAPIDKu) 197 | FSTRINGVAR(tAPIDTu) 198 | FSTRINGVAR(tAPIDClassic) 199 | FSTRINGVAR(tAPIDKp) 200 | FSTRINGVAR(tAPIDKi) 201 | FSTRINGVAR(tAPIDKd) 202 | FSTRINGVAR(tAPIDFailedHigh) 203 | FSTRINGVAR(tAPIDFailedTimeout) 204 | FSTRINGVAR(tAPIDFinished) 205 | FSTRINGVAR(tMTEMPColon) 206 | FSTRINGVAR(tHeatedBed) 207 | FSTRINGVAR(tExtruderSpace) 208 | FSTRINGVAR(tTempSensorDefect) 209 | FSTRINGVAR(tTempSensorWorking) 210 | FSTRINGVAR(tDryModeUntilRestart) 211 | #ifdef DEBUG_QUEUE_MOVE 212 | FSTRINGVAR(tDBGId) 213 | FSTRINGVAR(tDBGVStartEnd) 214 | FSTRINGVAR(tDBAccelSteps) 215 | FSTRINGVAR(tDBGStartEndSpeed) 216 | FSTRINGVAR(tDBGFlags) 217 | FSTRINGVAR(tDBGJoinFlags) 218 | FSTRINGVAR(tDBGDelta) 219 | FSTRINGVAR(tDBGDir) 220 | FSTRINGVAR(tDBGFullSpeed) 221 | FSTRINGVAR(tDBGVMax) 222 | FSTRINGVAR(tDBGAcceleration) 223 | FSTRINGVAR(tDBGAccelerationPrim) 224 | FSTRINGVAR(tDBGRemainingSteps) 225 | FSTRINGVAR(tDBGAdvanceFull) 226 | FSTRINGVAR(tDBGAdvanceRate) 227 | FSTRINGVAR(tDBGLimitInterval) 228 | FSTRINGVAR(tDBGMoveDistance) 229 | FSTRINGVAR(tDBGCommandedFeedrate) 230 | FSTRINGVAR(tDBGConstFullSpeedMoveTime) 231 | #endif // DEBUG_QUEUE_MOVEFSTRINGVALUE(Com::,"") 232 | #ifdef DEBUG_DELTA_OVERFLOW 233 | FSTRINGVAR(tDBGDeltaOverflow) 234 | #endif // DEBUG_DELTA_OVERFLOW 235 | #ifdef DEBUG_SPLIT 236 | FSTRINGVAR(tDBGDeltaSeconds) 237 | FSTRINGVAR(tDBGDeltaZDelta) 238 | FSTRINGVAR(tDBGDeltaSegments) 239 | FSTRINGVAR(tDBGDeltaNumLines) 240 | FSTRINGVAR(tDBGDeltaSegmentsPerLine) 241 | FSTRINGVAR(tDBGDeltaMaxDS) 242 | FSTRINGVAR(tDBGDeltaStepsPerSegment) 243 | FSTRINGVAR(tDBGDeltaVirtualAxisSteps) 244 | #endif 245 | #ifdef DEBUG_STEPCOUNT 246 | FSTRINGVAR(tDBGMissedSteps) 247 | #endif 248 | #if FEATURE_Z_PROBE 249 | FSTRINGVAR(tZProbe) 250 | FSTRINGVAR(tZProbeState) 251 | FSTRINGVAR(tZProbeStartScript) 252 | FSTRINGVAR(tZProbeEndScript) 253 | FSTRINGVAR(tHitZProbe) 254 | FSTRINGVAR(tZProbeAverage) 255 | FSTRINGVAR(tZProbeZReset) 256 | FSTRINGVAR(tZProbeBedDitance) 257 | #endif 258 | FSTRINGVAR(tAutolevelReset) 259 | FSTRINGVAR(tAutolevelEnabled) 260 | FSTRINGVAR(tAutolevelDisabled) 261 | FSTRINGVAR(tTransformationMatrix) 262 | FSTRINGVAR(tZProbeFailed) 263 | FSTRINGVAR(tZProbeMax) 264 | FSTRINGVAR(tZProbePrinterHeight) 265 | 266 | #ifdef WAITING_IDENTIFIER 267 | FSTRINGVAR(tWait) 268 | #endif // WAITING_IDENTIFIER 269 | 270 | #if EEPROM_MODE==0 271 | FSTRINGVAR(tNoEEPROMSupport) 272 | #else 273 | FSTRINGVAR(tZProbeOffsetZ) 274 | #if FEATURE_Z_PROBE 275 | FSTRINGVAR(tZProbeHeight) 276 | FSTRINGVAR(tZProbeOffsetX) 277 | FSTRINGVAR(tZProbeOffsetY) 278 | FSTRINGVAR(tZProbeSpeed) 279 | FSTRINGVAR(tZProbeSpeedXY) 280 | FSTRINGVAR(tZProbeX1) 281 | FSTRINGVAR(tZProbeY1) 282 | FSTRINGVAR(tZProbeX2) 283 | FSTRINGVAR(tZProbeY2) 284 | FSTRINGVAR(tZProbeX3) 285 | FSTRINGVAR(tZProbeY3) 286 | FSTRINGVAR(zZProbeBendingCorA) 287 | FSTRINGVAR(zZProbeBendingCorB) 288 | FSTRINGVAR(zZProbeBendingCorC) 289 | #endif 290 | #if FEATURE_AUTOLEVEL 291 | FSTRINGVAR(tAutolevelActive) 292 | #endif 293 | #if FEATURE_AXISCOMP 294 | FSTRINGVAR(tAxisCompTanXY) 295 | FSTRINGVAR(tAxisCompTanYZ) 296 | FSTRINGVAR(tAxisCompTanXZ) 297 | #endif 298 | FSTRINGVAR(tConfigStoredEEPROM) 299 | FSTRINGVAR(tConfigLoadedEEPROM) 300 | FSTRINGVAR(tEPRConfigResetDefaults) 301 | FSTRINGVAR(tEPRProtocolChanged) 302 | FSTRINGVAR(tEPR0) 303 | FSTRINGVAR(tEPR1) 304 | FSTRINGVAR(tEPR2) 305 | FSTRINGVAR(tEPR3) 306 | FSTRINGVAR(tLanguage) 307 | FSTRINGVAR(tEPRBaudrate) 308 | FSTRINGVAR(tEPRFilamentPrinted) 309 | FSTRINGVAR(tEPRPrinterActive) 310 | FSTRINGVAR(tEPRMaxInactiveTime) 311 | FSTRINGVAR(tEPRStopAfterInactivty) 312 | FSTRINGVAR(tEPRMaxJerk) 313 | FSTRINGVAR(tEPRXHomePos) 314 | FSTRINGVAR(tEPRYHomePos) 315 | FSTRINGVAR(tEPRZHomePos) 316 | FSTRINGVAR(tEPRXMaxLength) 317 | FSTRINGVAR(tEPRYMaxLength) 318 | FSTRINGVAR(tEPRZMaxLength) 319 | FSTRINGVAR(tEPRXBacklash) 320 | FSTRINGVAR(tEPRYBacklash) 321 | FSTRINGVAR(tEPRZBacklash) 322 | FSTRINGVAR(tEPRZAcceleration) 323 | FSTRINGVAR(tEPRZTravelAcceleration) 324 | FSTRINGVAR(tEPRAccelerationFactorAtTop) 325 | FSTRINGVAR(tEPRZStepsPerUnit) 326 | FSTRINGVAR(tEPRZMaxFeedrate) 327 | FSTRINGVAR(tEPRZHomingFeedrate) 328 | #if DRIVE_SYSTEM != DELTA 329 | FSTRINGVAR(tEPRMaxZJerk) 330 | FSTRINGVAR(tEPRXStepsPerUnit) 331 | FSTRINGVAR(tEPRYStepsPerUnit) 332 | FSTRINGVAR(tEPRXMaxFeedrate) 333 | FSTRINGVAR(tEPRYMaxFeedrate) 334 | FSTRINGVAR(tEPRXHomingFeedrate) 335 | FSTRINGVAR(tEPRYHomingFeedrate) 336 | FSTRINGVAR(tEPRXAcceleration) 337 | FSTRINGVAR(tEPRYAcceleration) 338 | FSTRINGVAR(tEPRXTravelAcceleration) 339 | FSTRINGVAR(tEPRYTravelAcceleration) 340 | #else 341 | FSTRINGVAR(tEPRDiagonalRodLength) 342 | FSTRINGVAR(tEPRHorizontalRadius) 343 | FSTRINGVAR(tEPRTowerXOffset) 344 | FSTRINGVAR(tEPRTowerYOffset) 345 | FSTRINGVAR(tEPRTowerZOffset) 346 | #endif 347 | #if DRIVE_SYSTEM == SCARA // Kusuma SCARA 348 | FSTRINGVAR(tArmLength) // Kusuma SCARA 349 | FSTRINGVAR(tForearmLength) // Kusuma SCARA 350 | FSTRINGVAR(tShoulderMinAngle) // Kusuma SCARA 351 | FSTRINGVAR(tElbowMinAngle) // Kusuma SCARA 352 | FSTRINGVAR(tShoulderMaxAngle) // Kusuma SCARA 353 | FSTRINGVAR(tElbowMaxAngle) // Kusuma SCARA 354 | FSTRINGVAR(tShoulderBedCenterAngle) // Kusuma SCARA 355 | FSTRINGVAR(tElbowBedCenterAngle) // Kusuma SCARA 356 | #endif // Kusuma SCARA 357 | FSTRINGVAR(tEPROPSMode) 358 | FSTRINGVAR(tEPROPSMoveAfter) 359 | FSTRINGVAR(tEPROPSMinDistance) 360 | FSTRINGVAR(tEPROPSRetractionLength) 361 | FSTRINGVAR(tEPROPSRetractionBacklash) 362 | FSTRINGVAR(tEPRBedHeatManager) 363 | FSTRINGVAR(tEPRBedPIDDriveMax) 364 | FSTRINGVAR(tEPRBedPIDDriveMin) 365 | FSTRINGVAR(tEPRBedPGain) 366 | FSTRINGVAR(tEPRBedIGain) 367 | FSTRINGVAR(tEPRBedDGain) 368 | FSTRINGVAR(tEPRBedPISMaxValue) 369 | FSTRINGVAR(tEPRStepsPerUnit) 370 | FSTRINGVAR(tEPRMaxFeedrate) 371 | FSTRINGVAR(tEPRStartFeedrate) 372 | FSTRINGVAR(tEPRAcceleration) 373 | FSTRINGVAR(tEPRHeatManager) 374 | FSTRINGVAR(tEPRDriveMax) 375 | FSTRINGVAR(tEPRDriveMin) 376 | FSTRINGVAR(tEPRPGain) 377 | FSTRINGVAR(tEPRDead) 378 | FSTRINGVAR(tEPRUnused) 379 | FSTRINGVAR(tEPRIGain) 380 | FSTRINGVAR(tEPRDGain) 381 | FSTRINGVAR(tEPRPIDMaxValue) 382 | FSTRINGVAR(tEPRXOffset) 383 | FSTRINGVAR(tEPRYOffset) 384 | FSTRINGVAR(tEPRZOffset) 385 | FSTRINGVAR(tEPRStabilizeTime) 386 | FSTRINGVAR(tEPRRetractionWhenHeating) 387 | FSTRINGVAR(tEPRDistanceRetractHeating) 388 | FSTRINGVAR(tEPRExtruderCoolerSpeed) 389 | FSTRINGVAR(tEPRAdvanceK) 390 | FSTRINGVAR(tEPRAdvanceL) 391 | #endif 392 | #if SDSUPPORT 393 | //FSTRINGVAR(tSDRemoved) 394 | //FSTRINGVAR(tSDInserted) 395 | FSTRINGVAR(tSDInitFail) 396 | FSTRINGVAR(tErrorWritingToFile) 397 | FSTRINGVAR(tBeginFileList) 398 | FSTRINGVAR(tEndFileList) 399 | FSTRINGVAR(tFileOpened) 400 | FSTRINGVAR(tSpaceSizeColon) 401 | FSTRINGVAR(tFileSelected) 402 | FSTRINGVAR(tFileOpenFailed) 403 | FSTRINGVAR(tSDPrintingByte) 404 | FSTRINGVAR(tNotSDPrinting) 405 | FSTRINGVAR(tOpenFailedFile) 406 | FSTRINGVAR(tWritingToFile) 407 | FSTRINGVAR(tDoneSavingFile) 408 | FSTRINGVAR(tFileDeleted) 409 | FSTRINGVAR(tDeletionFailed) 410 | FSTRINGVAR(tDirectoryCreated) 411 | FSTRINGVAR(tCreationFailed) 412 | FSTRINGVAR(tSDErrorCode) 413 | #endif // SDSUPPORT 414 | FSTRINGVAR(tHeaterDecoupled) 415 | FSTRINGVAR(tHeaterDecoupledWarning) 416 | #if DISTORTION_CORRECTION 417 | FSTRINGVAR(tZCorrectionEnabled) 418 | FSTRINGVAR(tZCorrectionDisabled) 419 | #endif 420 | #if FEATURE_RETRACTION 421 | FSTRINGVAR(tEPRAutoretractEnabled) 422 | FSTRINGVAR(tEPRRetractionLength) 423 | FSTRINGVAR(tEPRRetractionLongLength) 424 | FSTRINGVAR(tEPRRetractionSpeed) 425 | FSTRINGVAR(tEPRRetractionZLift) 426 | FSTRINGVAR(tEPRRetractionUndoExtraLength) 427 | FSTRINGVAR(tEPRRetractionUndoExtraLongLength) 428 | FSTRINGVAR(tEPRRetractionUndoSpeed) 429 | #endif 430 | FSTRINGVAR(tConfig) 431 | FSTRINGVAR(tExtrDot) 432 | 433 | #if STEPPER_CURRENT_CONTROL == CURRENT_CONTROL_MCP4728 434 | FSTRINGVAR(tMCPEpromSettings) 435 | FSTRINGVAR(tMCPCurrentSettings) 436 | #endif 437 | FSTRINGVAR(tPrinterModeFFF) 438 | FSTRINGVAR(tPrinterModeLaser) 439 | FSTRINGVAR(tPrinterModeCNC) 440 | #ifdef STARTUP_GCODE 441 | FSTRINGVAR(tStartupGCode) 442 | #endif 443 | #if NONLINEAR_SYSTEM 444 | FSTRINGVAR(tEPRSegmentsPerSecondPrint) 445 | FSTRINGVAR(tEPRSegmentsPerSecondTravel) 446 | #endif 447 | 448 | static void config(FSTRINGPARAM(text)); 449 | static void config(FSTRINGPARAM(text),int value); 450 | static void config(FSTRINGPARAM(text),const char *msg); 451 | static void config(FSTRINGPARAM(text),int32_t value); 452 | static void config(FSTRINGPARAM(text),uint32_t value); 453 | static void config(FSTRINGPARAM(text),float value,uint8_t digits=2); 454 | static void printNumber(uint32_t n); 455 | static void printWarningF(FSTRINGPARAM(text)); 456 | static void printInfoF(FSTRINGPARAM(text)); 457 | static void printErrorF(FSTRINGPARAM(text)); 458 | static void printWarningFLN(FSTRINGPARAM(text)); 459 | static void printInfoFLN(FSTRINGPARAM(text)); 460 | static void printErrorFLN(FSTRINGPARAM(text)); 461 | static void printFLN(FSTRINGPARAM(text)); 462 | static void printF(FSTRINGPARAM(text)); 463 | static void printF(FSTRINGPARAM(text),int value); 464 | static void printF(FSTRINGPARAM(text),const char *msg); 465 | static void printF(FSTRINGPARAM(text),int32_t value); 466 | static void printF(FSTRINGPARAM(text),uint32_t value); 467 | static void printF(FSTRINGPARAM(text),float value,uint8_t digits=2); 468 | static void printFLN(FSTRINGPARAM(text),int value); 469 | static void printFLN(FSTRINGPARAM(text),int32_t value); 470 | static void printFLN(FSTRINGPARAM(text),uint32_t value); 471 | static void printFLN(FSTRINGPARAM(text),const char *msg); 472 | static void printFLN(FSTRINGPARAM(text),float value,uint8_t digits=2); 473 | static void printArrayFLN(FSTRINGPARAM(text),float *arr,uint8_t n=4,uint8_t digits=2); 474 | static void printArrayFLN(FSTRINGPARAM(text),long *arr,uint8_t n=4); 475 | static void print(long value); 476 | static inline void print(uint32_t value) {printNumber(value);} 477 | static inline void print(int value) {print((int32_t)value);} 478 | static void print(const char *text); 479 | static inline void print(char c) {HAL::serialWriteByte(c);} 480 | static void printFloat(float number, uint8_t digits); 481 | static inline void print(float number) {printFloat(number, 6);} 482 | static inline void println() {HAL::serialWriteByte('\r');HAL::serialWriteByte('\n');} 483 | #if UI_DISPLAY_TYPE != NO_DISPLAY 484 | static const char* translatedF(int textId); 485 | static void selectLanguage(fast8_t lang); 486 | static uint8_t selectedLanguage; 487 | #endif 488 | protected: 489 | private: 490 | }; 491 | 492 | #ifdef DEBUG 493 | #define SHOW(x) {Com::printF(PSTR(" " #x "=")); Com::print(x); Com::println();} 494 | #define SHOWS(x) {Com::printF(PSTR(" " #x "=")); Com::print(x); Com::print(" steps "); Com::print(x/80); Com::printFLN(PSTR(" mm"));} 495 | #define SHOWM(x) {Com::printF(PSTR(" " #x "=")); Com::print((long)x*80); Com::print(" steps "); Com::print(x); Com::printFLN(PSTR(" mm"));} 496 | #define SHOT(x) Com::printF(PSTR(x " ")) 497 | #define SHOWA(t,a,n) {SHOT(t); for (int i=0;i. 19 | */ 20 | #ifndef FatStructs_h 21 | #define FatStructs_h 22 | /** 23 | * \file 24 | * FAT file structures 25 | */ 26 | /* 27 | * mostly from Microsoft document fatgen103.doc 28 | * http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx 29 | */ 30 | //------------------------------------------------------------------------------ 31 | /** Value for byte 510 of boot block or MBR */ 32 | uint8_t const BOOTSIG0 = 0X55; 33 | /** Value for byte 511 of boot block or MBR */ 34 | uint8_t const BOOTSIG1 = 0XAA; 35 | //------------------------------------------------------------------------------ 36 | /** 37 | * \struct partitionTable 38 | * \brief MBR partition table entry 39 | * 40 | * A partition table entry for a MBR formatted storage device. 41 | * The MBR partition table has four entries. 42 | */ 43 | struct partitionTable { 44 | /** 45 | * Boot Indicator . Indicates whether the volume is the active 46 | * partition. Legal values include: 0X00. Do not use for booting. 47 | * 0X80 Active partition. 48 | */ 49 | uint8_t boot; 50 | /** 51 | * Head part of Cylinder-head-sector address of the first block in 52 | * the partition. Legal values are 0-255. Only used in old PC BIOS. 53 | */ 54 | uint8_t beginHead; 55 | /** 56 | * Sector part of Cylinder-head-sector address of the first block in 57 | * the partition. Legal values are 1-63. Only used in old PC BIOS. 58 | */ 59 | unsigned beginSector : 6; 60 | /** High bits cylinder for first block in partition. */ 61 | unsigned beginCylinderHigh : 2; 62 | /** 63 | * Combine beginCylinderLow with beginCylinderHigh. Legal values 64 | * are 0-1023. Only used in old PC BIOS. 65 | */ 66 | uint8_t beginCylinderLow; 67 | /** 68 | * Partition type. See defines that begin with PART_TYPE_ for 69 | * some Microsoft partition types. 70 | */ 71 | uint8_t type; 72 | /** 73 | * head part of cylinder-head-sector address of the last sector in the 74 | * partition. Legal values are 0-255. Only used in old PC BIOS. 75 | */ 76 | uint8_t endHead; 77 | /** 78 | * Sector part of cylinder-head-sector address of the last sector in 79 | * the partition. Legal values are 1-63. Only used in old PC BIOS. 80 | */ 81 | unsigned endSector : 6; 82 | /** High bits of end cylinder */ 83 | unsigned endCylinderHigh : 2; 84 | /** 85 | * Combine endCylinderLow with endCylinderHigh. Legal values 86 | * are 0-1023. Only used in old PC BIOS. 87 | */ 88 | uint8_t endCylinderLow; 89 | /** Logical block address of the first block in the partition. */ 90 | uint32_t firstSector; 91 | /** Length of the partition, in blocks. */ 92 | uint32_t totalSectors; 93 | }; 94 | /** Type name for partitionTable */ 95 | typedef struct partitionTable part_t; 96 | //------------------------------------------------------------------------------ 97 | /** 98 | * \struct masterBootRecord 99 | * 100 | * \brief Master Boot Record 101 | * 102 | * The first block of a storage device that is formatted with a MBR. 103 | */ 104 | struct masterBootRecord { 105 | /** Code Area for master boot program. */ 106 | uint8_t codeArea[440]; 107 | /** Optional WindowsNT disk signature. May contain more boot code. */ 108 | uint32_t diskSignature; 109 | /** Usually zero but may be more boot code. */ 110 | uint16_t usuallyZero; 111 | /** Partition tables. */ 112 | part_t part[4]; 113 | /** First MBR signature byte. Must be 0X55 */ 114 | uint8_t mbrSig0; 115 | /** Second MBR signature byte. Must be 0XAA */ 116 | uint8_t mbrSig1; 117 | }; 118 | /** Type name for masterBootRecord */ 119 | typedef struct masterBootRecord mbr_t; 120 | //------------------------------------------------------------------------------ 121 | /** 122 | * \struct biosParmBlock 123 | * 124 | * \brief BIOS parameter block 125 | * 126 | * The BIOS parameter block describes the physical layout of a FAT volume. 127 | */ 128 | struct biosParmBlock { 129 | /** 130 | * Count of bytes per sector. This value may take on only the 131 | * following values: 512, 1024, 2048 or 4096 132 | */ 133 | uint16_t bytesPerSector; 134 | /** 135 | * Number of sectors per allocation unit. This value must be a 136 | * power of 2 that is greater than 0. The legal values are 137 | * 1, 2, 4, 8, 16, 32, 64, and 128. 138 | */ 139 | uint8_t sectorsPerCluster; 140 | /** 141 | * Number of sectors before the first FAT. 142 | * This value must not be zero. 143 | */ 144 | uint16_t reservedSectorCount; 145 | /** The count of FAT data structures on the volume. This field should 146 | * always contain the value 2 for any FAT volume of any type. 147 | */ 148 | uint8_t fatCount; 149 | /** 150 | * For FAT12 and FAT16 volumes, this field contains the count of 151 | * 32-byte directory entries in the root directory. For FAT32 volumes, 152 | * this field must be set to 0. For FAT12 and FAT16 volumes, this 153 | * value should always specify a count that when multiplied by 32 154 | * results in a multiple of bytesPerSector. FAT16 volumes should 155 | * use the value 512. 156 | */ 157 | uint16_t rootDirEntryCount; 158 | /** 159 | * This field is the old 16-bit total count of sectors on the volume. 160 | * This count includes the count of all sectors in all four regions 161 | * of the volume. This field can be 0; if it is 0, then totalSectors32 162 | * must be non-zero. For FAT32 volumes, this field must be 0. For 163 | * FAT12 and FAT16 volumes, this field contains the sector count, and 164 | * totalSectors32 is 0 if the total sector count fits 165 | * (is less than 0x10000). 166 | */ 167 | uint16_t totalSectors16; 168 | /** 169 | * This dates back to the old MS-DOS 1.x media determination and is 170 | * no longer usually used for anything. 0xF8 is the standard value 171 | * for fixed (non-removable) media. For removable media, 0xF0 is 172 | * frequently used. Legal values are 0xF0 or 0xF8-0xFF. 173 | */ 174 | uint8_t mediaType; 175 | /** 176 | * Count of sectors occupied by one FAT on FAT12/FAT16 volumes. 177 | * On FAT32 volumes this field must be 0, and sectorsPerFat32 178 | * contains the FAT size count. 179 | */ 180 | uint16_t sectorsPerFat16; 181 | /** Sectors per track for interrupt 0x13. Not used otherwise. */ 182 | uint16_t sectorsPerTrtack; 183 | /** Number of heads for interrupt 0x13. Not used otherwise. */ 184 | uint16_t headCount; 185 | /** 186 | * Count of hidden sectors preceding the partition that contains this 187 | * FAT volume. This field is generally only relevant for media 188 | * visible on interrupt 0x13. 189 | */ 190 | uint32_t hidddenSectors; 191 | /** 192 | * This field is the new 32-bit total count of sectors on the volume. 193 | * This count includes the count of all sectors in all four regions 194 | * of the volume. This field can be 0; if it is 0, then 195 | * totalSectors16 must be non-zero. 196 | */ 197 | uint32_t totalSectors32; 198 | /** 199 | * Count of sectors occupied by one FAT on FAT32 volumes. 200 | */ 201 | uint32_t sectorsPerFat32; 202 | /** 203 | * This field is only defined for FAT32 media and does not exist on 204 | * FAT12 and FAT16 media. 205 | * Bits 0-3 -- Zero-based number of active FAT. 206 | * Only valid if mirroring is disabled. 207 | * Bits 4-6 -- Reserved. 208 | * Bit 7 -- 0 means the FAT is mirrored at runtime into all FATs. 209 | * -- 1 means only one FAT is active; it is the one referenced in bits 0-3. 210 | * Bits 8-15 -- Reserved. 211 | */ 212 | uint16_t fat32Flags; 213 | /** 214 | * FAT32 version. High byte is major revision number. 215 | * Low byte is minor revision number. Only 0.0 define. 216 | */ 217 | uint16_t fat32Version; 218 | /** 219 | * Cluster number of the first cluster of the root directory for FAT32. 220 | * This usually 2 but not required to be 2. 221 | */ 222 | uint32_t fat32RootCluster; 223 | /** 224 | * Sector number of FSINFO structure in the reserved area of the 225 | * FAT32 volume. Usually 1. 226 | */ 227 | uint16_t fat32FSInfo; 228 | /** 229 | * If non-zero, indicates the sector number in the reserved area 230 | * of the volume of a copy of the boot record. Usually 6. 231 | * No value other than 6 is recommended. 232 | */ 233 | uint16_t fat32BackBootBlock; 234 | /** 235 | * Reserved for future expansion. Code that formats FAT32 volumes 236 | * should always set all of the bytes of this field to 0. 237 | */ 238 | uint8_t fat32Reserved[12]; 239 | }; 240 | /** Type name for biosParmBlock */ 241 | typedef struct biosParmBlock bpb_t; 242 | //------------------------------------------------------------------------------ 243 | /** 244 | * \struct fat32BootSector 245 | * 246 | * \brief Boot sector for a FAT16 or FAT32 volume. 247 | * 248 | */ 249 | struct fat32BootSector { 250 | /** X86 jmp to boot program */ 251 | uint8_t jmpToBootCode[3]; 252 | /** informational only - don't depend on it */ 253 | char oemName[8]; 254 | /** BIOS Parameter Block */ 255 | bpb_t bpb; 256 | /** for int0x13 use value 0X80 for hard drive */ 257 | uint8_t driveNumber; 258 | /** used by Windows NT - should be zero for FAT */ 259 | uint8_t reserved1; 260 | /** 0X29 if next three fields are valid */ 261 | uint8_t bootSignature; 262 | /** usually generated by combining date and time */ 263 | uint32_t volumeSerialNumber; 264 | /** should match volume label in root dir */ 265 | char volumeLabel[11]; 266 | /** informational only - don't depend on it */ 267 | char fileSystemType[8]; 268 | /** X86 boot code */ 269 | uint8_t bootCode[420]; 270 | /** must be 0X55 */ 271 | uint8_t bootSectorSig0; 272 | /** must be 0XAA */ 273 | uint8_t bootSectorSig1; 274 | }; 275 | //------------------------------------------------------------------------------ 276 | // End Of Chain values for FAT entries 277 | /** FAT16 end of chain value used by Microsoft. */ 278 | uint16_t const FAT16EOC = 0XFFFF; 279 | /** Minimum value for FAT16 EOC. Use to test for EOC. */ 280 | uint16_t const FAT16EOC_MIN = 0XFFF8; 281 | /** FAT32 end of chain value used by Microsoft. */ 282 | uint32_t const FAT32EOC = 0X0FFFFFFF; 283 | /** Minimum value for FAT32 EOC. Use to test for EOC. */ 284 | uint32_t const FAT32EOC_MIN = 0X0FFFFFF8; 285 | /** Mask a for FAT32 entry. Entries are 28 bits. */ 286 | uint32_t const FAT32MASK = 0X0FFFFFFF; 287 | 288 | /** Type name for fat32BootSector */ 289 | typedef struct fat32BootSector fbs_t; 290 | //------------------------------------------------------------------------------ 291 | /** 292 | * \struct directoryEntry 293 | * \brief FAT short directory entry 294 | * 295 | * Short means short 8.3 name, not the entry size. 296 | * 297 | * Date Format. A FAT directory entry date stamp is a 16-bit field that is 298 | * basically a date relative to the MS-DOS epoch of 01/01/1980. Here is the 299 | * format (bit 0 is the LSB of the 16-bit word, bit 15 is the MSB of the 300 | * 16-bit word): 301 | * 302 | * Bits 9-15: Count of years from 1980, valid value range 0-127 303 | * inclusive (1980-2107). 304 | * 305 | * Bits 5-8: Month of year, 1 = January, valid value range 1-12 inclusive. 306 | * 307 | * Bits 0-4: Day of month, valid value range 1-31 inclusive. 308 | * 309 | * Time Format. A FAT directory entry time stamp is a 16-bit field that has 310 | * a granularity of 2 seconds. Here is the format (bit 0 is the LSB of the 311 | * 16-bit word, bit 15 is the MSB of the 16-bit word). 312 | * 313 | * Bits 11-15: Hours, valid value range 0-23 inclusive. 314 | * 315 | * Bits 5-10: Minutes, valid value range 0-59 inclusive. 316 | * 317 | * Bits 0-4: 2-second count, valid value range 0-29 inclusive (0 - 58 seconds). 318 | * 319 | * The valid time range is from Midnight 00:00:00 to 23:59:58. 320 | */ 321 | struct directoryEntry { 322 | /** 323 | * Short 8.3 name. 324 | * The first eight bytes contain the file name with blank fill. 325 | * The last three bytes contain the file extension with blank fill. 326 | */ 327 | uint8_t name[11]; 328 | /** Entry attributes. 329 | * 330 | * The upper two bits of the attribute byte are reserved and should 331 | * always be set to 0 when a file is created and never modified or 332 | * looked at after that. See defines that begin with DIR_ATT_. 333 | */ 334 | uint8_t attributes; 335 | /** 336 | * Reserved for use by Windows NT. Set value to 0 when a file is 337 | * created and never modify or look at it after that. 338 | */ 339 | uint8_t reservedNT; 340 | /** 341 | * The granularity of the seconds part of creationTime is 2 seconds 342 | * so this field is a count of tenths of a second and its valid 343 | * value range is 0-199 inclusive. (WHG note - seems to be hundredths) 344 | */ 345 | uint8_t creationTimeTenths; 346 | /** Time file was created. */ 347 | uint16_t creationTime; 348 | /** Date file was created. */ 349 | uint16_t creationDate; 350 | /** 351 | * Last access date. Note that there is no last access time, only 352 | * a date. This is the date of last read or write. In the case of 353 | * a write, this should be set to the same date as lastWriteDate. 354 | */ 355 | uint16_t lastAccessDate; 356 | /** 357 | * High word of this entry's first cluster number (always 0 for a 358 | * FAT12 or FAT16 volume). 359 | */ 360 | uint16_t firstClusterHigh; 361 | /** Time of last write. File creation is considered a write. */ 362 | uint16_t lastWriteTime; 363 | /** Date of last write. File creation is considered a write. */ 364 | uint16_t lastWriteDate; 365 | /** Low word of this entry's first cluster number. */ 366 | uint16_t firstClusterLow; 367 | /** 32-bit unsigned holding this file's size in bytes. */ 368 | uint32_t fileSize; 369 | }; 370 | //------------------------------------------------------------------------------ 371 | // Definitions for directory entries 372 | // 373 | /** Type name for directoryEntry */ 374 | typedef struct directoryEntry dir_t; 375 | /** escape for name[0] = 0XE5 */ 376 | uint8_t const DIR_NAME_0XE5 = 0X05; 377 | /** name[0] value for entry that is free after being "deleted" */ 378 | uint8_t const DIR_NAME_DELETED = 0XE5; 379 | /** name[0] value for entry that is free and no allocated entries follow */ 380 | uint8_t const DIR_NAME_FREE = 0X00; 381 | /** file is read-only */ 382 | uint8_t const DIR_ATT_READ_ONLY = 0X01; 383 | /** File should hidden in directory listings */ 384 | uint8_t const DIR_ATT_HIDDEN = 0X02; 385 | /** Entry is for a system file */ 386 | uint8_t const DIR_ATT_SYSTEM = 0X04; 387 | /** Directory entry contains the volume label */ 388 | uint8_t const DIR_ATT_VOLUME_ID = 0X08; 389 | /** Entry is for a directory */ 390 | uint8_t const DIR_ATT_DIRECTORY = 0X10; 391 | /** Old DOS archive bit for backup support */ 392 | uint8_t const DIR_ATT_ARCHIVE = 0X20; 393 | /** Test value for long name entry. Test is 394 | (d->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME. */ 395 | uint8_t const DIR_ATT_LONG_NAME = 0X0F; 396 | /** Test mask for long name entry */ 397 | uint8_t const DIR_ATT_LONG_NAME_MASK = 0X3F; 398 | /** defined attribute bits */ 399 | uint8_t const DIR_ATT_DEFINED_BITS = 0X3F; 400 | /** Directory entry is part of a long name */ 401 | static inline uint8_t DIR_IS_LONG_NAME(const dir_t* dir) { 402 | return (dir->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME; 403 | } 404 | /** Mask for file/subdirectory tests */ 405 | uint8_t const DIR_ATT_FILE_TYPE_MASK = (DIR_ATT_VOLUME_ID | DIR_ATT_DIRECTORY); 406 | /** Directory entry is for a file */ 407 | static inline uint8_t DIR_IS_FILE(const dir_t* dir) { 408 | return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == 0; 409 | } 410 | /** Directory entry is for a subdirectory */ 411 | static inline uint8_t DIR_IS_SUBDIR(const dir_t* dir) { 412 | return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == DIR_ATT_DIRECTORY; 413 | } 414 | /** Directory entry is for a file or subdirectory */ 415 | static inline uint8_t DIR_IS_FILE_OR_SUBDIR(const dir_t* dir) { 416 | return (dir->attributes & DIR_ATT_VOLUME_ID) == 0; 417 | } 418 | #endif // FatStructs_h 419 | -------------------------------------------------------------------------------- /Wangsamas/Wangsamas.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Berkas ini adalah bagian dari Wangsamas-Firmware oleh Kusuma Ruslan. 3 | 4 | Wangsamas-Firmware adalah perangkat lunak bebas: 5 | Anda dapat mendistribusikannya dan/atau mengubahnya 6 | dengan syarat dan ketentuan GNU General Public License 7 | yang dipublikasikan oleh Free Software Foundation, 8 | baik ijin versi 3, atau (menurut pilihanmu) versi yang terbaru. 9 | 10 | Wangsamas-Firmware didistribusikan dengan harapan agar dapat bermanfaat, 11 | tetapi TANPA JAMINAN; bahkan tanpa jaminan tersirat PERDAGANGAN atau 12 | KECOCOKAN UNTUK TUJUAN TERTENTU. Lihat GNU General Public License 13 | untuk keterangan lebih lanjut. 14 | 15 | Anda seharusnya sudah menerima salinan GNU General Public License bersamaan 16 | dengan Wangsamas-Firmware. Jika tidak, lihat . 17 | 18 | Firmware ini berdasarkan Repetier-Firmware yang berdasarkan Sprinter firmware 19 | yang berdasarkan Tonokip Reprap firmware yang berdasarkan Hydra-mmm firmware. 20 | 21 | Lihat di sini untuk keterangan gcode: http://linuxcnc.org/handbook/gcode/g-code.html 22 | dan http://objects.reprap.org/wiki/Mendel_User_Manual:_RepRapGCodes 23 | 24 | code yang diterapkan 25 | bagian GCodes 26 | 27 | - G0 -> G1 28 | - G1 - Pergerakan koordinat X Y Z E, S1 meniadakan pemeriksaan batasan, S0 mengadakannya 29 | - G4 - Berdiam S atau P 30 | - G5 - Pergerakan putar X (Bahu), Y (Siku) untuk SCARA 31 | - G10 S<1 = Tarikan panjang, 0 = tarikan pendek = bawaan> menarik filamen menurut pengaturan yang tersimpan 32 | - G11 S<1 = Tarikan panjang, 0 = tarikan pendek = bawaan> membalikan tarikan filamen menurut pengaturan yang tersimpan 33 | - G20 - Units untuk G0/G1 adalah inci. 34 | - G21 - Units untuk G0/G1 adalah mm. 35 | - G28 - Semua sumbu atau yang disebut kembali ke awalan. 36 | - G29 S<0..2> - Periksa-Z pada 3 titik pemeriksaan yang ditetapkan. S = 1 ukur rata2 tinggi Z, S = 2 simpan rat2 tinggi Z 37 | - G30 P<0..3> - Periksa-Z pada titik yang sedang berlangsung. P = 1 pengukuran pertama, P = 2 pengukuran terakhir P = 0 atau 3 pengukuran pertama dan terakhir 38 | - G31 - Tulis signal pada sensor periksa 39 | - G32 S<0..2> P<0..1> - Autolevel papan cetak. S = 1 ukur tinggi Z, S = 2 ukur dan simpan tinggi Z baru 40 | - G50 Rute kalibrasi SCARA 41 | - G90 - Gunakan koordinat pasti 42 | - G91 - Gunakan koordinat relatif 43 | - G92 - Tetapkan posisi sekarang ke koordinat yang diberikan 44 | - G131 - Tetapkan posisi offset extruder ke 0 - dibutuhkan untuk kalibrasi dengan G132 45 | - G132 - Kalibrasi posisi endstop. Gunakan ini setelah gunakan G131 dan setelah tempatkan dudukan extruder ke titik tengah. 46 | - G133 - Ukur langkah menuju endstop untuk delta. Dapat digunakan untuk mendeteksi langkah yang hilang dalam toleransi endstop. 47 | - G134 Px Sx Zx - Kalibrasi perbedaan tinggi nozzle (butuh Periksa-Z dalam nozzle!) Px = extruder referensi, Sx = hanya ukur extruder x terhadap referensi, Zx = menambahkan jarak z yang diukur Sx untuk koreksi. 48 | 49 | bagian M code 50 | - M104 - Tetapkan target suhu extruder 51 | - M105 - Baca suhu sekarang 52 | - M106 S P - Kipas pada kecepatan = 0..255, P = 0 atau 1, 0 adalah bawaan dan dapat diabaikan 53 | - M107 P - Kipas mati, P = 0 atau 1, 0 adalah bawaan dan dapat diabaikan 54 | - M109 - Tunggu suhu extruder mencapat suhu target. 55 | - M114 - Perlihatkan posisi sekarang 56 | 57 | M Code khusus 58 | 59 | - M20 - Daftar kartu SD 60 | - M21 - Mulai kartu SD 61 | - M22 - Lepas kartu SD 62 | - M23 - Pilih berkas SD (M23 namaberkas.g) 63 | - M24 - Mulai/lanjutkan cetak SD 64 | - M25 - Tunda cetak SD 65 | - M26 - Tetapkan posisi SD dalam bytes (M26 S12345) 66 | - M27 - Laporkan status cetak SD 67 | - M28 - Mulai tulis SD (M28 namaberkas.g) 68 | - M29 - Hentikan tulis SD 69 | - M30 - Hapus berkas pada kartu SD 70 | - M32 buat subdaftar 71 | - M42 P S - Ganti keluaran pin P ke S. tidak bekerja pada pin yang penting. 72 | - M80 - Nyalakan sumber listrik 73 | - M81 - Matikan sumber listrik 74 | - M82 - Tetapkan kode E pasti (bawaan) 75 | - M83 - Tetapkan kode E relatif pada waktu dalam mode koordinat absolut(G90) 76 | - M84 - Matikan motor hingga langkah berikutnya, 77 | atau gunakan S untuk tentukan waktu tidak aktif setelah motor dimatikan. S0 untuk menghentikan waktu. 78 | - M85 - Tetapkan waktu matikan ketika tidak ada aktifitas dengan parameter S. Untuk mengentikan tetapkan nol (bawaan) 79 | - M92 - Tetapkan axisStepsPerUnit - sama seperti G92 80 | - M99 S X0 Y0 Z0 - Matikan motor untuk S detik (bawaan 10) untuk sumbu yang diberikan. 81 | - M104 S T P1 F1 - Tetapkan suhu tanpa tunggu. P1 = tunggu sampai gerakan berakhir, F1 = bunyi beep ketika suhu mencapai pertama kalinya 82 | - M105 X0 - Dapatkan suhu. Jika X0 ditambahkan, nilai mentah analog juga ditulis. 83 | - M112 - Matikan darurat 84 | - M115- Deret kemampuan 85 | - M116 - Tunggu sampai semua suhu dalam batasan +/- 1 derajat 86 | - M117 - Tulis pesan dalam baris status pada LCD 87 | - M119 - Laporkan status endstop 88 | - M140 S F1 - Tetapkan suhu target papan, F1 bunyi beep ketika suhu mencapai pertama kalinya 89 | - M163 S P - Tetapkan berat untuk mencampur extruder drive 90 | - M164 S P<0 = jangan simpan eeprom,1 = simpan ke eeprom> - simpan berat sebagai extruder bayangan S 91 | - M190 - Tunggu sampai suhu papan sekarang mencapai suhu target 92 | - M200 T D - Gunakan pengeluaran berbasis volume. Tetapkan D0 atau abaikan D untuk hentikan pengeluaran berbasis volume. Abaikan T untuk extruder sekarang. 93 | - M201 - Tetapkan percepatan max dalam unit/s^2 untuk gerakan cetak (M201 X1000 Y1000) 94 | - M202 - Tetapkan percepatan max dalam unit/s^2 untuk gerakan pindah (M202 X1000 Y1000) 95 | - M203 - Tetapkan pantauan suhu ke Sx 96 | - M204 - Tetapkan parameter PID X => Kp Y => Ki Z => Kd S Bawaan adalah extruder sekarang. NUM_EXTRUDER=Pemanas papan 97 | - M205 - Keluaran pengaturan EEPROM 98 | - M206 - Tetapkan nilai EEPROM 99 | - M207 X Z E - Ubah nilai kedutan sekarang, tetapi tidak simpan di eeprom. 100 | - M209 S<0/1> - Nyalakan/matikan tarikan otomatis 101 | - M220 S - Naikan/turunkan kecepatan yang diberikan 102 | - M221 S - Naikan/turunkan arus yang diberikan 103 | - M226 P S - Tuunggu sampai pin mendapat status S. Tambah X0 untuk mulai sebagai masukan tanpa menarik dan X1 untuk masukan dengan menarik. 104 | - M231 S X Y Z F - Tetapkan parameter OPS 105 | - M232 - Baca dan ulangi nilai max lanjutan 106 | - M233 X Y - Tetapkan nilai K lanjutan sementara ke X dan nilai L ke Y 107 | - M251 Ukur langkah Z dari perhentian awal (Delta printers). S0 - Ulangi, S1 - Cetak, S2 - Simpan ke panjang Z (juga EEPROM jika dinyalakan) 108 | - M280 S - Tetapkan mode cetak salinan. mode: 0 = mati, 1 = 1 extra extruder, 2 = 2 extra extruder, 3 = 3 extra extruders 109 | - M281 Tes apakah watchdog berjalan dan bekerja. Gunakan M281 X0 untuk hentikan watchdog pada papan AVR. Terkadang dibutuhkan untuk papan dengan bootloaders lama untuk dapat digunakan kembali. 110 | - M300 S P mainkan frekuensi 111 | - M302 S<0 atau 1> - perbolehkan pengeluaran dingin. Tanpa parameter S akan diperbolehkan. S1 untuk dilarang. 112 | - M303 P S X0 R- temukan otomatis nilai pid. Gunakan P untuk pemanas papan. X0 simpan hasil di EEPROM. R adalah jumlah siklus. 113 | - M320 S<0/1> - Nyalakan autolevel, S1 simpan dalam eeprom 114 | - M321 S<0/1> - Matikan autolevel, S1 simpan dalam eeprom 115 | - M322 - Ulangi matrix autolevel 116 | - M323 S0/S1 nyalakan matikan koreksi penyimpangan P0 = tidak permanen, P1 = permanen = bawaan 117 | - M340 P S R: servoID = 0..3, Servos dikendalikan dengan getaran normalnya antara 500 dan 2500 dengan 1500ms dalam posisi tengah. 0 matikan servo. R membolehkan mematikan otomatis setelah beberapa saat. 118 | - M350 S X Y Z E P : tetapkan microstepping pada RAMBO board 119 | - M355 S<0/1> - Nyalakan/matikan lampu, tidak ada S = laporkan status 120 | - M360 - perlihatkan konfigurasi 121 | - M400 - Tunggu sampai antrian gerakan kosong. 122 | - M401 - Simpan posisi x, y dan z. 123 | - M402 - Pindah ke posisi yang disimpan. Jika X, Y atau Z ditentukan, hanya koordinat ini yang dipakai. F mengubah kecepatan pada gerakan itu. 124 | - M450 - Laporkan mode cetak 125 | - M451 - Tetapkan mode cetak ke FFF 126 | - M452 - Tetapkan mode cetak ke laser 127 | - M453 - Tetapkan mode cetak ke CNC 128 | - M460 X Y : Tetapkan bentangan suhu agar thermistor mengendalikan kipas 129 | - M500 Simpan pengaturan ke EEPROM 130 | - M501 Ambil pengaturan dari EEPROM 131 | - M502 Ulangi pengaturan ke yang ada di configuration.h. Tidak simipan nilai ke EEPROM! 132 | - M513 - Bersihkan semua tanda macet. 133 | - M600 Ganti filamen 134 | - M601 S<1/0> - Tunda extruder. extrude yang ditunda mematikan pemanas dan motor. Membatalkan tunda memanaskan kembali extruder ke suhu yang lama. 135 | - M602 S<1/0> P<1/0>- Debug kontrol macet (S) mematikan kontrol macet (P). Jika dinyalakan akan mencatat perubahan signal dan tidak akan memicu kesalahan macet! 136 | - M908 P S : Tetaokan arus listrik motor untuk digipot (RAMBO board) 137 | - M999 - Lanjutkan dari kesalahan fatal. M999 S1 akan membuat kesalahan fatal untuk pencobaan. 138 | 139 | --------------------- 140 | 141 | This file is part of Wangsamas-Firmware by Kusuma Ruslan. 142 | 143 | Wangsamas-Firmware is free software: you can redistribute it and/or modify 144 | it under the terms of the GNU General Public License as published by 145 | the Free Software Foundation, either version 3 of the License, or 146 | (at your option) any later version. 147 | 148 | Wangsamas-Firmware is distributed in the hope that it will be useful, 149 | but WITHOUT ANY WARRANTY; without even the implied warranty of 150 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 151 | GNU General Public License for more details. 152 | 153 | You should have received a copy of the GNU General Public License 154 | along with Wangsamas-Firmware. If not, see . 155 | 156 | This firmware is based on Repetier-Firmware which based on Sprinter firmware 157 | which based on Tonokip RepRap firmware which based on Hydra-mmm firmware. 158 | 159 | section GCodes 160 | 161 | look here for descriptions of gcodes: http://linuxcnc.org/handbook/gcode/g-code.html 162 | and http://objects.reprap.org/wiki/Mendel_User_Manual:_RepRapGCodes 163 | 164 | Implemented Codes 165 | 166 | - G0 -> G1 167 | - G1 - Coordinated Movement X Y Z E, S1 disables boundary check, S0 enables it 168 | - G4 - Dwell S or P 169 | - G5 - Rotation Movement X (Shoulder), Y (Elbow) 170 | - G10 S<1 = long retract, 0 = short retract = default> retracts filament according to stored setting 171 | - G11 S<1 = long retract, 0 = short retract = default> = Undo retraction according to stored setting 172 | - G20 - Units for G0/G1 are inches. 173 | - G21 - Units for G0/G1 are mm. 174 | - G28 - Home all axis or named axis. 175 | - G29 S<0..2> - Z-Probe at the 3 defined probe points. S = 1 measure avg. zHeight, S = 2 store avg zHeight 176 | - G30 P<0..3> - Single z-probe at current position P = 1 first measurement, P = 2 Last measurement P = 0 or 3 first and last measurement 177 | - G31 - Write signal of probe sensor 178 | - G32 S<0..2> P<0..1> - Autolevel print bed. S = 1 measure zLength, S = 2 Measure and store new zLength 179 | - G50 SCARA calibration route 180 | - G90 - Use absolute coordinates 181 | - G91 - Use relative coordinates 182 | - G92 - Set current position to coordinates given 183 | - G131 - set extruder offset position to 0 - needed for calibration with G132 184 | - G132 - calibrate endstop positions. Call this, after calling G131 and after centering the extruder holder. 185 | - G133 - measure steps until max endstops for deltas. Can be used to detect lost steps within tolerances of endstops. 186 | - G134 Px Sx Zx - Calibrate nozzle height difference (need z probe in nozzle!) Px = reference extruder, Sx = only measure extrude x against reference, Zx = add to measured z distance for Sx for correction. 187 | 188 | RepRap M Codes 189 | 190 | - M104 - Set extruder target temp 191 | - M105 - Read current temp 192 | - M106 S P - Fan on speed = 0..255, P = 0 or 1, 0 is default and can be omitted 193 | - M107 P - Fan off, P = 0 or 1, 0 is default and can be omitted 194 | - M109 - Wait for extruder current temp to reach target temp. 195 | - M114 - Display current position 196 | 197 | Custom M Codes 198 | 199 | - M20 - List SD card 200 | - M21 - Init SD card 201 | - M22 - Release SD card 202 | - M23 - Select SD file (M23 filename.g) 203 | - M24 - Start/resume SD print 204 | - M25 - Pause SD print 205 | - M26 - Set SD position in bytes (M26 S12345) 206 | - M27 - Report SD print status 207 | - M28 - Start SD write (M28 filename.g) 208 | - M29 - Stop SD write 209 | - M30 - Delete file on sd card 210 | - M32 create subdirectory 211 | - M42 P S - Change output of pin P to S. Does not work on most important pins. 212 | - M80 - Turn on power supply 213 | - M81 - Turn off power supply 214 | - M82 - Set E codes absolute (default) 215 | - M83 - Set E codes relative while in Absolute Coordinates (G90) mode 216 | - M84 - Disable steppers until next move, 217 | or use S to specify an inactivity timeout, after which the steppers will be disabled. S0 to disable the timeout. 218 | - M85 - Set inactivity shutdown timer with parameter S. To disable set zero (default) 219 | - M92 - Set axisStepsPerUnit - same syntax as G92 220 | - M99 S X0 Y0 Z0 - Disable motors for S seconds (default 10) for given axis. 221 | - M104 S T P1 F1 - Set temperature without wait. P1 = wait for moves to finish, F1 = beep when temp. reached first time 222 | - M105 X0 - Get temperatures. If X0 is added, the raw analog values are also written. 223 | - M112 - Emergency kill 224 | - M115- Capabilities string 225 | - M116 - Wait for all temperatures in a +/- 1 degree range 226 | - M117 - Write message in status row on lcd 227 | - M119 - Report endstop status 228 | - M140 S F1 - Set bed target temp, F1 makes a beep when temperature is reached the first time 229 | - M163 S P - Set weight for this mixing extruder drive 230 | - M164 S P<0 = dont store eeprom,1 = store to eeprom> - Store weights as virtual extruder S 231 | - M190 - Wait for bed current temp to reach target temp. 232 | - M200 T D - Use volumetric extrusion. Set D0 or omit D to disable volumetric extr. Omit T for current extruder. 233 | - M201 - Set max acceleration in units/s^2 for print moves (M201 X1000 Y1000) 234 | - M202 - Set max acceleration in units/s^2 for travel moves (M202 X1000 Y1000) 235 | - M203 - Set temperture monitor to Sx 236 | - M204 - Set PID parameter X => Kp Y => Ki Z => Kd S Default is current extruder. NUM_EXTRUDER=Heated bed 237 | - M205 - Output EEPROM settings 238 | - M206 - Set EEPROM value 239 | - M207 X Z E - Changes current jerk values, but do not store them in eeprom. 240 | - M209 S<0/1> - Enable/disable autoretraction 241 | - M220 S - Increase/decrease given feedrate 242 | - M221 S - Increase/decrease given flow rate 243 | - M226 P S - Wait for pin getting state S. Add X0 to init as input without pullup and X1 for input with pullup. 244 | - M231 S X Y Z F - Set OPS parameter 245 | - M232 - Read and reset max. advance values 246 | - M233 X Y - Set temporary advance K-value to X and linear term advanceL to Y 247 | - M251 Measure Z steps from homing stop (Delta printers). S0 - Reset, S1 - Print, S2 - Store to Z length (also EEPROM if enabled) 248 | - M280 S - Set ditto printing mode. mode: 0 = off, 1 = 1 extra extruder, 2 = 2 extra extruder, 3 = 3 extra extruders 249 | - M281 Test if watchdog is running and working. Use M281 X0 to disable watchdog on AVR boards. Sometimes needed for boards with old bootloaders to allow reflashing. 250 | - M300 S P play frequency 251 | - M302 S<0 or 1> - allow cold extrusion. Without S parameter it will allow. S1 will disallow. 252 | - M303 P S X0 R- Autodetect pid values. Use P for heated bed. X0 saves result in EEPROM. R is number of cycles. 253 | - M320 S<0/1> - Activate autolevel, S1 stores it in eeprom 254 | - M321 S<0/1> - Deactivate autolevel, S1 stores it in eeprom 255 | - M322 - Reset autolevel matrix 256 | - M323 S0/S1 enable disable distortion correction P0 = not permanent, P1 = permanent = default 257 | - M340 P S R: servoID = 0..3, Servos are controlled by a pulse with normally between 500 and 2500 with 1500ms in center position. 0 turns servo off. R allows automatic disabling after a while. 258 | - M350 S X Y Z E P : Set microstepping on RAMBO board 259 | - M355 S<0/1> - Turn case light on/off, no S = report status 260 | - M360 - show configuration 261 | - M400 - Wait until move buffers empty. 262 | - M401 - Store x, y and z position. 263 | - M402 - Go to stored position. If X, Y or Z is specified, only these coordinates are used. F changes feedrate fo rthat move. 264 | - M450 - Reports printer mode 265 | - M451 - Set printer mode to FFF 266 | - M452 - Set printer mode to laser 267 | - M453 - Set printer mode to CNC 268 | - M460 X Y : Set temperature range for thermistor controlled fan 269 | - M500 Store settings to EEPROM 270 | - M501 Load settings from EEPROM 271 | - M502 Reset settings to the one in configuration.h. Does not store values in EEPROM! 272 | - M513 - Clear all jam marker. 273 | - M600 Change filament 274 | - M601 S<1/0> - Pause extruders. Paused extrudes disable heaters and motor. Unpausing reheats extruder to old temp. 275 | - M602 S<1/0> P<1/0>- Debug jam control (S) Disable jam control (P). If enabled it will log signal changes and will not trigger jam errors! 276 | - M908 P
S : Set stepper current for digipot (RAMBO board) 277 | - M999 - Continue from fatal error. M999 S1 will create a fatal error for testing. 278 | */ 279 | 280 | #include "Wangsamas.h" 281 | #include 282 | 283 | #if UI_DISPLAY_TYPE == DISPLAY_ARDUINO_LIB 284 | //#include // Uncomment this if you are using liquid crystal library 285 | #endif 286 | 287 | void setup() 288 | { 289 | Printer::setup(); 290 | } 291 | 292 | void loop() 293 | { 294 | Commands::commandLoop(); 295 | } 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | -------------------------------------------------------------------------------- /Wangsamas/SDCard.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Berkas ini adalah bagian dari Wangsamas-Firmware oleh Kusuma Ruslan. 3 | 4 | Wangsamas-Firmware adalah perangkat lunak bebas: 5 | Anda dapat mendistribusikannya dan/atau mengubahnya 6 | dengan syarat dan ketentuan GNU General Public License 7 | yang dipublikasikan oleh Free Software Foundation, 8 | baik ijin versi 3, atau (menurut pilihanmu) versi yang terbaru. 9 | 10 | Wangsamas-Firmware didistribusikan dengan harapan agar dapat bermanfaat, 11 | tetapi TANPA JAMINAN; bahkan tanpa jaminan tersirat PERDAGANGAN atau 12 | KECOCOKAN UNTUK TUJUAN TERTENTU. Lihat GNU General Public License 13 | untuk keterangan lebih lanjut. 14 | 15 | Anda seharusnya sudah menerima salinan GNU General Public License bersamaan 16 | dengan Wangsamas-Firmware. Jika tidak, lihat . 17 | 18 | Firmware ini berdasarkan Repetier-Firmware yang berdasarkan Sprinter firmware 19 | yang berdasarkan Tonokip Reprap firmware yang berdasarkan Hydra-mmm firmware. 20 | 21 | --------------------- 22 | 23 | This file is part of Wangsamas-Firmware by Kusuma Ruslan. 24 | 25 | Wangsamas-Firmware is free software: you can redistribute it and/or modify 26 | it under the terms of the GNU General Public License as published by 27 | the Free Software Foundation, either version 3 of the License, or 28 | (at your option) any later version. 29 | 30 | Wangsamas-Firmware is distributed in the hope that it will be useful, 31 | but WITHOUT ANY WARRANTY; without even the implied warranty of 32 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 33 | GNU General Public License for more details. 34 | 35 | You should have received a copy of the GNU General Public License 36 | along with Wangsamas-Firmware. If not, see . 37 | 38 | This firmware is based on Repetier-Firmware which based on sprinter firmware 39 | which based on Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware. 40 | */ 41 | 42 | #include "Wangsamas.h" 43 | 44 | #if SDSUPPORT 45 | 46 | char tempLongFilename[LONG_FILENAME_LENGTH + 1]; 47 | char fullName[LONG_FILENAME_LENGTH * SD_MAX_FOLDER_DEPTH + SD_MAX_FOLDER_DEPTH + 1]; 48 | 49 | SDCard sd; 50 | 51 | SDCard::SDCard() 52 | { 53 | sdmode = 0; 54 | sdactive = false; 55 | savetosd = false; 56 | Printer::setAutomount(false); 57 | } 58 | 59 | void SDCard::automount() 60 | { 61 | #if SDCARDDETECT > -1 62 | if(READ(SDCARDDETECT) != SDCARDDETECTINVERTED) 63 | { 64 | if(sdactive || sdmode == 100) // Card removed 65 | { 66 | Com::printFLN(PSTR("SD card removed")); 67 | #if UI_DISPLAY_TYPE != NO_DISPLAY 68 | uid.executeAction(UI_ACTION_TOP_MENU, true); 69 | #endif 70 | unmount(); 71 | UI_STATUS_UPD_F(Com::translatedF(UI_TEXT_SD_REMOVED_ID)); 72 | } 73 | } 74 | else 75 | { 76 | if(!sdactive && sdmode != 100) 77 | { 78 | UI_STATUS_UPD_F(Com::translatedF(UI_TEXT_SD_INSERTED_ID)); 79 | mount(); 80 | if(sdmode != 100) // send message only if we have success 81 | Com::printFLN(PSTR("SD card inserted")); // Not translatable or host will not understand signal 82 | #if UI_DISPLAY_TYPE != NO_DISPLAY 83 | if(sdactive && !uid.isWizardActive()) { // Wizards have priority 84 | Printer::setAutomount(true); 85 | uid.executeAction(UI_ACTION_SD_PRINT + UI_ACTION_TOPMENU, true); 86 | } 87 | #endif 88 | } 89 | } 90 | #endif 91 | } 92 | 93 | void SDCard::initsd() 94 | { 95 | sdactive = false; 96 | #if SDSS > -1 97 | #if SDCARDDETECT > -1 98 | if(READ(SDCARDDETECT) != SDCARDDETECTINVERTED) 99 | return; 100 | #endif 101 | HAL::pingWatchdog(); 102 | HAL::delayMilliseconds(50); // wait for stabilization of contacts, bootup ... 103 | fat.begin(SDSS, SPI_FULL_SPEED); // dummy init of SD_CARD 104 | HAL::delayMilliseconds(50); // wait for init end 105 | HAL::pingWatchdog(); 106 | /*if(dir[0].isOpen()) 107 | dir[0].close();*/ 108 | if(!fat.begin(SDSS, SPI_FULL_SPEED)) 109 | { 110 | Com::printFLN(Com::tSDInitFail); 111 | sdmode = 100; // prevent automount loop! 112 | return; 113 | } 114 | sdactive = true; 115 | Printer::setMenuMode(MENU_MODE_SD_MOUNTED, true); 116 | HAL::pingWatchdog(); 117 | 118 | fat.chdir(); 119 | if(selectFile("init.g", true)) 120 | { 121 | startPrint(); 122 | } 123 | #endif 124 | } 125 | 126 | void SDCard::mount() 127 | { 128 | sdmode = 0; 129 | initsd(); 130 | } 131 | 132 | void SDCard::unmount() 133 | { 134 | sdmode = 0; 135 | sdactive = false; 136 | savetosd = false; 137 | Printer::setAutomount(false); 138 | Printer::setMenuMode(MENU_MODE_SD_MOUNTED + MENU_MODE_SD_PAUSED + MENU_MODE_SD_PRINTING, false); 139 | #if UI_DISPLAY_TYPE != NO_DISPLAY && SDSUPPORT 140 | uid.cwd[0] = '/'; 141 | uid.cwd[1] = 0; 142 | uid.folderLevel = 0; 143 | #endif 144 | } 145 | 146 | void SDCard::startPrint() 147 | { 148 | if(!sdactive) return; 149 | sdmode = 1; 150 | Printer::setMenuMode(MENU_MODE_SD_PRINTING, true); 151 | Printer::setMenuMode(MENU_MODE_SD_PAUSED, false); 152 | } 153 | void SDCard::pausePrint(bool intern) 154 | { 155 | if(!sd.sdactive) return; 156 | sdmode = 2; // finish running line 157 | Printer::setMenuMode(MENU_MODE_SD_PAUSED, true); 158 | if(intern) { 159 | Commands::waitUntilEndOfAllBuffers(); 160 | sdmode = 0; 161 | Printer::MemoryPosition(); 162 | Printer::moveToReal(IGNORE_COORDINATE, IGNORE_COORDINATE, IGNORE_COORDINATE, 163 | Printer::memoryE - RETRACT_ON_PAUSE, 164 | Printer::maxFeedrate[E_AXIS] / 2); 165 | #if DRIVE_SYSTEM == DELTA 166 | Printer::moveToReal(0, 0.9 * EEPROM::deltaMaxRadius(), IGNORE_COORDINATE, IGNORE_COORDINATE, Printer::maxFeedrate[X_AXIS]); 167 | #else 168 | Printer::moveToReal(Printer::xMin, Printer::yMin + Printer::yLength, IGNORE_COORDINATE, IGNORE_COORDINATE, Printer::maxFeedrate[X_AXIS]); 169 | #endif 170 | Printer::lastCmdPos[X_AXIS] = Printer::currentPosition[X_AXIS]; 171 | Printer::lastCmdPos[Y_AXIS] = Printer::currentPosition[Y_AXIS]; 172 | Printer::lastCmdPos[Z_AXIS] = Printer::currentPosition[Z_AXIS]; 173 | GCode::executeFString(PSTR(PAUSE_START_COMMANDS)); 174 | } 175 | } 176 | 177 | void SDCard::continuePrint(bool intern) 178 | { 179 | if(!sd.sdactive) return; 180 | if(intern) { 181 | GCode::executeFString(PSTR(PAUSE_END_COMMANDS)); 182 | Printer::GoToMemoryPosition(true, true, false, false, Printer::maxFeedrate[X_AXIS]); 183 | Printer::GoToMemoryPosition(false, false, true, false, Printer::maxFeedrate[Z_AXIS] / 2.0f); 184 | Printer::GoToMemoryPosition(false, false, false, true, Printer::maxFeedrate[E_AXIS] / 2.0f); 185 | } 186 | Printer::setMenuMode(MENU_MODE_SD_PAUSED, false); 187 | sdmode = 1; 188 | } 189 | 190 | void SDCard::stopPrint() 191 | { 192 | if(!sd.sdactive) return; 193 | if(sdmode) 194 | Com::printFLN(PSTR("SD print stopped by user.")); 195 | sdmode = 0; 196 | Printer::setMenuMode(MENU_MODE_SD_PRINTING,false); 197 | Printer::setMenuMode(MENU_MODE_SD_PAUSED,false); 198 | GCode::executeFString(PSTR(SD_RUN_ON_STOP)); 199 | #if DRIVE_SYSTEM == SCARA 200 | Printer::closeArm(true, true, true); 201 | #endif 202 | if(SD_STOP_HEATER_AND_MOTORS_ON_STOP) { 203 | Commands::waitUntilEndOfAllMoves(); 204 | Printer::kill(false); 205 | } 206 | } 207 | 208 | void SDCard::writeCommand(GCode *code) 209 | { 210 | unsigned int sum1 = 0, sum2 = 0; // for fletcher-16 checksum 211 | uint8_t buf[100]; 212 | uint8_t p = 2; 213 | file.writeError = false; 214 | uint16_t params = 128 | (code->params & ~1); 215 | memcopy2(buf,¶ms); 216 | //*(int*)buf = params; 217 | if(code->isV2()) // Read G,M as 16 bit value 218 | { 219 | memcopy2(&buf[p],&code->params2); 220 | //*(int*)&buf[p] = code->params2; 221 | p += 2; 222 | if(code->hasString()) 223 | buf[p++] = strlen(code->text); 224 | if(code->hasM()) 225 | { 226 | memcopy2(&buf[p],&code->M); 227 | //*(int*)&buf[p] = code->M; 228 | p += 2; 229 | } 230 | if(code->hasG()) 231 | { 232 | memcopy2(&buf[p],&code->G); 233 | //*(int*)&buf[p]= code->G; 234 | p += 2; 235 | } 236 | } 237 | else 238 | { 239 | if(code->hasM()) 240 | { 241 | buf[p++] = (uint8_t)code->M; 242 | } 243 | if(code->hasG()) 244 | { 245 | buf[p++] = (uint8_t)code->G; 246 | } 247 | } 248 | if(code->hasX()) 249 | { 250 | memcopy4(&buf[p],&code->X); 251 | //*(float*)&buf[p] = code->X; 252 | p += 4; 253 | } 254 | if(code->hasY()) 255 | { 256 | memcopy4(&buf[p],&code->Y); 257 | //*(float*)&buf[p] = code->Y; 258 | p += 4; 259 | } 260 | if(code->hasZ()) 261 | { 262 | memcopy4(&buf[p],&code->Z); 263 | //*(float*)&buf[p] = code->Z; 264 | p += 4; 265 | } 266 | if(code->hasE()) 267 | { 268 | memcopy4(&buf[p],&code->E); 269 | //*(float*)&buf[p] = code->E; 270 | p += 4; 271 | } 272 | if(code->hasF()) 273 | { 274 | memcopy4(&buf[p],&code->F); 275 | //*(float*)&buf[p] = code->F; 276 | p += 4; 277 | } 278 | if(code->hasT()) 279 | { 280 | buf[p++] = code->T; 281 | } 282 | if(code->hasS()) 283 | { 284 | memcopy4(&buf[p],&code->S); 285 | //*(int32_t*)&buf[p] = code->S; 286 | p += 4; 287 | } 288 | if(code->hasP()) 289 | { 290 | memcopy4(&buf[p],&code->P); 291 | //*(int32_t*)&buf[p] = code->P; 292 | p += 4; 293 | } 294 | if(code->hasI()) 295 | { 296 | memcopy4(&buf[p],&code->I); 297 | //*(float*)&buf[p] = code->I; 298 | p += 4; 299 | } 300 | if(code->hasJ()) 301 | { 302 | memcopy4(&buf[p],&code->J); 303 | //*(float*)&buf[p] = code->J; 304 | p += 4; 305 | } 306 | if(code->hasR()) 307 | { 308 | memcopy4(&buf[p],&code->R); 309 | //*(float*)&buf[p] = code->R; 310 | p += 4; 311 | } 312 | if(code->hasD()) 313 | { 314 | memcopy4(&buf[p],&code->D); 315 | //*(float*)&buf[p] = code->D; 316 | p += 4; 317 | } 318 | if(code->hasC()) 319 | { 320 | memcopy4(&buf[p],&code->C); 321 | //*(float*)&buf[p] = code->C; 322 | p += 4; 323 | } 324 | if(code->hasH()) 325 | { 326 | memcopy4(&buf[p],&code->H); 327 | //*(float*)&buf[p] = code->H; 328 | p += 4; 329 | } 330 | if(code->hasA()) 331 | { 332 | memcopy4(&buf[p],&code->A); 333 | //*(float*)&buf[p] = code->A; 334 | p += 4; 335 | } 336 | if(code->hasB()) 337 | { 338 | memcopy4(&buf[p],&code->B); 339 | //*(float*)&buf[p] = code->B; 340 | p += 4; 341 | } 342 | if(code->hasK()) 343 | { 344 | memcopy4(&buf[p],&code->K); 345 | //*(float*)&buf[p] = code->K; 346 | p += 4; 347 | } 348 | if(code->hasL()) 349 | { 350 | memcopy4(&buf[p],&code->L); 351 | //*(float*)&buf[p] = code->L; 352 | p += 4; 353 | } 354 | if(code->hasO()) 355 | { 356 | memcopy4(&buf[p],&code->O); 357 | //*(float*)&buf[p] = code->O; 358 | p += 4; 359 | } 360 | if(code->hasString()) // read 16 uint8_t into string 361 | { 362 | char *sp = code->text; 363 | if(code->isV2()) 364 | { 365 | uint8_t i = strlen(code->text); 366 | for(; i; i--) buf[p++] = *sp++; 367 | } 368 | else 369 | { 370 | for(uint8_t i = 0; i < 16; ++i) buf[p++] = *sp++; 371 | } 372 | } 373 | uint8_t *ptr = buf; 374 | uint8_t len = p; 375 | while (len) 376 | { 377 | uint8_t tlen = len > 21 ? 21 : len; 378 | len -= tlen; 379 | do 380 | { 381 | sum1 += *ptr++; 382 | if(sum1 >= 255) sum1 -= 255; 383 | sum2 += sum1; 384 | if(sum2 >= 255) sum2 -= 255; 385 | } 386 | while (--tlen); 387 | } 388 | buf[p++] = sum1; 389 | buf[p++] = sum2; 390 | // Debug 391 | /*Com::printF(PSTR("Buf: ")); 392 | for(int i=0;iinit(targetFile); 514 | } 515 | if (!targetFile.isOpen()) { 516 | Com::printF(Com::tJSONErrorStart); 517 | Com::printF(Com::tNotSDPrinting); 518 | Com::printFLN(Com::tJSONErrorEnd); 519 | return; 520 | } 521 | 522 | // {"err":0,"size":457574,"height":4.00,"layerHeight":0.25,"filament":[6556.3],"generatedBy":"Slic3r 1.1.7 on 2014-11-09 at 17:11:32"} 523 | Com::printF(Com::tJSONFileInfoStart); 524 | Com::print(info->fileSize); 525 | Com::printF(Com::tJSONFileInfoHeight); 526 | Com::print(info->objectHeight); 527 | Com::printF(Com::tJSONFileInfoLayerHeight); 528 | Com::print(info->layerHeight); 529 | Com::printF(Com::tJSONFileInfoFilament); 530 | Com::print(info->filamentNeeded); 531 | Com::printF(Com::tJSONFileInfoGeneratedBy); 532 | Com::print(info->generatedBy); 533 | Com::print('"'); 534 | if (strlen(filename) == 0) { 535 | Com::printF(Com::tJSONFileInfoName); 536 | file.printName(); 537 | Com::print('"'); 538 | } 539 | Com::print('}'); 540 | Com::println(); 541 | }; 542 | 543 | #endif 544 | 545 | bool SDCard::selectFile(const char *filename, bool silent) 546 | { 547 | SdBaseFile parent; 548 | const char *oldP = filename; 549 | 550 | if(!sdactive) return false; 551 | sdmode = 0; 552 | 553 | file.close(); 554 | 555 | parent = *fat.vwd(); 556 | if (file.open(&parent, filename, O_READ)) 557 | { 558 | if ((oldP = strrchr(filename, '/')) != NULL) 559 | oldP++; 560 | else 561 | oldP = filename; 562 | 563 | if(!silent) 564 | { 565 | Com::printF(Com::tFileOpened, oldP); 566 | Com::printFLN(Com::tSpaceSizeColon,file.fileSize()); 567 | } 568 | #if JSON_OUTPUT 569 | fileInfo.init(file); 570 | #endif 571 | sdpos = 0; 572 | filesize = file.fileSize(); 573 | Com::printFLN(Com::tFileSelected); 574 | return true; 575 | } 576 | else 577 | { 578 | if(!silent) 579 | Com::printFLN(Com::tFileOpenFailed); 580 | return false; 581 | } 582 | } 583 | 584 | void SDCard::printStatus() 585 | { 586 | if(sdactive) 587 | { 588 | Com::printF(Com::tSDPrintingByte, sdpos); 589 | Com::printFLN(Com::tSlash, filesize); 590 | } 591 | else 592 | { 593 | Com::printFLN(Com::tNotSDPrinting); 594 | } 595 | } 596 | 597 | void SDCard::startWrite(char *filename) 598 | { 599 | if(!sdactive) return; 600 | file.close(); 601 | sdmode = 0; 602 | fat.chdir(); 603 | if(!file.open(filename, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) 604 | { 605 | Com::printFLN(Com::tOpenFailedFile,filename); 606 | } 607 | else 608 | { 609 | UI_STATUS_F(Com::translatedF(UI_TEXT_UPLOADING_ID)); 610 | savetosd = true; 611 | Com::printFLN(Com::tWritingToFile,filename); 612 | } 613 | } 614 | 615 | void SDCard::finishWrite() 616 | { 617 | if(!savetosd) return; // already closed or never opened 618 | file.sync(); 619 | file.close(); 620 | savetosd = false; 621 | Com::printFLN(Com::tDoneSavingFile); 622 | UI_CLEAR_STATUS; 623 | } 624 | 625 | void SDCard::deleteFile(char *filename) 626 | { 627 | if(!sdactive) return; 628 | sdmode = 0; 629 | file.close(); 630 | if(fat.remove(filename)) 631 | { 632 | Com::printFLN(Com::tFileDeleted); 633 | } 634 | else 635 | { 636 | if(fat.rmdir(filename)) 637 | Com::printFLN(Com::tFileDeleted); 638 | else 639 | Com::printFLN(Com::tDeletionFailed); 640 | } 641 | } 642 | 643 | void SDCard::makeDirectory(char *filename) 644 | { 645 | if(!sdactive) return; 646 | sdmode = 0; 647 | file.close(); 648 | if(fat.mkdir(filename)) 649 | { 650 | Com::printFLN(Com::tDirectoryCreated); 651 | } 652 | else 653 | { 654 | Com::printFLN(Com::tCreationFailed); 655 | } 656 | } 657 | 658 | #ifdef GLENN_DEBUG 659 | void SDCard::writeToFile() 660 | { 661 | size_t nbyte; 662 | char szName[10]; 663 | 664 | strcpy(szName, "Testing\r\n"); 665 | nbyte = file.write(szName, strlen(szName)); 666 | Com::print("L="); 667 | Com::print((long)nbyte); 668 | Com::println(); 669 | } 670 | 671 | #endif 672 | 673 | #endif 674 | 675 | -------------------------------------------------------------------------------- /Wangsamas/uiconfig.h: -------------------------------------------------------------------------------- 1 | /* 2 | Berkas ini adalah bagian dari Wangsamas-Firmware oleh Kusuma Ruslan. 3 | 4 | Wangsamas-Firmware adalah perangkat lunak bebas: 5 | Anda dapat mendistribusikannya dan/atau mengubahnya 6 | dengan syarat dan ketentuan GNU General Public License 7 | yang dipublikasikan oleh Free Software Foundation, 8 | baik ijin versi 3, atau (menurut pilihanmu) versi yang terbaru. 9 | 10 | Wangsamas-Firmware didistribusikan dengan harapan agar dapat bermanfaat, 11 | tetapi TANPA JAMINAN; bahkan tanpa jaminan tersirat PERDAGANGAN atau 12 | KECOCOKAN UNTUK TUJUAN TERTENTU. Lihat GNU General Public License 13 | untuk keterangan lebih lanjut. 14 | 15 | Anda seharusnya sudah menerima salinan GNU General Public License bersamaan 16 | dengan Wangsamas-Firmware. Jika tidak, lihat . 17 | 18 | Firmware ini berdasarkan Repetier-Firmware yang berdasarkan Sprinter firmware 19 | yang berdasarkan Tonokip Reprap firmware yang berdasarkan Hydra-mmm firmware. 20 | 21 | --------------------- 22 | 23 | This file is part of Wangsamas-Firmware by Kusuma Ruslan. 24 | 25 | Wangsamas-Firmware is free software: you can redistribute it and/or modify 26 | it under the terms of the GNU General Public License as published by 27 | the Free Software Foundation, either version 3 of the License, or 28 | (at your option) any later version. 29 | 30 | Wangsamas-Firmware is distributed in the hope that it will be useful, 31 | but WITHOUT ANY WARRANTY; without even the implied warranty of 32 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 33 | GNU General Public License for more details. 34 | 35 | You should have received a copy of the GNU General Public License 36 | along with Wangsamas-Firmware. If not, see . 37 | 38 | This firmware is based on Repetier-Firmware which based on sprinter firmware 39 | which based on Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware. 40 | 41 | */ 42 | 43 | /* ===================== IMPORTANT ======================== 44 | 45 | The LCD and Key support is new. I tested everything as good as possible, 46 | but some combinations may not work as supposed. 47 | The I2C methods rely on a stable I2C connection. Noise may cause wrong signals 48 | which can cause the firmware to freeze. 49 | 50 | The ui adds quite some code, so AVRs with 64kB ram (Sanguino, Gen6) can not handle all features 51 | of the firmware at the same time. You have to disable some features to gain the 52 | ram needed. What should work: 53 | - No sd card - the sd card code is quite large. 54 | - No keys attached - The longest part is the menu handling. 55 | - EEPROM_MODE 0 . 56 | 57 | Currently supported hardware: 58 | 59 | *** Displays *** 60 | 61 | - direct connected lcd with 4 data lines 62 | - connected via i2c 63 | 64 | *** Keys *** 65 | 66 | - rotary encoder 67 | - push button 68 | - key matrix up to 4x4 69 | - rotary encoder via i2c (only slow turns are captured correct) 70 | - push button via i2c 71 | 72 | *** Buzzer *** 73 | 74 | - directly connected, high = on 75 | - connected via i2c, low = on 76 | 77 | ==============================================================*/ 78 | 79 | #ifndef _ui_config_h 80 | #define _ui_config_h 81 | 82 | /** While the ascii chars are all the same, the driver have different charsets 83 | for special chars used in different countries. The charset allows to fix for 84 | this problem. If characters look wrong, try a different charset. If nothing 85 | works, use the ascii charset 0 as fallback. Not the nicest for everything but working! 86 | 87 | 0 = ASCII fallback 88 | 1 = Default works on most displays. This has some japanese chars in charset 89 | 2 = Alternative charset with more european chars 90 | 91 | */ 92 | #define UI_DISPLAY_CHARSET 2 93 | 94 | /** Select type of beeper 95 | 0 = none 96 | 1 = Piezo connected to pin 97 | 2 = Piezo connected to a pin over I2C 98 | */ 99 | #ifndef BEEPER_TYPE 100 | #define BEEPER_TYPE 1 101 | #define BEEPER_TYPE_INVERTING false 102 | #endif 103 | 104 | #if BEEPER_TYPE==1 && !defined(BEEPER_PIN) 105 | #define BEEPER_PIN 37 106 | #endif 107 | #if BEEPER_TYPE==2 108 | #define BEEPER_ADDRESS 0x40 // I2C address of the chip with the beeper pin 109 | #define BEEPER_PIN _BV(7) // Bit value for pin 8 110 | #define COMPILE_I2C_DRIVER // We need the I2C driver as we are using i2c 111 | #endif 112 | 113 | 114 | /** 115 | What display type do you use? 116 | 0 = No display - do not use here. Set FEATURE_CONTROLLER 0 instead 117 | 1 = LCD Display with 4 bit data bus 118 | 2 = LCD Display with 8 bit data bus (currently not implemented, fallback to 1) 119 | 3 = LCD Display with I2C connection, 4 bit mode 120 | 4 = Use the slower LiquiedCrystal library bundled with arduino. 121 | IMPORTANT: You need to uncomment the LiquidCrystal include in Repetier.pde for it to work. 122 | If you have Sanguino and want to use the library, you need to have Arduino 023 or older. (13.04.2012) 123 | 5 = U8G supported display 124 | */ 125 | #define UI_DISPLAY_TYPE 5 126 | 127 | #if UI_DISPLAY_TYPE == DISPLAY_U8G // Special case for graphic displays 128 | 129 | // You need to define which controller you use and set pins accodringly 130 | 131 | // For software spi assign these definitions 132 | // SCK Pin: UI_DISPLAY_D4_PIN 133 | // Mosi Pin: UI_DISPLAY_ENABLE_PIN 134 | // CD Pin: UI_DISPLAY_RS_PIN 135 | 136 | // ST7920 with software SPI 137 | #define U8GLIB_ST7920 138 | // SSD1306 with software SPI 139 | //#define U8GLIB_SSD1306_SW_SPI 140 | // SH1106 with software SPI 141 | // U8GLIB_SH1106_SW_SPI 142 | // SSD1306 over I2C using hardware I2C pins 143 | //#define U8GLIB_SSD1306_I2C 144 | // For the 8 bit ks0108 display you need to set these pins 145 | // UI_DISPLAY_D0_PIN,UI_DISPLAY_D1_PIN,UI_DISPLAY_D2_PIN,UI_DISPLAY_D3_PIN,UI_DISPLAY_D4_PIN,UI_DISPLAY_D5_PIN,UI_DISPLAY_D6_PIN,UI_DISPLAY_D7_PIN 146 | // UI_DISPLAY_ENABLE_PIN,UI_DISPLAY_CS1,UI_DISPLAY_CS2, 147 | // UI_DISPLAY_DI,UI_DISPLAY_RW_PIN,UI_DISPLAY_RESET_PIN 148 | //#define U8GLIB_KS0108 149 | //#define U8GLIB_KS0108_FAST 150 | // UI_DISPLAY_RS_PIN = CS 151 | // UI_DISPLAY_D5_PIN = A0 152 | //#define U8GLIB_ST7565_NHD_C2832_HW_SPI 153 | 154 | #define UI_LCD_WIDTH 128 155 | #define UI_LCD_HEIGHT 64 156 | 157 | //select font size 158 | #define UI_FONT_6X10 //default font 159 | #ifdef UI_FONT_6X10 160 | #define UI_FONT_WIDTH 6 161 | #define UI_FONT_HEIGHT 10 162 | #define UI_FONT_SMALL_HEIGHT 7 163 | #define UI_FONT_DEFAULT wangsamas_6x10 164 | #define UI_FONT_SMALL wangsamas_5x7 165 | #define UI_FONT_SMALL_WIDTH 5 //smaller font for status display 166 | #define UI_ANIMATION false // Animations are too slow 167 | #endif 168 | 169 | //calculate rows and cols available with current font 170 | #define UI_COLS (UI_LCD_WIDTH/UI_FONT_WIDTH) 171 | #define UI_ROWS (UI_LCD_HEIGHT/UI_FONT_HEIGHT) 172 | #define UI_DISPLAY_CHARSET 3 173 | #else 174 | /** Number of columns per row 175 | Typical values are 16 and 20 176 | */ 177 | #define UI_COLS 20 178 | /** 179 | Rows of your display. 2 or 4 180 | */ 181 | #define UI_ROWS 4 182 | #endif // UI_DISPLAY_TYPE 183 | 184 | /* What type of chip is used for I2C communication 185 | 0 : PCF8574 or PCF8574A or compatible chips. 186 | 1 : MCP23017 187 | */ 188 | #define UI_DISPLAY_I2C_CHIPTYPE 0 189 | // 0x40 till 0x4e for PCF8574, 0x40 for the adafruid RGB shield, 0x40 - 0x4e for MCP23017 190 | // Official addresses have a value half as high! 191 | #define UI_DISPLAY_I2C_ADDRESS 0x4e 192 | // For MCP 23017 define which pins should be output 193 | #define UI_DISPLAY_I2C_OUTPUT_PINS 65504 194 | // Set the output mask that is or'd over the output data. This is needed to activate 195 | // a backlight switched over the I2C. 196 | // The adafruit RGB shields enables a light if the bit is not set. Bits 6-8 are used for backlight. 197 | #define UI_DISPLAY_I2C_OUTPUT_START_MASK 0 198 | // For MCP which inputs are with pullup. 31 = pins 0-4 for adafruid rgb shield buttons 199 | #define UI_DISPLAY_I2C_PULLUP 31 200 | /* How fast should the I2C clock go. The PCF8574 work only with the lowest setting 100000. 201 | A MCP23017 can run also with 400000 Hz */ 202 | #define UI_I2C_CLOCKSPEED 100000L 203 | /** 204 | Define the pin 205 | */ 206 | #if UI_DISPLAY_TYPE == DISPLAY_I2C // I2C Pin configuration 207 | #define UI_DISPLAY_RS_PIN _BV(4) 208 | #define UI_DISPLAY_RW_PIN _BV(5) 209 | #define UI_DISPLAY_ENABLE_PIN _BV(6) 210 | #define UI_DISPLAY_D0_PIN _BV(0) 211 | #define UI_DISPLAY_D1_PIN _BV(1) 212 | #define UI_DISPLAY_D2_PIN _BV(2) 213 | #define UI_DISPLAY_D3_PIN _BV(3) 214 | #define UI_DISPLAY_D4_PIN _BV(0) 215 | #define UI_DISPLAY_D5_PIN _BV(1) 216 | #define UI_DISPLAY_D6_PIN _BV(2) 217 | #define UI_DISPLAY_D7_PIN _BV(3) 218 | 219 | // uncomment if your using led to indicated the bed is hot 220 | //#define UI_I2C_HEATBED_LED _BV(8) 221 | 222 | // uncomment if your using led to indicated the extruder is hot 223 | //#define UI_I2C_HOTEND_LED _BV(7) 224 | 225 | // uncomment if your using led to indicated the FAN is on 226 | //#define UI_I2C_FAN_LED _BV(6) 227 | 228 | // Pins for adafruid RGB shield 229 | /*#define UI_DISPLAY_RS_PIN _BV(15) 230 | #define UI_DISPLAY_RW_PIN _BV(14) 231 | #define UI_DISPLAY_ENABLE_PIN _BV(13) 232 | #define UI_DISPLAY_D0_PIN _BV(12) 233 | #define UI_DISPLAY_D1_PIN _BV(11) 234 | #define UI_DISPLAY_D2_PIN _BV(10) 235 | #define UI_DISPLAY_D3_PIN _BV(9) 236 | #define UI_DISPLAY_D4_PIN _BV(12) 237 | #define UI_DISPLAY_D5_PIN _BV(11) 238 | #define UI_DISPLAY_D6_PIN _BV(10) 239 | #define UI_DISPLAY_D7_PIN _BV(9)*/ 240 | 241 | #else // Direct display connections 242 | #define UI_DISPLAY_RS_PIN 63 // PINK.1, 88, D_RS 243 | #define UI_DISPLAY_RW_PIN -1 244 | #define UI_DISPLAY_ENABLE_PIN 65 // PINK.3, 86, D_E 245 | #define UI_DISPLAY_D0_PIN 59 // PINF.5, 92, D_D4 246 | #define UI_DISPLAY_D1_PIN 64 // PINK.2, 87, D_D5 247 | #define UI_DISPLAY_D2_PIN 44 // PINL.5, 40, D_D6 248 | #define UI_DISPLAY_D3_PIN 66 // PINK.4, 85, D_D7 249 | #define UI_DISPLAY_D4_PIN 59 // PINF.5, 92, D_D4 250 | #define UI_DISPLAY_D5_PIN 64 // PINK.2, 87, D_D5 251 | #define UI_DISPLAY_D6_PIN 44 // PINL.5, 40, D_D6 252 | #define UI_DISPLAY_D7_PIN 66 // PINK.4, 85, D_D7 253 | #define UI_DELAYPERCHAR 50 254 | 255 | // Special pins for some u8g driven display 256 | 257 | #define UI_DISPLAY_CS1 59 258 | #define UI_DISPLAY_CS2 59 259 | #define UI_DISPLAY_DI 59 260 | #define UI_DISPLAY_RW_PIN 59 261 | #define UI_DISPLAY_RESET_PIN 59 262 | #endif 263 | 264 | 265 | /** \brief Are some keys connected? 266 | 267 | 0 = No keys attached - disables also menu 268 | 1 = Some keys attached 269 | */ 270 | #define UI_HAS_KEYS 0 271 | 272 | 273 | /** \brief Is a back key present. 274 | 275 | If you have menus enabled, you need a method to leave it. If you have a back key, you can always go one level higher. 276 | Without a back key, you need to navigate to the back entry in the menu. Setting this value to 1 removes the back entry. 277 | */ 278 | #define UI_HAS_BACK_KEY 1 279 | 280 | /* Then you have the next/previous keys more like up/down keys, it may be more intuitive to change the direction you skip through the menus. 281 | If you set it to true, next will go to previous menu instead of the next menu. 282 | 283 | */ 284 | #define UI_INVERT_MENU_DIRECTION 0 285 | 286 | /** Uncomment this, if you have keys connected via i2c to a PCF8574 chip. */ 287 | //#define UI_HAS_I2C_KEYS 288 | 289 | // Do you have a I2C connected encoder? 290 | #define UI_HAS_I2C_ENCODER 0 291 | 292 | // Under which address can the key status requested. This is the address of your PCF8574 where the keys are connected. 293 | // If you use a MCP23017 the address from display is used also for keys. 294 | #define UI_I2C_KEY_ADDRESS 0x40 295 | 296 | 297 | #ifdef UI_MAIN 298 | /* ####################################################################### 299 | Key definitions 300 | 301 | The firmware is very flexible regarding your input methods. You can use one 302 | or more of the predefined key macros, to define a mapper. If no matching mapper 303 | is available, you can add you c-code for mapping directly into the keyboard 304 | routines. The predefined macros do the same, just hiding the code behind it. 305 | 306 | For each key, two seperate parts must be defined. The first is the initialization 307 | which must be added inside uiInitKeys() and the second ist a testing routine. 308 | These come into uiCheckKeys() or uiCheckSlowKeys() depending on the time needed 309 | for testing. If you are in doubt, put it in uiCheckSlowKeys(). 310 | uiInitKeys() is called from an interrupt controlling the extruder, so only 311 | fast tests should be put there. 312 | The detect methods need an action identifier. A list of supported ids is found 313 | at the beginning of ui.h It's best to use the symbol name, in case the value changes. 314 | 315 | 1. Simple push button connected to gnd if closed on a free arduino pin 316 | init -> UI_KEYS_INIT_BUTTON_LOW(pinNumber); 317 | detect -> UI_KEYS_BUTTON_LOW(pinNumber,action); 318 | 319 | 2. Simple push button connected to 5v if closed on a free arduino pin 320 | init -> UI_KEYS_INIT_BUTTON_HIGH(pinNumber); 321 | detect -> UI_KEYS_BUTTON_HIGH(pinNumber,action); 322 | 323 | 3. Click encoder, A/B connected to gnd if closed. 324 | init -> UI_KEYS_INIT_CLICKENCODER_LOW(pinA,pinB); 325 | detect -> UI_KEYS_CLICKENCODER_LOW(pinA,pinB); 326 | or UI_KEYS_CLICKENCODER_LOW_REV(pinA,pinB); // reverse direction 327 | If you can move the menu cursor without a click, just be adding some force in one direction, 328 | toggle the _REV with non _REV and toggle pins. 329 | If the direction is wrong, toggle _REV with non _REV version. 330 | For the push button of the encoder use 1. 331 | 332 | 4. Click encoder, A/B connected to 5V if closed. 333 | init -> UI_KEYS_INIT_CLICKENCODER_HIGH(pinA,pinB); 334 | detect -> UI_KEYS_CLICKENCODER_HIGH(pinA,pinB); 335 | or UI_KEYS_CLICKENCODER_HIGH_REV(pinA,pinB); // reverse direction 336 | If you can move the menu cursor without a click, just be adding some force in one direction, 337 | toggle the _REV with non _REV and toggle pins. 338 | If the direction is wrong, toggle _REV with non _REV version. 339 | For the push button of the encoder use 2. 340 | 341 | 5. Maxtrix keyboard with 1-4 rows and 1-4 columns. 342 | init -> UI_KEYS_INIT_MATRIX(r1,r2,r3,r4,c1,c2,c3,c4); 343 | detect -> UI_KEYS_MATRIX(r1,r2,r3,r4,c1,c2,c3,c4); 344 | In addition you have to set UI_MATRIX_ACTIONS to match your desired actions. 345 | 346 | ------- Keys connected via I2C ------------- 347 | 348 | All keys and the buzzer if present must be on a connected to a single PCF8574 chip! 349 | As all I2C request take time, they belong all in uiCheckSlowKeys. 350 | Dont use the pin ids but instead _BV(pinNumber0_7) as pin id. 0 = First pin 351 | 352 | 6. Click encoder, A/B connected to gnd if closed. 353 | init -> not needed, but make sure UI_HAS_I2C_KEY is not commented out. 354 | detect -> UI_KEYS_I2C_CLICKENCODER_LOW(pinA,pinB); 355 | or UI_KEYS_I2C_CLICKENCODER_LOW_REV(pinA,pinB); // reverse direction 356 | If you can move the menu cursor without a click, just be adding some force in one direction, 357 | toggle the _REV with non _REV and toggle pins. 358 | If the direction is wrong, toggle _REV with non _REV version. 359 | For the push button of the encoder use 7. 360 | NOTICE: The polling frequency is limited, so only slow turns are captured correct! 361 | 362 | 7. Simple push button connected to gnd if closed via I2C on a PCF8574 363 | init -> not needed, but make sure UI_HAS_I2C_KEY is not commented out. 364 | detect -> UI_KEYS_I2C_BUTTON_LOW(pinNumber,action); 365 | 366 | -------- Some notes on actions ------------- 367 | 368 | There are three kinds of actions. 369 | 370 | Type 1: Immediate actions - these are execute and forget actions like home/pre-heat 371 | Type 2: Parameter change action - these change the mode for next/previous keys. They are valid 372 | until a new change action is initiated or the action is finished with ok button. 373 | Type 3: Show menu action. These actions have a _MENU_ in their name. If they are executed, a new 374 | menu is pushed on the menu stack and you see the menu. If you assign these actions directly 375 | to a key, you might not want this pushing behaviour. In this case add UI_ACTION_TOPMENU to the 376 | action, like UI_ACTION_TOPMENU+UI_ACTION_MENU_XPOSFAST. That will show the menu as top-menu 377 | closing all othe submenus that were open. 378 | 379 | ####################################################################### */ 380 | 381 | // Use these codes for key detect. The main menu will show the pressed action in the lcd display. 382 | // after that assign the desired codes. 383 | //#define UI_MATRIX_ACTIONS {2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015} 384 | // Define your matrix actions 385 | #if DRIVE_SYSTEM == SCARA // Kusuma SCARA 386 | #define UI_MATRIX_ACTIONS {UI_ACTION_HOME_ALL, UI_ACTION_TOP_MENU, UI_ACTION_SET_ORIGIN, UI_ACTION_NEXT,\ 387 | UI_ACTION_HOME_Z, UI_ACTION_MENU_ZPOS, UI_ACTION_COOLDOWN, UI_ACTION_OK,\ 388 | UI_ACTION_MENU_Y_ANGLE_FAST, UI_ACTION_MENU_YPOSFAST, UI_ACTION_PREHEAT_ABS, UI_ACTION_PREVIOUS,\ 389 | UI_ACTION_MENU_X_ANGLE_FAST, UI_ACTION_MENU_XPOSFAST, UI_ACTION_DISABLE_STEPPER, UI_ACTION_BACK} 390 | #else // Kusuma SCARA 391 | #define UI_MATRIX_ACTIONS {UI_ACTION_HOME_ALL, UI_ACTION_TOP_MENU, UI_ACTION_SET_ORIGIN, UI_ACTION_NEXT,\ 392 | UI_ACTION_HOME_Z, UI_ACTION_MENU_ZPOS, UI_ACTION_COOLDOWN, UI_ACTION_OK,\ 393 | UI_ACTION_HOME_Y, UI_ACTION_MENU_YPOSFAST, UI_ACTION_PREHEAT_ABS, UI_ACTION_PREVIOUS,\ 394 | UI_ACTION_HOME_X, UI_ACTION_MENU_XPOSFAST, UI_ACTION_DISABLE_STEPPER, UI_ACTION_BACK} 395 | #endif // Kusuma SCARA 396 | #ifdef UI_MATRIX_ACTIONS 397 | const int matrixActions[] PROGMEM = UI_MATRIX_ACTIONS; 398 | #endif 399 | 400 | void uiInitKeys() { 401 | #if UI_HAS_KEYS!=0 402 | //UI_KEYS_INIT_CLICKENCODER_LOW(33,31); // click encoder on pins 47 and 45. Phase is connected with gnd for signals. 403 | UI_KEYS_INIT_BUTTON_LOW(4); // push button, connects gnd to pin 404 | UI_KEYS_INIT_BUTTON_LOW(5); 405 | UI_KEYS_INIT_BUTTON_LOW(6); 406 | UI_KEYS_INIT_BUTTON_LOW(11); 407 | UI_KEYS_INIT_BUTTON_LOW(42); 408 | 409 | // UI_KEYS_INIT_CLICKENCODER_LOW(47,45); // click encoder on pins 47 and 45. Phase is connected with gnd for signals. 410 | // UI_KEYS_INIT_BUTTON_LOW(43); // push button, connects gnd to pin 411 | // UI_KEYS_INIT_MATRIX(32,47,45,43,41,39,37,35); 412 | #endif 413 | } 414 | void uiCheckKeys(uint16_t &action) { 415 | #if UI_HAS_KEYS!=0 416 | 417 | //UI_KEYS_CLICKENCODER_LOW_REV(33,31); // click encoder on pins 47 and 45. Phase is connected with gnd for signals. 418 | UI_KEYS_BUTTON_LOW(4,UI_ACTION_OK); // push button, connects gnd to pin 419 | UI_KEYS_BUTTON_LOW(5,UI_ACTION_NEXT); // push button, connects gnd to pin 420 | UI_KEYS_BUTTON_LOW(6,UI_ACTION_PREVIOUS); // push button, connects gnd to pin 421 | UI_KEYS_BUTTON_LOW(11,UI_ACTION_BACK); // push button, connects gnd to pin 422 | UI_KEYS_BUTTON_LOW(42,UI_ACTION_SD_PRINT ); // push button, connects gnd to pin 423 | // UI_KEYS_CLICKENCODER_LOW_REV(47,45); // click encoder on pins 47 and 45. Phase is connected with gnd for signals. 424 | // UI_KEYS_BUTTON_LOW(43,UI_ACTION_OK); // push button, connects gnd to pin 425 | #endif 426 | } 427 | inline void uiCheckSlowEncoder() { 428 | #if defined(UI_HAS_I2C_KEYS) && UI_HAS_KEYS!=0 429 | #if UI_DISPLAY_I2C_CHIPTYPE==0 430 | HAL::i2cStartWait(UI_I2C_KEY_ADDRESS+I2C_READ); 431 | uint8_t keymask = HAL::i2cReadNak(); // Read current key mask 432 | #endif 433 | #if UI_DISPLAY_I2C_CHIPTYPE==1 434 | HAL::i2cStartWait(UI_DISPLAY_I2C_ADDRESS+I2C_WRITE); 435 | HAL::i2cWrite(0x12); // GIOA 436 | HAL::i2cStop(); 437 | HAL::i2cStartWait(UI_DISPLAY_I2C_ADDRESS+I2C_READ); 438 | uint16_t keymask = HAL::i2cReadAck(); 439 | keymask = keymask + (HAL::i2cReadNak()<<8); 440 | #endif 441 | HAL::i2cStop(); 442 | // Add I2C click encoder tests here, all other i2c tests and a copy of the encoder test belog in uiCheckSlowKeys 443 | UI_KEYS_I2C_CLICKENCODER_LOW_REV(_BV(2),_BV(0)); // click encoder on pins 0 and 2. Phase is connected with gnd for signals. 444 | #endif 445 | } 446 | void uiCheckSlowKeys(uint16_t &action) { 447 | #if defined(UI_HAS_I2C_KEYS) && UI_HAS_KEYS!=0 448 | #if UI_DISPLAY_I2C_CHIPTYPE==0 449 | HAL::i2cStartWait(UI_I2C_KEY_ADDRESS+I2C_READ); 450 | uint8_t keymask = HAL::i2cReadNak(); // Read current key mask 451 | #endif 452 | #if UI_DISPLAY_I2C_CHIPTYPE==1 453 | HAL::i2cStartWait(UI_DISPLAY_I2C_ADDRESS+I2C_WRITE); 454 | HAL::i2cWrite(0x12); // GPIOA 455 | HAL::i2cStop(); 456 | HAL::i2cStartWait(UI_DISPLAY_I2C_ADDRESS+I2C_READ); 457 | uint16_t keymask = HAL::i2cReadAck(); 458 | keymask = keymask + (HAL::i2cReadNak()<<8); 459 | #endif 460 | HAL::i2cStop(); 461 | // Add I2C key tests here 462 | UI_KEYS_I2C_CLICKENCODER_LOW_REV(_BV(2),_BV(0)); // click encoder on pins 0 and 2. Phase is connected with gnd for signals. 463 | UI_KEYS_I2C_BUTTON_LOW(_BV(1),UI_ACTION_OK); // push button, connects gnd to pin 464 | UI_KEYS_I2C_BUTTON_LOW(_BV(3),UI_ACTION_BACK); // push button, connects gnd to pin 465 | UI_KEYS_I2C_BUTTON_LOW(_BV(4),UI_ACTION_MENU_MOVE_Y+UI_ACTION_TOPMENU); // push button, connects gnd to pin 466 | UI_KEYS_I2C_BUTTON_LOW(_BV(5),UI_ACTION_MENU_EXTRUDER+UI_ACTION_TOPMENU); // push button, connects gnd to pin 467 | UI_KEYS_I2C_BUTTON_LOW(_BV(6),UI_ACTION_MENU_POSITIONS+UI_ACTION_TOPMENU); // push button, connects gnd to pin 468 | UI_KEYS_I2C_BUTTON_LOW(_BV(7),UI_ACTION_MENU_MOVE_X+UI_ACTION_TOPMENU); // push button, connects gnd to pin 469 | /* 470 | // Button handling for the Adafruit RGB shild 471 | UI_KEYS_I2C_BUTTON_LOW(4,UI_ACTION_PREVIOUS); // Up button 472 | UI_KEYS_I2C_BUTTON_LOW(8,UI_ACTION_NEXT); // down button 473 | UI_KEYS_I2C_BUTTON_LOW(16,UI_ACTION_BACK); // left button 474 | UI_KEYS_I2C_BUTTON_LOW(2,UI_ACTION_OK); // right button 475 | UI_KEYS_I2C_BUTTON_LOW(1,UI_ACTION_MENU_QUICKSETTINGS); //Select button 476 | // ----- End RGB shield ---------- 477 | */ 478 | #endif 479 | 480 | //UI_KEYS_MATRIX(32,47,45,43,41,39,37,35); 481 | } 482 | 483 | #endif 484 | #endif 485 | 486 | 487 | 488 | -------------------------------------------------------------------------------- /Wangsamas/Eeprom.h: -------------------------------------------------------------------------------- 1 | /* 2 | Berkas ini adalah bagian dari Wangsamas-Firmware oleh Kusuma Ruslan. 3 | 4 | Wangsamas-Firmware adalah perangkat lunak bebas: 5 | Anda dapat mendistribusikannya dan/atau mengubahnya 6 | dengan syarat dan ketentuan GNU General Public License 7 | yang dipublikasikan oleh Free Software Foundation, 8 | baik ijin versi 3, atau (menurut pilihanmu) versi yang terbaru. 9 | 10 | Wangsamas-Firmware didistribusikan dengan harapan agar dapat bermanfaat, 11 | tetapi TANPA JAMINAN; bahkan tanpa jaminan tersirat PERDAGANGAN atau 12 | KECOCOKAN UNTUK TUJUAN TERTENTU. Lihat GNU General Public License 13 | untuk keterangan lebih lanjut. 14 | 15 | Anda seharusnya sudah menerima salinan GNU General Public License bersamaan 16 | dengan Wangsamas-Firmware. Jika tidak, lihat . 17 | 18 | Firmware ini berdasarkan Repetier-Firmware yang berdasarkan Sprinter firmware 19 | yang berdasarkan Tonokip Reprap firmware yang berdasarkan Hydra-mmm firmware. 20 | 21 | --------------------- 22 | 23 | This file is part of Wangsamas-Firmware by Kusuma Ruslan. 24 | 25 | Wangsamas-Firmware is free software: you can redistribute it and/or modify 26 | it under the terms of the GNU General Public License as published by 27 | the Free Software Foundation, either version 3 of the License, or 28 | (at your option) any later version. 29 | 30 | Wangsamas-Firmware is distributed in the hope that it will be useful, 31 | but WITHOUT ANY WARRANTY; without even the implied warranty of 32 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 33 | GNU General Public License for more details. 34 | 35 | You should have received a copy of the GNU General Public License 36 | along with Wangsamas-Firmware. If not, see . 37 | 38 | This firmware is based on Repetier-Firmware which based on sprinter firmware 39 | which based on Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware. 40 | 41 | */ 42 | 43 | #ifndef _EEPROM_H 44 | #define _EEPROM_H 45 | 46 | // Id to distinguish version changes 47 | #define EEPROM_PROTOCOL_VERSION 16 48 | 49 | /** Where to start with our datablock in memory. Can be moved if you 50 | have problems with other modules using the eeprom */ 51 | 52 | #define EPR_MAGIC_BYTE 0 53 | #define EPR_ACCELERATION_TYPE 1 54 | #define EPR_XAXIS_STEPS_PER_UNIT 3 55 | #define EPR_YAXIS_STEPS_PER_UNIT 7 56 | #define EPR_ZAXIS_STEPS_PER_UNIT 11 57 | #define EPR_X_MAX_FEEDRATE 15 58 | #define EPR_Y_MAX_FEEDRATE 19 59 | #define EPR_Z_MAX_FEEDRATE 23 60 | #define EPR_X_HOMING_FEEDRATE 27 61 | #define EPR_Y_HOMING_FEEDRATE 31 62 | #define EPR_Z_HOMING_FEEDRATE 35 63 | #define EPR_MAX_JERK 39 64 | //#define EPR_OPS_MIN_DISTANCE 43 65 | #define EPR_MAX_ZJERK 47 66 | #define EPR_X_MAX_ACCEL 51 67 | #define EPR_Y_MAX_ACCEL 55 68 | #define EPR_Z_MAX_ACCEL 59 69 | #define EPR_X_MAX_TRAVEL_ACCEL 63 70 | #define EPR_Y_MAX_TRAVEL_ACCEL 67 71 | #define EPR_Z_MAX_TRAVEL_ACCEL 71 72 | #define EPR_BAUDRATE 75 73 | #define EPR_MAX_INACTIVE_TIME 79 74 | #define EPR_STEPPER_INACTIVE_TIME 83 75 | //#define EPR_OPS_RETRACT_DISTANCE 87 76 | //#define EPR_OPS_RETRACT_BACKLASH 91 77 | #define EPR_EXTRUDER_SPEED 95 78 | //#define EPR_OPS_MOVE_AFTER 99 79 | //#define EPR_OPS_MODE 103 80 | #define EPR_INTEGRITY_BYTE 104 // Here the xored sum over eeprom is stored 81 | #define EPR_VERSION 105 // Version id for updates in EEPROM storage 82 | #define EPR_BED_HEAT_MANAGER 106 83 | #define EPR_BED_DRIVE_MAX 107 84 | #define EPR_BED_PID_PGAIN 108 85 | #define EPR_BED_PID_IGAIN 112 86 | #define EPR_BED_PID_DGAIN 116 87 | #define EPR_BED_PID_MAX 120 88 | #define EPR_BED_DRIVE_MIN 124 89 | #define EPR_PRINTING_TIME 125 // Time in seconds printing 90 | #define EPR_PRINTING_DISTANCE 129 // Filament length printed 91 | #define EPR_X_HOME_OFFSET 133 92 | #define EPR_Y_HOME_OFFSET 137 93 | #define EPR_Z_HOME_OFFSET 141 94 | #define EPR_X_LENGTH 145 95 | #define EPR_Y_LENGTH 149 96 | #define EPR_Z_LENGTH 153 97 | #define EPR_BACKLASH_X 157 98 | #define EPR_BACKLASH_Y 161 99 | #define EPR_BACKLASH_Z 165 100 | 101 | #define EPR_Z_PROBE_X_OFFSET 800 102 | #define EPR_Z_PROBE_Y_OFFSET 804 103 | #define EPR_Z_PROBE_HEIGHT 808 104 | #define EPR_Z_PROBE_SPEED 812 105 | #define EPR_Z_PROBE_X1 816 106 | #define EPR_Z_PROBE_Y1 820 107 | #define EPR_Z_PROBE_X2 824 108 | #define EPR_Z_PROBE_Y2 828 109 | #define EPR_Z_PROBE_X3 832 110 | #define EPR_Z_PROBE_Y3 836 111 | #define EPR_Z_PROBE_XY_SPEED 840 112 | #define EPR_AUTOLEVEL_MATRIX 844 113 | #define EPR_AUTOLEVEL_ACTIVE 880 114 | #define EPR_DELTA_DIAGONAL_ROD_LENGTH 881 115 | #define EPR_DELTA_HORIZONTAL_RADIUS 885 116 | #define EPR_DELTA_SEGMENTS_PER_SECOND_PRINT 889 117 | #define EPR_DELTA_SEGMENTS_PER_SECOND_MOVE 891 118 | #define EPR_DELTA_TOWERX_OFFSET_STEPS 893 119 | #define EPR_DELTA_TOWERY_OFFSET_STEPS 895 120 | #define EPR_DELTA_TOWERZ_OFFSET_STEPS 897 121 | #define EPR_DELTA_ALPHA_A 901 122 | #define EPR_DELTA_ALPHA_B 905 123 | #define EPR_DELTA_ALPHA_C 909 124 | #define EPR_DELTA_RADIUS_CORR_A 913 125 | #define EPR_DELTA_RADIUS_CORR_B 917 126 | #define EPR_DELTA_RADIUS_CORR_C 921 127 | #define EPR_DELTA_MAX_RADIUS 925 128 | #define EPR_Z_PROBE_BED_DISTANCE 929 129 | #define EPR_DELTA_DIAGONAL_CORRECTION_A 933 130 | #define EPR_DELTA_DIAGONAL_CORRECTION_B 937 131 | #define EPR_DELTA_DIAGONAL_CORRECTION_C 941 132 | #define EPR_TOUCHSCREEN 946 // - 975 = 30 byte for touchscreen calibration data 133 | 134 | #define EPR_ARM_LENGTH 1048 // Kusuma SCARA 135 | #define EPR_FOREARM_LENGTH 1052 // Kusuma SCARA 136 | #define EPR_SHOULDER_MIN_ANGLE 1056 // Kusuma SCARA 137 | #define EPR_ELBOW_MIN_ANGLE 1060 // Kusuma SCARA 138 | #define EPR_SHOULDER_MAX_ANGLE 1064 // Kusuma SCARA 139 | #define EPR_ELBOW_MAX_ANGLE 1068 // Kusuma SCARA 140 | #define EPR_SHOULDER_BED_CENTER_ANGLE 1072 // Kusuma SCARA 141 | #define EPR_ELBOW_BED_CENTER_ANGLE 1076 // Kusuma SCARA 142 | 143 | // Axis compensation 144 | #define EPR_AXISCOMP_TANXY 976 145 | #define EPR_AXISCOMP_TANYZ 980 146 | #define EPR_AXISCOMP_TANXZ 984 147 | 148 | #define EPR_DISTORTION_CORRECTION_ENABLED 988 149 | #define EPR_RETRACTION_LENGTH 992 150 | #define EPR_RETRACTION_LONG_LENGTH 996 151 | #define EPR_RETRACTION_SPEED 1000 152 | #define EPR_RETRACTION_Z_LIFT 1004 153 | #define EPR_RETRACTION_UNDO_EXTRA_LENGTH 1008 154 | #define EPR_RETRACTION_UNDO_EXTRA_LONG_LENGTH 1012 155 | #define EPR_RETRACTION_UNDO_SPEED 1016 156 | #define EPR_AUTORETRACT_ENABLED 1020 157 | #define EPR_Z_PROBE_Z_OFFSET 1024 158 | #define EPR_SELECTED_LANGUAGE 1028 159 | #define EPR_ACCELERATION_FACTOR_TOP 1032 160 | #define EPR_BENDING_CORRECTION_A 1036 161 | #define EPR_BENDING_CORRECTION_B 1040 162 | #define EPR_BENDING_CORRECTION_C 1044 163 | 164 | #if EEPROM_MODE != 0 165 | #define EEPROM_FLOAT(x) HAL::eprGetFloat(EPR_##x) 166 | #define EEPROM_INT32(x) HAL::eprGetInt32(EPR_##x) 167 | #define EEPROM_BYTE(x) HAL::eprGetByte(EPR_##x) 168 | #define EEPROM_SET_BYTE(x,val) HAL::eprSetByte(EPR_##x,val) 169 | #else 170 | #define EEPROM_FLOAT(x) (float)(x) 171 | #define EEPROM_INT32(x) (int32_t)(x) 172 | #define EEPROM_BYTE(x) (uint8_t)(x) 173 | #define EEPROM_SET_BYTE(x,val) 174 | #endif 175 | 176 | #define EEPROM_EXTRUDER_OFFSET 200 177 | // bytes per extruder needed, leave some space for future development 178 | #define EEPROM_EXTRUDER_LENGTH 100 179 | // Extruder positions relative to extruder start 180 | #define EPR_EXTRUDER_STEPS_PER_UNIT 0 181 | #define EPR_EXTRUDER_MAX_FEEDRATE 4 182 | // Feedrate from halted extruder in mm/s 183 | #define EPR_EXTRUDER_MAX_START_FEEDRATE 8 184 | // Acceleration in mm/s^2 185 | #define EPR_EXTRUDER_MAX_ACCELERATION 12 186 | #define EPR_EXTRUDER_HEAT_MANAGER 16 187 | #define EPR_EXTRUDER_DRIVE_MAX 17 188 | #define EPR_EXTRUDER_PID_PGAIN 18 189 | #define EPR_EXTRUDER_PID_IGAIN 22 190 | #define EPR_EXTRUDER_PID_DGAIN 26 191 | #define EPR_EXTRUDER_DEADTIME EPR_EXTRUDER_PID_PGAIN 192 | #define EPR_EXTRUDER_PID_MAX 30 193 | #define EPR_EXTRUDER_X_OFFSET 31 194 | #define EPR_EXTRUDER_Y_OFFSET 35 195 | #define EPR_EXTRUDER_WATCH_PERIOD 39 196 | #define EPR_EXTRUDER_ADVANCE_K 41 197 | #define EPR_EXTRUDER_DRIVE_MIN 45 198 | #define EPR_EXTRUDER_ADVANCE_L 46 199 | #define EPR_EXTRUDER_WAIT_RETRACT_TEMP 50 200 | #define EPR_EXTRUDER_WAIT_RETRACT_UNITS 52 201 | #define EPR_EXTRUDER_COOLER_SPEED 54 202 | // 55-57 free for byte sized parameter 203 | #define EPR_EXTRUDER_MIXING_RATIOS 58 // 16*2 byte ratios = 32 byte -> end = 89 204 | #define EPR_EXTRUDER_Z_OFFSET 90 205 | #ifndef Z_PROBE_BED_DISTANCE 206 | #define Z_PROBE_BED_DISTANCE 5.0 207 | #endif 208 | 209 | class EEPROM 210 | { 211 | #if EEPROM_MODE != 0 212 | static void writeExtruderPrefix(uint pos); 213 | static void writeFloat(uint pos,PGM_P text,uint8_t digits = 3); 214 | static void writeLong(uint pos,PGM_P text); 215 | static void writeInt(uint pos,PGM_P text); 216 | static void writeByte(uint pos,PGM_P text); 217 | public: 218 | static uint8_t computeChecksum(); 219 | static void updateChecksum(); 220 | #endif 221 | public: 222 | 223 | static void init(); 224 | static void initBaudrate(); 225 | static void storeDataIntoEEPROM(uint8_t corrupted = 0); 226 | static void storeScaraDataIntoEEPROM(uint8_t corrupted = 0); // Kusuma SCARA 227 | static void readDataFromEEPROM(bool includeExtruder); 228 | static void restoreEEPROMSettingsFromConfiguration(); 229 | static void writeSettings(); 230 | static void update(GCode *com); 231 | static void updatePrinterUsage(); 232 | static inline void setVersion(uint8_t v) { 233 | #if EEPROM_MODE != 0 234 | HAL::eprSetByte(EPR_VERSION,v); 235 | HAL::eprSetByte(EPR_INTEGRITY_BYTE,computeChecksum()); 236 | #endif 237 | } 238 | static inline uint8_t getStoredLanguage() { 239 | #if EEPROM_MODE != 0 240 | return HAL::eprGetByte(EPR_SELECTED_LANGUAGE); 241 | #else 242 | return 0; 243 | #endif 244 | } 245 | static inline float zProbeZOffset() { 246 | #if EEPROM_MODE != 0 247 | return HAL::eprGetFloat(EPR_Z_PROBE_Z_OFFSET); 248 | #else 249 | return Z_PROBE_Z_OFFSET; 250 | #endif 251 | } 252 | static inline float zProbeSpeed() { 253 | #if EEPROM_MODE != 0 254 | return HAL::eprGetFloat(EPR_Z_PROBE_SPEED); 255 | #else 256 | return Z_PROBE_SPEED; 257 | #endif 258 | } 259 | static inline float zProbeXYSpeed() { 260 | #if EEPROM_MODE != 0 261 | return HAL::eprGetFloat(EPR_Z_PROBE_XY_SPEED); 262 | #else 263 | return Z_PROBE_XY_SPEED; 264 | #endif 265 | } 266 | static inline float zProbeXOffset() { 267 | #if EEPROM_MODE != 0 268 | return HAL::eprGetFloat(EPR_Z_PROBE_X_OFFSET); 269 | #else 270 | return Z_PROBE_X_OFFSET; 271 | #endif 272 | } 273 | static inline float zProbeYOffset() { 274 | #if EEPROM_MODE != 0 275 | return HAL::eprGetFloat(EPR_Z_PROBE_Y_OFFSET); 276 | #else 277 | return Z_PROBE_Y_OFFSET; 278 | #endif 279 | } 280 | static inline float zProbeHeight() { 281 | #if EEPROM_MODE != 0 282 | return HAL::eprGetFloat(EPR_Z_PROBE_HEIGHT); 283 | #else 284 | return Z_PROBE_HEIGHT; 285 | #endif 286 | } 287 | static inline float zProbeX1() { 288 | #if EEPROM_MODE != 0 289 | return HAL::eprGetFloat(EPR_Z_PROBE_X1); 290 | #else 291 | return Z_PROBE_X1; 292 | #endif 293 | } 294 | static inline float zProbeY1() { 295 | #if EEPROM_MODE != 0 296 | return HAL::eprGetFloat(EPR_Z_PROBE_Y1); 297 | #else 298 | return Z_PROBE_Y1; 299 | #endif 300 | } 301 | static inline float zProbeX2() { 302 | #if EEPROM_MODE != 0 303 | return HAL::eprGetFloat(EPR_Z_PROBE_X2); 304 | #else 305 | return Z_PROBE_X2; 306 | #endif 307 | } 308 | static inline float zProbeY2() { 309 | #if EEPROM_MODE != 0 310 | return HAL::eprGetFloat(EPR_Z_PROBE_Y2); 311 | #else 312 | return Z_PROBE_Y2; 313 | #endif 314 | } 315 | static inline float zProbeX3() { 316 | #if EEPROM_MODE != 0 317 | return HAL::eprGetFloat(EPR_Z_PROBE_X3); 318 | #else 319 | return Z_PROBE_X3; 320 | #endif 321 | } 322 | static inline float zProbeY3() { 323 | #if EEPROM_MODE != 0 324 | return HAL::eprGetFloat(EPR_Z_PROBE_Y3); 325 | #else 326 | return Z_PROBE_Y3; 327 | #endif 328 | } 329 | static inline float zProbeBedDistance() { 330 | #if EEPROM_MODE != 0 331 | return HAL::eprGetFloat(EPR_Z_PROBE_BED_DISTANCE); 332 | #else 333 | return Z_PROBE_BED_DISTANCE; 334 | #endif 335 | } 336 | 337 | static inline float axisCompTanXY() { 338 | #if EEPROM_MODE != 0 339 | return HAL::eprGetFloat(EPR_AXISCOMP_TANXY); 340 | #else 341 | return AXISCOMP_TANXY; 342 | #endif 343 | } 344 | static inline float axisCompTanYZ() { 345 | #if EEPROM_MODE != 0 346 | return HAL::eprGetFloat(EPR_AXISCOMP_TANYZ); 347 | #else 348 | return AXISCOMP_TANYZ; 349 | #endif 350 | } 351 | static inline float axisCompTanXZ() { 352 | #if EEPROM_MODE != 0 353 | return HAL::eprGetFloat(EPR_AXISCOMP_TANXZ); 354 | #else 355 | return AXISCOMP_TANXZ; 356 | #endif 357 | } 358 | 359 | #if NONLINEAR_SYSTEM 360 | static inline int16_t deltaSegmentsPerSecondMove() { 361 | #if EEPROM_MODE != 0 362 | return HAL::eprGetInt16(EPR_DELTA_SEGMENTS_PER_SECOND_MOVE); 363 | #else 364 | return DELTA_SEGMENTS_PER_SECOND_MOVE; 365 | #endif 366 | } 367 | static inline float deltaDiagonalRodLength() { 368 | #if EEPROM_MODE != 0 369 | return HAL::eprGetFloat(EPR_DELTA_DIAGONAL_ROD_LENGTH); 370 | #else 371 | return DELTA_DIAGONAL_ROD; 372 | #endif 373 | } 374 | static inline int16_t deltaSegmentsPerSecondPrint() { 375 | #if EEPROM_MODE != 0 376 | return HAL::eprGetInt16(EPR_DELTA_SEGMENTS_PER_SECOND_PRINT); 377 | #else 378 | return DELTA_SEGMENTS_PER_SECOND_PRINT; 379 | #endif 380 | } 381 | #endif 382 | #if DRIVE_SYSTEM == SCARA // Kusuma SCARA 383 | static inline float armLength() { // Kusuma SCARA 384 | #if EEPROM_MODE != 0 // Kusuma SCARA 385 | return HAL::eprGetFloat(EPR_ARM_LENGTH); // Kusuma SCARA 386 | #else // Kusuma SCARA 387 | return ARM_LENGTH; // Kusuma SCARA 388 | #endif // Kusuma SCARA 389 | } // Kusuma SCARA 390 | static inline float forearmLength() { // Kusuma SCARA 391 | #if EEPROM_MODE != 0 // Kusuma SCARA 392 | return HAL::eprGetFloat(EPR_FOREARM_LENGTH); // Kusuma SCARA 393 | #else // Kusuma SCARA 394 | return FOREARM_LENGTH; // Kusuma SCARA 395 | #endif // Kusuma SCARA 396 | } // Kusuma SCARA 397 | static inline float ShoulderMinAngle() { // Kusuma SCARA 398 | #if EEPROM_MODE != 0 // Kusuma SCARA 399 | return HAL::eprGetFloat(EPR_SHOULDER_MIN_ANGLE); // Kusuma SCARA 400 | #else // Kusuma SCARA 401 | return SHOULDER_MIN_ANGLE; // Kusuma SCARA 402 | #endif // Kusuma SCARA 403 | } // Kusuma SCARA 404 | static inline float ElbowMinAngle() { // Kusuma SCARA 405 | #if EEPROM_MODE != 0 // Kusuma SCARA 406 | return HAL::eprGetFloat(EPR_ELBOW_MIN_ANGLE); // Kusuma SCARA 407 | #else // Kusuma SCARA 408 | return ELBOW_MIN_ANGLE; // Kusuma SCARA 409 | #endif // Kusuma SCARA 410 | } // Kusuma SCARA 411 | static inline float ShoulderMaxAngle() { // Kusuma SCARA 412 | #if EEPROM_MODE != 0 // Kusuma SCARA 413 | return HAL::eprGetFloat(EPR_SHOULDER_MAX_ANGLE); // Kusuma SCARA 414 | #else // Kusuma SCARA 415 | return SHOULDER_MAX_ANGLE; // Kusuma SCARA 416 | #endif // Kusuma SCARA 417 | } // Kusuma SCARA 418 | static inline float ElbowMaxAngle() { // Kusuma SCARA 419 | #if EEPROM_MODE != 0 // Kusuma SCARA 420 | return HAL::eprGetFloat(EPR_ELBOW_MAX_ANGLE); // Kusuma SCARA 421 | #else // Kusuma SCARA 422 | return ELBOW_MAX_ANGLE; // Kusuma SCARA 423 | #endif // Kusuma SCARA 424 | } // Kusuma SCARA 425 | static inline float ShoulderBedCenterAngle() { // Kusuma SCARA 426 | #if EEPROM_MODE != 0 // Kusuma SCARA 427 | return HAL::eprGetFloat(EPR_SHOULDER_BED_CENTER_ANGLE); // Kusuma SCARA 428 | #else // Kusuma SCARA 429 | return SHOULDER_BED_CENTER_ANGLE; // Kusuma SCARA 430 | #endif // Kusuma SCARA 431 | } // Kusuma SCARA 432 | static inline float ElbowBedCenterAngle() { // Kusuma SCARA 433 | #if EEPROM_MODE != 0 // Kusuma SCARA 434 | return HAL::eprGetFloat(EPR_ELBOW_BED_CENTER_ANGLE); // Kusuma SCARA 435 | #else // Kusuma SCARA 436 | return ELBOW_BED_CENTER_ANGLE; // Kusuma SCARA 437 | #endif // Kusuma SCARA 438 | } // Kusuma SCARA 439 | #endif // Kusuma SCARA 440 | #if DRIVE_SYSTEM == DELTA 441 | static inline float deltaHorizontalRadius() { 442 | #if EEPROM_MODE != 0 443 | return HAL::eprGetFloat(EPR_DELTA_HORIZONTAL_RADIUS); 444 | #else 445 | return ROD_RADIUS; 446 | #endif 447 | } 448 | static inline int16_t deltaTowerXOffsetSteps() { 449 | #if EEPROM_MODE != 0 450 | return HAL::eprGetInt16(EPR_DELTA_TOWERX_OFFSET_STEPS); 451 | #else 452 | return DELTA_X_ENDSTOP_OFFSET_STEPS; 453 | #endif 454 | } 455 | static inline int16_t deltaTowerYOffsetSteps() { 456 | #if EEPROM_MODE != 0 457 | return HAL::eprGetInt16(EPR_DELTA_TOWERY_OFFSET_STEPS); 458 | #else 459 | return DELTA_Y_ENDSTOP_OFFSET_STEPS; 460 | #endif 461 | } 462 | static inline int16_t deltaTowerZOffsetSteps() { 463 | #if EEPROM_MODE != 0 464 | return HAL::eprGetInt16(EPR_DELTA_TOWERZ_OFFSET_STEPS); 465 | #else 466 | return DELTA_Z_ENDSTOP_OFFSET_STEPS; 467 | #endif 468 | } 469 | 470 | static inline void setRodRadius(float mm) { 471 | #if DRIVE_SYSTEM == DELTA 472 | Printer::radius0=mm; 473 | Printer::updateDerivedParameter(); 474 | #if EEPROM_MODE != 0 475 | //This is an odd situation, the radius can only be changed if eeprom is on. 476 | // The radius is not saved to printer variablke now, it is all derived parameters of 477 | // fetching the radius, which if EEProm is off returns the Configuration constant. 478 | HAL::eprSetFloat(EPR_DELTA_HORIZONTAL_RADIUS, mm); 479 | Com::printFLN(PSTR("Rod Radius set to: "),mm,3); 480 | uint8_t newcheck = computeChecksum(); 481 | if(newcheck!=HAL::eprGetByte(EPR_INTEGRITY_BYTE)) 482 | HAL::eprSetByte(EPR_INTEGRITY_BYTE,newcheck); 483 | #endif 484 | #endif 485 | } 486 | static inline void incrementRodRadius(float mm) { 487 | setRodRadius(mm + deltaHorizontalRadius()); 488 | } 489 | static inline void setTowerXFloor(float newZ) { 490 | #if DRIVE_SYSTEM == DELTA 491 | Printer::xMin = newZ; 492 | Printer::updateDerivedParameter(); 493 | Com::printFLN(PSTR("X (A) tower floor set to: "),Printer::xMin,3); 494 | #if EEPROM_MODE != 0 495 | HAL::eprSetFloat(EPR_X_HOME_OFFSET,Printer::xMin); 496 | uint8_t newcheck = computeChecksum(); 497 | if(newcheck!=HAL::eprGetByte(EPR_INTEGRITY_BYTE)) 498 | HAL::eprSetByte(EPR_INTEGRITY_BYTE,newcheck); 499 | #endif 500 | #endif 501 | } 502 | static inline void setTowerYFloor(float newZ) { 503 | #if DRIVE_SYSTEM == DELTA 504 | Printer::yMin = newZ; 505 | Printer::updateDerivedParameter(); 506 | Com::printFLN(PSTR("Y (B) tower floor set to: "), Printer::yMin, 3); 507 | #if EEPROM_MODE != 0 508 | 509 | HAL::eprSetFloat(EPR_Y_HOME_OFFSET,Printer::yMin); 510 | uint8_t newcheck = computeChecksum(); 511 | if(newcheck != HAL::eprGetByte(EPR_INTEGRITY_BYTE)) 512 | HAL::eprSetByte(EPR_INTEGRITY_BYTE,newcheck); 513 | #endif 514 | #endif 515 | } 516 | static inline void setTowerZFloor(float newZ) { 517 | #if DRIVE_SYSTEM == DELTA 518 | Printer::zMin = newZ; 519 | Printer::updateDerivedParameter(); 520 | Com::printFLN(PSTR("Z (C) tower floor set to: "), Printer::zMin, 3); 521 | #if EEPROM_MODE != 0 522 | HAL::eprSetFloat(EPR_Z_HOME_OFFSET,Printer::zMin); 523 | uint8_t newcheck = computeChecksum(); 524 | if(newcheck != HAL::eprGetByte(EPR_INTEGRITY_BYTE)) 525 | HAL::eprSetByte(EPR_INTEGRITY_BYTE,newcheck); 526 | #endif 527 | #endif 528 | } 529 | static inline void setDeltaTowerXOffsetSteps(int16_t steps) { 530 | #if EEPROM_MODE != 0 531 | HAL::eprSetInt16(EPR_DELTA_TOWERX_OFFSET_STEPS,steps); 532 | uint8_t newcheck = computeChecksum(); 533 | if(newcheck != HAL::eprGetByte(EPR_INTEGRITY_BYTE)) 534 | HAL::eprSetByte(EPR_INTEGRITY_BYTE,newcheck); 535 | #endif 536 | } 537 | static inline void setDeltaTowerYOffsetSteps(int16_t steps) { 538 | #if EEPROM_MODE != 0 539 | HAL::eprSetInt16(EPR_DELTA_TOWERY_OFFSET_STEPS,steps); 540 | uint8_t newcheck = computeChecksum(); 541 | if(newcheck != HAL::eprGetByte(EPR_INTEGRITY_BYTE)) 542 | HAL::eprSetByte(EPR_INTEGRITY_BYTE,newcheck); 543 | #endif 544 | } 545 | static inline void setDeltaTowerZOffsetSteps(int16_t steps) { 546 | #if EEPROM_MODE != 0 547 | HAL::eprSetInt16(EPR_DELTA_TOWERZ_OFFSET_STEPS,steps); 548 | uint8_t newcheck = computeChecksum(); 549 | if(newcheck != HAL::eprGetByte(EPR_INTEGRITY_BYTE)) 550 | HAL::eprSetByte(EPR_INTEGRITY_BYTE,newcheck); 551 | #endif 552 | } 553 | static inline float deltaAlphaA() { 554 | #if EEPROM_MODE != 0 555 | return HAL::eprGetFloat(EPR_DELTA_ALPHA_A); 556 | #else 557 | return DELTA_ALPHA_A; 558 | #endif 559 | } 560 | static inline float deltaAlphaB() { 561 | #if EEPROM_MODE != 0 562 | return HAL::eprGetFloat(EPR_DELTA_ALPHA_B); 563 | #else 564 | return DELTA_ALPHA_B; 565 | #endif 566 | } 567 | static inline float deltaAlphaC() { 568 | #if EEPROM_MODE != 0 569 | return HAL::eprGetFloat(EPR_DELTA_ALPHA_C); 570 | #else 571 | return DELTA_ALPHA_C; 572 | #endif 573 | } 574 | static inline float deltaRadiusCorrectionA() { 575 | #if EEPROM_MODE != 0 576 | return HAL::eprGetFloat(EPR_DELTA_RADIUS_CORR_A); 577 | #else 578 | return DELTA_RADIUS_CORRECTION_A; 579 | #endif 580 | } 581 | static inline float deltaRadiusCorrectionB() { 582 | #if EEPROM_MODE != 0 583 | return HAL::eprGetFloat(EPR_DELTA_RADIUS_CORR_B); 584 | #else 585 | return DELTA_RADIUS_CORRECTION_B; 586 | #endif 587 | } 588 | static inline float deltaRadiusCorrectionC() { 589 | #if EEPROM_MODE != 0 590 | return HAL::eprGetFloat(EPR_DELTA_RADIUS_CORR_C); 591 | #else 592 | return DELTA_RADIUS_CORRECTION_C; 593 | #endif 594 | } 595 | static inline float deltaDiagonalCorrectionA() { 596 | return EEPROM_FLOAT(DELTA_DIAGONAL_CORRECTION_A); 597 | } 598 | static inline float deltaDiagonalCorrectionB() { 599 | return EEPROM_FLOAT(DELTA_DIAGONAL_CORRECTION_B); 600 | } 601 | static inline float deltaDiagonalCorrectionC() { 602 | return EEPROM_FLOAT(DELTA_DIAGONAL_CORRECTION_C); 603 | } 604 | static inline float deltaMaxRadius() { 605 | return EEPROM_FLOAT(DELTA_MAX_RADIUS); 606 | } 607 | 608 | #endif 609 | static void initalizeUncached(); 610 | #if MIXING_EXTRUDER 611 | static void storeMixingRatios(bool updateChecksums = true); 612 | static void readMixingRatios(); 613 | static void restoreMixingRatios(); 614 | #endif 615 | 616 | static void setZCorrection(int32_t c,int index); 617 | static inline int32_t getZCorrection(int index) { 618 | return HAL::eprGetInt32(2048 + (index << 2)); 619 | } 620 | static inline void setZCorrectionEnabled(int8_t on) { 621 | #if EEPROM_MODE != 0 622 | if(isZCorrectionEnabled() == on) return; 623 | HAL::eprSetInt16(EPR_DISTORTION_CORRECTION_ENABLED, on); 624 | uint8_t newcheck = computeChecksum(); 625 | if(newcheck != HAL::eprGetByte(EPR_INTEGRITY_BYTE)) 626 | HAL::eprSetByte(EPR_INTEGRITY_BYTE, newcheck); 627 | #endif 628 | } 629 | static inline int8_t isZCorrectionEnabled() { 630 | #if EEPROM_MODE != 0 631 | return HAL::eprGetByte(EPR_DISTORTION_CORRECTION_ENABLED); 632 | #else 633 | return 0; 634 | #endif 635 | } 636 | static inline float bendingCorrectionA() { 637 | #if EEPROM_MODE != 0 638 | return HAL::eprGetFloat(EPR_BENDING_CORRECTION_A); 639 | #else 640 | return BENDING_CORRECTION_A; 641 | #endif 642 | } 643 | static inline float bendingCorrectionB() { 644 | #if EEPROM_MODE != 0 645 | return HAL::eprGetFloat(EPR_BENDING_CORRECTION_B); 646 | #else 647 | return BENDING_CORRECTION_B; 648 | #endif 649 | } 650 | static inline float bendingCorrectionC() { 651 | #if EEPROM_MODE != 0 652 | return HAL::eprGetFloat(EPR_BENDING_CORRECTION_C); 653 | #else 654 | return BENDING_CORRECTION_C; 655 | #endif 656 | } 657 | static inline float accelarationFactorTop() { 658 | #if EEPROM_MODE != 0 659 | return HAL::eprGetFloat(EPR_ACCELERATION_FACTOR_TOP); 660 | #else 661 | return ACCELERATION_FACTOR_TOP; 662 | #endif 663 | } 664 | 665 | }; 666 | #endif 667 | -------------------------------------------------------------------------------- /Wangsamas/motion.h: -------------------------------------------------------------------------------- 1 | /* 2 | Berkas ini adalah bagian dari Wangsamas-Firmware oleh Kusuma Ruslan. 3 | 4 | Wangsamas-Firmware adalah perangkat lunak bebas: 5 | Anda dapat mendistribusikannya dan/atau mengubahnya 6 | dengan syarat dan ketentuan GNU General Public License 7 | yang dipublikasikan oleh Free Software Foundation, 8 | baik ijin versi 3, atau (menurut pilihanmu) versi yang terbaru. 9 | 10 | Wangsamas-Firmware didistribusikan dengan harapan agar dapat bermanfaat, 11 | tetapi TANPA JAMINAN; bahkan tanpa jaminan tersirat PERDAGANGAN atau 12 | KECOCOKAN UNTUK TUJUAN TERTENTU. Lihat GNU General Public License 13 | untuk keterangan lebih lanjut. 14 | 15 | Anda seharusnya sudah menerima salinan GNU General Public License bersamaan 16 | dengan Wangsamas-Firmware. Jika tidak, lihat . 17 | 18 | Firmware ini berdasarkan Repetier-Firmware yang berdasarkan Sprinter firmware 19 | yang berdasarkan Tonokip Reprap firmware yang berdasarkan Hydra-mmm firmware. 20 | 21 | --------------------- 22 | 23 | This file is part of Wangsamas-Firmware by Kusuma Ruslan. 24 | 25 | Wangsamas-Firmware is free software: you can redistribute it and/or modify 26 | it under the terms of the GNU General Public License as published by 27 | the Free Software Foundation, either version 3 of the License, or 28 | (at your option) any later version. 29 | 30 | Wangsamas-Firmware is distributed in the hope that it will be useful, 31 | but WITHOUT ANY WARRANTY; without even the implied warranty of 32 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 33 | GNU General Public License for more details. 34 | 35 | You should have received a copy of the GNU General Public License 36 | along with Wangsamas-Firmware. If not, see . 37 | 38 | This firmware is based on Repetier-Firmware which based on sprinter firmware 39 | which based on Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware. 40 | 41 | Functions in this file are used to communicate using ascii or repetier protocol. 42 | */ 43 | 44 | #ifndef MOTION_H_INCLUDED 45 | #define MOTION_H_INCLUDED 46 | 47 | /** Marks the first step of a new move */ 48 | #define FLAG_WARMUP 1 49 | #define FLAG_NOMINAL 2 50 | #define FLAG_DECELERATING 4 51 | #define FLAG_ACCELERATION_ENABLED 8 // unused 52 | #define FLAG_CHECK_ENDSTOPS 16 53 | #define FLAG_ALL_E_MOTORS 32 // For mixed extruder move all motors instead of selected motor 54 | #define FLAG_SKIP_DEACCELERATING 64 // unused 55 | #define FLAG_BLOCKED 128 56 | 57 | /** Are the step parameter computed */ 58 | #define FLAG_JOIN_STEPPARAMS_COMPUTED 1 59 | /** The right speed is fixed. Don't check this block or any block to the left. */ 60 | #define FLAG_JOIN_END_FIXED 2 61 | /** The left speed is fixed. Don't check left block. */ 62 | #define FLAG_JOIN_START_FIXED 4 63 | /** Start filament retraction at move start */ 64 | #define FLAG_JOIN_START_RETRACT 8 65 | /** Wait for filament push back, before ending move */ 66 | #define FLAG_JOIN_END_RETRACT 16 67 | /** Disable retract for this line */ 68 | #define FLAG_JOIN_NO_RETRACT 32 69 | /** Wait for the extruder to finish it's up movement */ 70 | #define FLAG_JOIN_WAIT_EXTRUDER_UP 64 71 | /** Wait for the extruder to finish it's down movement */ 72 | #define FLAG_JOIN_WAIT_EXTRUDER_DOWN 128 73 | // Printing related data 74 | #if NONLINEAR_SYSTEM 75 | // Allow the delta cache to store segments for every line in line cache. Beware this gets big ... fast. 76 | 77 | class PrintLine; 78 | typedef struct 79 | { 80 | flag8_t dir; ///< Direction of delta movement. 81 | uint16_t deltaSteps[TOWER_ARRAY]; ///< Number of steps in move. 82 | inline bool checkEndstops(PrintLine *cur,bool checkall); 83 | inline void setXMoveFinished() 84 | { 85 | dir &= ~XSTEP; 86 | } 87 | inline void setYMoveFinished() 88 | { 89 | dir &= ~YSTEP; 90 | } 91 | inline void setZMoveFinished() 92 | { 93 | dir &= ~ZSTEP; 94 | } 95 | inline void setXYMoveFinished() 96 | { 97 | dir &= ~XY_STEP; 98 | } 99 | inline bool isXPositiveMove() 100 | { 101 | return (dir & X_STEP_DIRPOS) == X_STEP_DIRPOS; 102 | } 103 | inline bool isXNegativeMove() 104 | { 105 | return (dir & X_STEP_DIRPOS) == XSTEP; 106 | } 107 | inline bool isYPositiveMove() 108 | { 109 | return (dir & Y_STEP_DIRPOS) == Y_STEP_DIRPOS; 110 | } 111 | inline bool isYNegativeMove() 112 | { 113 | return (dir & Y_STEP_DIRPOS) == YSTEP; 114 | } 115 | inline bool isZPositiveMove() 116 | { 117 | return (dir & Z_STEP_DIRPOS) == Z_STEP_DIRPOS; 118 | } 119 | inline bool isZNegativeMove() 120 | { 121 | return (dir & Z_STEP_DIRPOS) == ZSTEP; 122 | } 123 | inline bool isEPositiveMove() 124 | { 125 | return (dir & E_STEP_DIRPOS) == E_STEP_DIRPOS; 126 | } 127 | inline bool isENegativeMove() 128 | { 129 | return (dir & E_STEP_DIRPOS) == ESTEP; 130 | } 131 | inline bool isXMove() 132 | { 133 | return (dir & XSTEP); 134 | } 135 | inline bool isYMove() 136 | { 137 | return (dir & YSTEP); 138 | } 139 | inline bool isXOrYMove() 140 | { 141 | return dir & XY_STEP; 142 | } 143 | inline bool isZMove() 144 | { 145 | return (dir & ZSTEP); 146 | } 147 | inline bool isEMove() 148 | { 149 | return (dir & ESTEP); 150 | } 151 | inline bool isEOnlyMove() 152 | { 153 | return (dir & XYZE_STEP)==ESTEP; 154 | } 155 | inline bool isNoMove() 156 | { 157 | return (dir & XYZE_STEP) == 0; 158 | } 159 | inline bool isXYZMove() 160 | { 161 | return dir & XYZ_STEP; 162 | } 163 | inline bool isMoveOfAxis(uint8_t axis) 164 | { 165 | return (dir & (XSTEP< inside interrupt handle 481 | inline void updateAdvanceSteps(speed_t v, uint8_t max_loops, bool accelerate) 482 | { 483 | #if USE_ADVANCE 484 | if(!Printer::isAdvanceActivated()) return; 485 | #if ENABLE_QUADRATIC_ADVANCE 486 | long advanceTarget = Printer::advanceExecuted; 487 | if(accelerate) 488 | { 489 | for(uint8_t loop = 0; loop < max_loops; loop++) advanceTarget += advanceRate; 490 | if(advanceTarget > advanceFull) 491 | advanceTarget = advanceFull; 492 | } 493 | else 494 | { 495 | for(uint8_t loop = 0; loop < max_loops; loop++) advanceTarget -= advanceRate; 496 | if(advanceTarget < advanceEnd) 497 | advanceTarget = advanceEnd; 498 | } 499 | long h = HAL::mulu16xu16to32(v, advanceL); 500 | int tred = ((advanceTarget + h) >> 16); 501 | HAL::forbidInterrupts(); 502 | Printer::extruderStepsNeeded += tred - Printer::advanceStepsSet; 503 | if(tred > 0 && Printer::advanceStepsSet <= 0) 504 | Printer::extruderStepsNeeded += Extruder::current->advanceBacklash; 505 | else if(tred < 0 && Printer::advanceStepsSet >= 0) 506 | Printer::extruderStepsNeeded -= Extruder::current->advanceBacklash; 507 | Printer::advanceStepsSet = tred; 508 | HAL::allowInterrupts(); 509 | Printer::advanceExecuted = advanceTarget; 510 | #else 511 | int tred = HAL::mulu6xu16shift16(v, advanceL); 512 | HAL::forbidInterrupts(); 513 | Printer::extruderStepsNeeded += tred - Printer::advanceStepsSet; 514 | if(tred > 0 && Printer::advanceStepsSet <= 0) 515 | Printer::extruderStepsNeeded += (Extruder::current->advanceBacklash << 1); 516 | else if(tred < 0 && Printer::advanceStepsSet >= 0) 517 | Printer::extruderStepsNeeded -= (Extruder::current->advanceBacklash << 1); 518 | Printer::advanceStepsSet = tred; 519 | HAL::allowInterrupts(); 520 | #endif 521 | #endif 522 | } 523 | INLINE bool moveDecelerating() 524 | { 525 | if(stepsRemaining <= decelSteps) 526 | { 527 | if (!(flags & FLAG_DECELERATING)) 528 | { 529 | Printer::timer = 0; 530 | flags |= FLAG_DECELERATING; 531 | } 532 | return true; 533 | } 534 | else return false; 535 | } 536 | INLINE bool moveAccelerating() 537 | { 538 | return Printer::stepNumber <= accelSteps; 539 | } 540 | INLINE void startXStep() 541 | { 542 | #if !(GANTRY) || defined(FAST_COREXYZ) 543 | Printer::startXStep(); 544 | #else 545 | #if DRIVE_SYSTEM == XY_GANTRY || DRIVE_SYSTEM == XZ_GANTRY 546 | if(isXPositiveMove()) 547 | { 548 | Printer::motorX++; 549 | Printer::motorYorZ++; 550 | } 551 | else 552 | { 553 | Printer::motorX--; 554 | Printer::motorYorZ--; 555 | } 556 | #endif 557 | #if DRIVE_SYSTEM == YX_GANTRY || DRIVE_SYSTEM == ZX_GANTRY 558 | if(isXPositiveMove()) 559 | { 560 | Printer::motorX++; 561 | Printer::motorYorZ--; 562 | } 563 | else 564 | { 565 | Printer::motorX--; 566 | Printer::motorYorZ++; 567 | } 568 | #endif 569 | #endif 570 | #ifdef DEBUG_STEPCOUNT 571 | totalStepsRemaining--; 572 | #endif 573 | } 574 | INLINE void startYStep() 575 | { 576 | #if !(GANTRY) || DRIVE_SYSTEM == ZX_GANTRY || DRIVE_SYSTEM == XZ_GANTRY || defined(FAST_COREXYZ) 577 | Printer::startYStep(); 578 | #else 579 | #if DRIVE_SYSTEM == XY_GANTRY 580 | if(isYPositiveMove()) 581 | { 582 | Printer::motorX++; 583 | Printer::motorYorZ--; 584 | } 585 | else 586 | { 587 | Printer::motorX--; 588 | Printer::motorYorZ++; 589 | } 590 | #endif 591 | #if DRIVE_SYSTEM == YX_GANTRY 592 | if(isYPositiveMove()) 593 | { 594 | Printer::motorX++; 595 | Printer::motorYorZ++; 596 | } 597 | else 598 | { 599 | Printer::motorX--; 600 | Printer::motorYorZ--; 601 | } 602 | #endif 603 | #endif // GANTRY 604 | #ifdef DEBUG_STEPCOUNT 605 | totalStepsRemaining--; 606 | #endif 607 | 608 | } 609 | INLINE void startZStep() 610 | { 611 | #if !(GANTRY) || DRIVE_SYSTEM == YX_GANTRY || DRIVE_SYSTEM == XY_GANTRY || defined(FAST_COREXYZ) 612 | Printer::startZStep(); 613 | #else 614 | #if DRIVE_SYSTEM == XZ_GANTRY 615 | if(isZPositiveMove()) 616 | { 617 | Printer::motorX++; 618 | Printer::motorYorZ--; 619 | } 620 | else 621 | { 622 | Printer::motorX--; 623 | Printer::motorYorZ++; 624 | } 625 | #endif 626 | #if DRIVE_SYSTEM == ZX_GANTRY 627 | if(isZPositiveMove()) 628 | { 629 | Printer::motorX++; 630 | Printer::motorYorZ++; 631 | } 632 | else 633 | { 634 | Printer::motorX--; 635 | Printer::motorYorZ--; 636 | } 637 | #endif 638 | #endif 639 | #ifdef DEBUG_STEPCOUNT 640 | totalStepsRemaining--; 641 | #endif 642 | } 643 | void updateStepsParameter(); 644 | float safeSpeed(fast8_t drivingAxis); 645 | void calculateMove(float axis_diff[],uint8_t pathOptimize,fast8_t distanceBase); 646 | void logLine(); 647 | INLINE long getWaitTicks() 648 | { 649 | return timeInTicks; 650 | } 651 | INLINE void setWaitTicks(long wait) 652 | { 653 | timeInTicks = wait; 654 | } 655 | 656 | static INLINE bool hasLines() 657 | { 658 | return linesCount; 659 | } 660 | static INLINE void setCurrentLine() 661 | { 662 | cur = &lines[linesPos]; 663 | #if CPU_ARCH==ARCH_ARM 664 | PrintLine::nlFlag = true; 665 | #endif 666 | } 667 | // Only called from within interrupts 668 | static INLINE void removeCurrentLineForbidInterrupt() 669 | { 670 | linesPos++; 671 | if(linesPos >= PRINTLINE_CACHE_SIZE) linesPos = 0; 672 | cur = NULL; 673 | #if CPU_ARCH == ARCH_ARM 674 | nlFlag = false; 675 | #endif 676 | HAL::forbidInterrupts(); 677 | --linesCount; 678 | if(!linesCount) 679 | Printer::setMenuMode(MENU_MODE_PRINTING, false); 680 | } 681 | static INLINE void pushLine() 682 | { 683 | linesWritePos++; 684 | if(linesWritePos >= PRINTLINE_CACHE_SIZE) linesWritePos = 0; 685 | Printer::setMenuMode(MENU_MODE_PRINTING, true); 686 | InterruptProtectedBlock noInts; 687 | linesCount++; 688 | } 689 | static uint8_t getLinesCount() 690 | { 691 | InterruptProtectedBlock noInts; 692 | return linesCount; 693 | } 694 | static PrintLine *getNextWriteLine() 695 | { 696 | return &lines[linesWritePos]; 697 | } 698 | static inline void computeMaxJunctionSpeed(PrintLine *previous,PrintLine *current); 699 | static int32_t bresenhamStep(); 700 | static void waitForXFreeLines(uint8_t b=1, bool allowMoves = false); 701 | static inline void forwardPlanner(ufast8_t p); 702 | static inline void backwardPlanner(ufast8_t p,ufast8_t last); 703 | static void updateTrapezoids(); 704 | static uint8_t insertWaitMovesIfNeeded(uint8_t pathOptimize, uint8_t waitExtraLines); 705 | #if !NONLINEAR_SYSTEM 706 | static void queueCartesianMove(uint8_t check_endstops,uint8_t pathOptimize); 707 | #if DISTORTION_CORRECTION 708 | static void queueCartesianSegmentTo(uint8_t check_endstops, uint8_t pathOptimize); 709 | #endif 710 | #endif 711 | static void moveRelativeDistanceInSteps(int32_t x,int32_t y,int32_t z,int32_t e,float feedrate,bool waitEnd,bool check_endstop,bool pathOptimize = true); 712 | static void moveRelativeDistanceInStepsReal(int32_t x,int32_t y,int32_t z,int32_t e,float feedrate,bool waitEnd,bool pathOptimize = true); 713 | static void rotateInSteps(int32_t x,int32_t y,float feedrate,bool waitEnd,bool check_endstop,bool pathOptimize = true); // Kusuma SCARA 714 | static void rotateInStepsNoCheck(int32_t x,int32_t y,float feedrate,bool waitEnd,bool check_endstop,bool pathOptimize = true); // Kusuma SCARA 715 | #if ARC_SUPPORT 716 | static void arc(float *position, float *target, float *offset, float radius, uint8_t isclockwise); 717 | #endif 718 | static INLINE void previousPlannerIndex(ufast8_t &p) 719 | { 720 | p = (p ? p - 1 : PRINTLINE_CACHE_SIZE - 1); 721 | } 722 | static INLINE void nextPlannerIndex(ufast8_t& p) 723 | { 724 | p = (p == PRINTLINE_CACHE_SIZE - 1 ? 0 : p + 1); 725 | } 726 | #if NONLINEAR_SYSTEM 727 | static uint8_t queueNonlinearMove(uint8_t check_endstops,uint8_t pathOptimize, uint8_t softEndstop); 728 | static uint8_t queueRotation(uint8_t check_endstops,uint8_t pathOptimize, uint8_t softEndstop); // Kusuma SCARA 729 | inline uint16_t calculateRotationSubSegments(uint8_t softEndstop); // Kusuma SCARA 730 | static inline void queueEMove(int32_t e_diff,uint8_t check_endstops,uint8_t pathOptimize); 731 | inline uint16_t calculateNonlinearSubSegments(uint8_t softEndstop); 732 | static inline void calculateDirectionAndDelta(int32_t difference[], ufast8_t *dir, int32_t delta[]); 733 | static inline uint8_t calculateDistance(float axis_diff[], uint8_t dir, float *distance); 734 | #if SOFTWARE_LEVELING && DRIVE_SYSTEM == DELTA 735 | static void calculatePlane(int32_t factors[], int32_t p1[], int32_t p2[], int32_t p3[]); 736 | static float calcZOffset(int32_t factors[], int32_t pointX, int32_t pointY); 737 | #endif 738 | #endif 739 | }; 740 | 741 | 742 | 743 | #endif // MOTION_H_INCLUDED 744 | -------------------------------------------------------------------------------- /Wangsamas/HAL.h: -------------------------------------------------------------------------------- 1 | /* 2 | Berkas ini adalah bagian dari Wangsamas-Firmware oleh Kusuma Ruslan. 3 | 4 | Wangsamas-Firmware adalah perangkat lunak bebas: 5 | Anda dapat mendistribusikannya dan/atau mengubahnya 6 | dengan syarat dan ketentuan GNU General Public License 7 | yang dipublikasikan oleh Free Software Foundation, 8 | baik ijin versi 3, atau (menurut pilihanmu) versi yang terbaru. 9 | 10 | Wangsamas-Firmware didistribusikan dengan harapan agar dapat bermanfaat, 11 | tetapi TANPA JAMINAN; bahkan tanpa jaminan tersirat PERDAGANGAN atau 12 | KECOCOKAN UNTUK TUJUAN TERTENTU. Lihat GNU General Public License 13 | untuk keterangan lebih lanjut. 14 | 15 | Anda seharusnya sudah menerima salinan GNU General Public License bersamaan 16 | dengan Wangsamas-Firmware. Jika tidak, lihat . 17 | 18 | Firmware ini berdasarkan Repetier-Firmware yang berdasarkan Sprinter firmware 19 | yang berdasarkan Tonokip Reprap firmware yang berdasarkan Hydra-mmm firmware. 20 | 21 | --------------------- 22 | 23 | This file is part of Wangsamas-Firmware by Kusuma Ruslan. 24 | 25 | Wangsamas-Firmware is free software: you can redistribute it and/or modify 26 | it under the terms of the GNU General Public License as published by 27 | the Free Software Foundation, either version 3 of the License, or 28 | (at your option) any later version. 29 | 30 | Wangsamas-Firmware is distributed in the hope that it will be useful, 31 | but WITHOUT ANY WARRANTY; without even the implied warranty of 32 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 33 | GNU General Public License for more details. 34 | 35 | You should have received a copy of the GNU General Public License 36 | along with Wangsamas-Firmware. If not, see . 37 | 38 | This firmware is based on Repetier-Firmware which based on sprinter firmware 39 | which based on Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware. 40 | Functions in this file are used to communicate using ascii or repetier protocol. 41 | */ 42 | 43 | #ifndef HAL_H 44 | #define HAL_H 45 | 46 | /** 47 | This is the main Hardware Abstraction Layer (HAL). 48 | To make the firmware work with different processors and toolchains, 49 | all hardware related code should be packed into the hal files. 50 | */ 51 | 52 | #include 53 | #include 54 | 55 | 56 | #define INLINE __attribute__((always_inline)) 57 | 58 | #if CPU_ARCH == ARCH_AVR 59 | #include 60 | #else 61 | #define PROGMEM 62 | #define PGM_P const char * 63 | #define PSTR(s) s 64 | #define pgm_read_byte_near(x) (*(uint8_t*)x) 65 | #define pgm_read_byte(x) (*(uint8_t*)x) 66 | #endif 67 | 68 | #define PACK 69 | 70 | #define FSTRINGVALUE(var,value) const char var[] PROGMEM = value; 71 | #define FSTRINGVAR(var) static const char var[] PROGMEM; 72 | #define FSTRINGPARAM(var) PGM_P var 73 | 74 | #include 75 | #include 76 | /** \brief Prescale factor, timer0 runs at. 77 | 78 | All known arduino boards use 64. This value is needed for the extruder timing. */ 79 | #define TIMER0_PRESCALE 64 80 | 81 | #define ANALOG_PRESCALER _BV(ADPS0)|_BV(ADPS1)|_BV(ADPS2) 82 | 83 | #if MOTHERBOARD==8 || MOTHERBOARD==88 || MOTHERBOARD==9 || MOTHERBOARD==92 || CPU_ARCH!=ARCH_AVR 84 | #define EXTERNALSERIAL 85 | #endif 86 | //#define EXTERNALSERIAL // Force using arduino serial 87 | #ifndef EXTERNALSERIAL 88 | #define HardwareSerial_h // Don't use standard serial console 89 | #endif 90 | #include 91 | #include "Print.h" 92 | #ifdef EXTERNALSERIAL 93 | #define SERIAL_RX_BUFFER_SIZE 128 94 | #endif 95 | #if defined(ARDUINO) && ARDUINO >= 100 96 | #include "Arduino.h" 97 | #else 98 | #include "WProgram.h" 99 | #define COMPAT_PRE1 100 | #endif 101 | #if CPU_ARCH==ARCH_AVR 102 | #include "fastio.h" 103 | #else 104 | #define READ(IO) digitalRead(IO) 105 | #define WRITE(IO, v) digitalWrite(IO, v) 106 | #define SET_INPUT(IO) pinMode(IO, INPUT) 107 | #define SET_OUTPUT(IO) pinMode(IO, OUTPUT) 108 | #endif 109 | 110 | class InterruptProtectedBlock 111 | { 112 | uint8_t sreg; 113 | public: 114 | inline void protect() 115 | { 116 | cli(); 117 | } 118 | 119 | inline void unprotect() 120 | { 121 | SREG = sreg; 122 | } 123 | 124 | inline InterruptProtectedBlock(bool later = false) 125 | { 126 | sreg = SREG; 127 | if(!later) 128 | cli(); 129 | } 130 | 131 | inline ~InterruptProtectedBlock() 132 | { 133 | SREG = sreg; 134 | } 135 | }; 136 | 137 | #define EEPROM_OFFSET 0 138 | #define SECONDS_TO_TICKS(s) (unsigned long)(s*(float)F_CPU) 139 | #define ANALOG_INPUT_SAMPLE 5 140 | // Bits of the ADC converter 141 | #define ANALOG_INPUT_BITS 10 142 | #define ANALOG_REDUCE_BITS 0 143 | #define ANALOG_REDUCE_FACTOR 1 144 | 145 | #define MAX_RAM 32767 146 | 147 | #define bit_clear(x,y) x&= ~(1<>8)*cur->accel)>>10; 448 | return res; 449 | #else 450 | return ((timer >> 8) * accel) >> 10; 451 | #endif 452 | } 453 | // Multiply two 16 bit values and return 32 bit result 454 | static inline uint32_t mulu16xu16to32(unsigned int a,unsigned int b) 455 | { 456 | uint32_t res; 457 | // 18 Ticks = 1.125 us 458 | __asm__ __volatile__ ( // 0 = res, 1 = timer, 2 = accel %D2=0 ,%A1 are unused is free 459 | // Result LSB first: %A0, %B0, %A1 460 | "clr r18 \n\t" 461 | "mul %B2,%B1 \n\t" // mul hig bytes 462 | "movw %C0,r0 \n\t" 463 | "mul %A1,%A2 \n\t" // mul low bytes 464 | "movw %A0,r0 \n\t" 465 | "mul %A1,%B2 \n\t" 466 | "add %B0,r0 \n\t" 467 | "adc %C0,r1 \n\t" 468 | "adc %D0,r18 \n\t" 469 | "mul %B1,%A2 \n\t" 470 | "add %B0,r0 \n\t" 471 | "adc %C0,r1 \n\t" 472 | "adc %D0,r18 \n\t" 473 | "clr r1 \n\t" 474 | :"=&r"(res),"=r"(a),"=r"(b) 475 | :"1"(a),"2"(b) 476 | :"r18" ); 477 | // return (long)a*b; 478 | return res; 479 | } 480 | // Multiply two 16 bit values and return 32 bit result 481 | static inline unsigned int mulu6xu16shift16(unsigned int a,unsigned int b) 482 | { 483 | #if CPU_ARCH == ARCH_AVR 484 | unsigned int res; 485 | // 18 Ticks = 1.125 us 486 | __asm__ __volatile__ ( // 0 = res, 1 = timer, 2 = accel %D2=0 ,%A1 are unused is free 487 | // Result LSB first: %A0, %B0, %A1 488 | "clr r18 \n\t" 489 | "mul %B2,%B1 \n\t" // mul hig bytes 490 | "movw %A0,r0 \n\t" 491 | "mul %A1,%A2 \n\t" // mul low bytes 492 | "mov r19,r1 \n\t" 493 | "mul %A1,%B2 \n\t" 494 | "add r19,r0 \n\t" 495 | "adc %A0,r1 \n\t" 496 | "adc %B0,r18 \n\t" 497 | "mul %B1,%A2 \n\t" 498 | "add r19,r0 \n\t" 499 | "adc %A0,r1 \n\t" 500 | "adc %B0,r18 \n\t" 501 | "clr r1 \n\t" 502 | :"=&r"(res),"=r"(a),"=r"(b) 503 | :"1"(a),"2"(b) 504 | :"r18","r19" ); 505 | return res; 506 | #else 507 | return ((int32_t)a * b) >> 16; 508 | #endif 509 | } 510 | static inline void digitalWrite(uint8_t pin,uint8_t value) 511 | { 512 | ::digitalWrite(pin,value); 513 | } 514 | static inline uint8_t digitalRead(uint8_t pin) 515 | { 516 | return ::digitalRead(pin); 517 | } 518 | static inline void pinMode(uint8_t pin,uint8_t mode) 519 | { 520 | ::pinMode(pin,mode); 521 | } 522 | static int32_t CPUDivU2(unsigned int divisor); 523 | static inline void delayMicroseconds(unsigned int delayUs) 524 | { 525 | ::delayMicroseconds(delayUs); 526 | } 527 | static inline void delayMilliseconds(unsigned int delayMs) 528 | { 529 | ::delay(delayMs); 530 | } 531 | static inline void tone(uint8_t pin,int duration) 532 | { 533 | ::tone(pin,duration); 534 | } 535 | static inline void noTone(uint8_t pin) 536 | { 537 | ::noTone(pin); 538 | } 539 | static inline void eprSetByte(unsigned int pos,uint8_t value) 540 | { 541 | eeprom_write_byte((unsigned char *)(EEPROM_OFFSET + pos), value); 542 | } 543 | static inline void eprSetInt16(unsigned int pos,int16_t value) 544 | { 545 | eeprom_write_word((unsigned int*)(EEPROM_OFFSET + pos),value); 546 | } 547 | static inline void eprSetInt32(unsigned int pos,int32_t value) 548 | { 549 | eeprom_write_dword((uint32_t*)(EEPROM_OFFSET + pos),value); 550 | } 551 | static inline void eprSetFloat(unsigned int pos,float value) 552 | { 553 | eeprom_write_block(&value,(void*)(EEPROM_OFFSET + pos), 4); 554 | } 555 | static inline uint8_t eprGetByte(unsigned int pos) 556 | { 557 | return eeprom_read_byte ((unsigned char *)(EEPROM_OFFSET + pos)); 558 | } 559 | static inline int16_t eprGetInt16(unsigned int pos) 560 | { 561 | return eeprom_read_word((uint16_t *)(EEPROM_OFFSET + pos)); 562 | } 563 | static inline int32_t eprGetInt32(unsigned int pos) 564 | { 565 | return eeprom_read_dword((uint32_t*)(EEPROM_OFFSET + pos)); 566 | } 567 | static inline float eprGetFloat(unsigned int pos) 568 | { 569 | float v; 570 | eeprom_read_block(&v,(void *)(EEPROM_OFFSET + pos),4); // newer gcc have eeprom_read_block but not arduino 22 571 | return v; 572 | } 573 | 574 | // Faster version of InterruptProtectedBlock. 575 | // For safety it ma yonly be called from within an 576 | // interrupt handler. 577 | static inline void allowInterrupts() 578 | { 579 | sei(); 580 | } 581 | 582 | // Faster version of InterruptProtectedBlock. 583 | // For safety it ma yonly be called from within an 584 | // interrupt handler. 585 | static inline void forbidInterrupts() 586 | { 587 | cli(); 588 | } 589 | static inline unsigned long timeInMilliseconds() 590 | { 591 | return millis(); 592 | } 593 | static inline char readFlashByte(PGM_P ptr) 594 | { 595 | return pgm_read_byte(ptr); 596 | } 597 | static inline void serialSetBaudrate(long baud) 598 | { 599 | RFSERIAL.begin(baud); 600 | } 601 | static inline bool serialByteAvailable() 602 | { 603 | return RFSERIAL.available() > 0; 604 | } 605 | static inline uint8_t serialReadByte() 606 | { 607 | return RFSERIAL.read(); 608 | } 609 | static inline void serialWriteByte(char b) 610 | { 611 | RFSERIAL.write(b); 612 | } 613 | static inline void serialFlush() 614 | { 615 | RFSERIAL.flush(); 616 | } 617 | static void setupTimer(); 618 | static void showStartReason(); 619 | static int getFreeRam(); 620 | static void resetHardware(); 621 | 622 | // SPI related functions 623 | static void spiBegin() 624 | { 625 | #if SDSS >= 0 626 | SET_INPUT(MISO_PIN); 627 | SET_OUTPUT(MOSI_PIN); 628 | SET_OUTPUT(SCK_PIN); 629 | // SS must be in output mode even it is not chip select 630 | SET_OUTPUT(SDSS); 631 | #if SDSSORIG >- 1 632 | SET_OUTPUT(SDSSORIG); 633 | #endif 634 | // set SS high - may be chip select for another SPI device 635 | #if defined(SET_SPI_SS_HIGH) && SET_SPI_SS_HIGH 636 | WRITE(SDSS, HIGH); 637 | #endif // SET_SPI_SS_HIGH 638 | #endif 639 | } 640 | static inline void spiInit(uint8_t spiRate) 641 | { 642 | uint8_t r = 0; 643 | for (uint8_t b = 2; spiRate > b && r < 6; b <<= 1, r++); 644 | 645 | SET_OUTPUT(SS); 646 | WRITE(SS,HIGH); 647 | SET_OUTPUT(SCK); 648 | SET_OUTPUT(MOSI_PIN); 649 | SET_INPUT(MISO_PIN); 650 | #ifdef PRR 651 | PRR &= ~(1<> 1); 657 | SPSR = (r & 1 || r == 6 ? 0 : 1) << SPI2X; 658 | 659 | } 660 | static inline uint8_t spiReceive(uint8_t send=0xff) 661 | { 662 | SPDR = send; 663 | while (!(SPSR & (1 << SPIF))) {} 664 | return SPDR; 665 | } 666 | static inline void spiReadBlock(uint8_t*buf,size_t nbyte) 667 | { 668 | if (nbyte-- == 0) return; 669 | SPDR = 0XFF; 670 | for (size_t i = 0; i < nbyte; i++) 671 | { 672 | while (!(SPSR & (1 << SPIF))) {} 673 | buf[i] = SPDR; 674 | SPDR = 0XFF; 675 | } 676 | while (!(SPSR & (1 << SPIF))) {} 677 | buf[nbyte] = SPDR; 678 | } 679 | static inline void spiSend(uint8_t b) 680 | { 681 | SPDR = b; 682 | while (!(SPSR & (1 << SPIF))) {} 683 | } 684 | static inline void spiSend(const uint8_t* buf , size_t n) 685 | { 686 | if (n == 0) return; 687 | SPDR = buf[0]; 688 | if (n > 1) 689 | { 690 | uint8_t b = buf[1]; 691 | size_t i = 2; 692 | while (1) 693 | { 694 | while (!(SPSR & (1 << SPIF))) {} 695 | SPDR = b; 696 | if (i == n) break; 697 | b = buf[i++]; 698 | } 699 | } 700 | while (!(SPSR & (1 << SPIF))) {} 701 | } 702 | 703 | static inline __attribute__((always_inline)) 704 | void spiSendBlock(uint8_t token, const uint8_t* buf) 705 | { 706 | SPDR = token; 707 | for (uint16_t i = 0; i < 512; i += 2) 708 | { 709 | while (!(SPSR & (1 << SPIF))) {} 710 | SPDR = buf[i]; 711 | while (!(SPSR & (1 << SPIF))) {} 712 | SPDR = buf[i + 1]; 713 | } 714 | while (!(SPSR & (1 << SPIF))) {} 715 | } 716 | 717 | // I2C Support 718 | 719 | static void i2cInit(uint32_t clockSpeedHz); 720 | static unsigned char i2cStart(uint8_t address); 721 | static void i2cStartWait(uint8_t address); 722 | static void i2cStop(void); 723 | static uint8_t i2cWrite( uint8_t data ); 724 | static uint8_t i2cReadAck(void); 725 | static uint8_t i2cReadNak(void); 726 | 727 | // Watchdog support 728 | 729 | inline static void startWatchdog() 730 | { 731 | #if defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__) 732 | WDTCSR = (1<