Some cleanup and fixes.

coil_winder
Marcin K 2018-07-12 02:05:39 +02:00
rodzic c56dcf211a
commit e84439a329
14 zmienionych plików z 453 dodań i 113 usunięć

9
.gitignore vendored
Wyświetl plik

@ -1,6 +1,7 @@
*.d
buildnumber.num
depend
*.o
*.gz
*.tar
*.d
*.eep
*.elf
*swp
*.hex

129
Makefile
Wyświetl plik

@ -1,77 +1,72 @@
OBJECTS=main.o error.o init.o lexer.o parser.o symbol.o
# This makefile for now is used to build executable for simavr for debbuging.
# Click & forget arduino IDE should deal with mcu flashing.
# MCU ?= atmega168
# MCU ?= atmega328p
#MCU ?= atmega644
# MCU ?= atmega644
# MCU ?= atmega1284p
# MCU ?= atmega1280
# MCU ?= atmega2560
# MCU ?= at90usb1286
MCU ?= atmega32
# CPU clock rate
# F_CPU ?= 8000000L
F_CPU ?= 16000000L
# F_CPU ?= 20000000L
ARDUINO_CORE = /usr/share/arduino/hardware/arduino/avr/cores/MightyCore
ARDUINO_VARIANT = /usr/share/arduino/hardware/arduino/avr/variants/mega32
#avr gcc
CC = avr-gcc
#avr objeccopy
OBJCOPY = avr-objcopy
CFLAGS = -w -std=gnu++11 -Os -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -DF_CPU=16000000L -I$(ARDUINO_CORE) -I$(ARDUINO_VARIANT)
CFLAGS += -mmcu=$(MCU)
SIMULFLAGS = -Wl,--section-start=.siminfo=0x900000
#debug?
CFLAGS += -g
OBJFLAG = -O ihex
elf:
avr-g++ -c -g -Os -w -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -w -x c++ -M -MG -MP -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 motor_control.ino
EXECUTABLE = teathimble
SOURCES = ${wildcard *.cpp $(ARDUINO_CORE)/main.cpp $(ARDUINO_CORE)/wiring.c $(ARDUINO_CORE)/hooks.c}
HEADERS = ${wildcard *.h}
OBJECTS = ${SOURCES:.c=.o}
avr-g++ -c -g -Os -w -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -w -x c++ -M -MG -MP -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 motor_control.ino
.PHONY: all
all: ${EXECUTABLE}
avr-g++ -c -g -Os -w -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -w -x c++ -M -MG -MP -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 motor_control.ino
$(EXECUTABLE): $(OBJECTS) buildnumber.num
$(CC) $(CFLAGS) $(SIMULFLAGS) -o $(EXECUTABLE).elf $(OBJECTS) -lm
$(OBJCOPY) $(OBJFLAG) -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 $(EXECUTABLE).elf $(EXECUTABLE).eep
avr-g++ -c -g -Os -w -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -w -x c++ -M -MG -MP -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 motor_control.ino
$(OBJCOPY) $(OBJFLAG) -R .eeprom $(EXECUTABLE).elf $(EXECUTABLE).hex
@echo "-- Build: " $$(cat buildnumber.num)
avr-g++ -c -g -Os -w -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -w -x c++ -M -MG -MP -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 debug.cpp
depend: $(SOURCES)
@echo "calling depend"
$(CC) $(CFLAGS) -Os -c -MM $^ > $@
avr-g++ -c -g -Os -w -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -w -x c++ -M -MG -MP -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 gcode_parser.cpp
-include depend
avr-g++ -c -g -Os -w -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -w -x c++ -M -MG -MP -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 kinematics.cpp
# Buildnumber administratie
buildnumber.num: $(OBJECTS)
@if ! test -f buildnumber.num; then echo 0 > buildnumber.num; fi
@echo $$(($$(cat buildnumber.num)+1)) > buildnumber.num
avr-g++ -c -g -Os -w -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -w -x c++ -M -MG -MP -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 maths.cpp
# Create a clean environment
.PHONY: clean
clean:
$(RM) $(EXECUTABLE)
avr-g++ -c -g -Os -w -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -w -x c++ -M -MG -MP -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 motor.cpp
avr-g++ -c -g -Os -w -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -w -x c++ -M -MG -MP -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 motor_control.ino
avr-g++ -c -g -Os -w -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -w -x c++ -M -MG -MP -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 msg.cpp
avr-g++ -c -g -Os -w -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -w -x c++ -M -MG -MP -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 pinio.cpp
avr-g++ -c -g -Os -w -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -w -x c++ -M -MG -MP -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 queue.cpp
avr-g++ -c -g -Os -w -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -w -x c++ -M -MG -MP -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 serial.cpp
avr-g++ -c -g -Os -w -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -w -x c++ -M -MG -MP -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 timer-avr.cpp
avr-g++ -c -g -Os -w -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -w -x c++ -E -CC -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 motor_control.ino
avr-g++ -c -g -Os -Wall -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 debug.cpp -o debug.cpp.o
avr-g++ -c -g -Os -Wall -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 gcode_parser.cpp -o gcode_parser.cpp.o
avr-g++ -c -g -Os -Wall -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 kinematics.cpp -o kinematics.cpp.o
avr-g++ -c -g -Os -Wall -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 maths.cpp -o maths.cpp.o
avr-g++ -c -g -Os -Wall -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 motor.cpp -o motor.cpp.o
avr-g++ -c -g -Os -Wall -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 motor_control.ino -o motor_control.ino.o
avr-g++ -c -g -Os -Wall -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 msg.cpp -o msg.cpp.o
avr-g++ -c -g -Os -Wall -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 pinio.cpp -o pinio.cpp.o
avr-g++ -c -g -Os -Wall -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 queue.cpp -o queue.cpp.o
avr-g++ -c -g -Os -Wall -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 serial.cpp -o serial.cpp.o
avr-g++ -c -g -Os -Wall -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 timer-avr.cpp -o timer-avr.cpp.o
avr-g++ -c -g -Os -Wall -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 motor_control.ino.cpp -o motor_control.ino.cpp.o
avr-g++ -c -g -Os -Wall -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 motion_planner.cpp -o motion_planner.cpp.o
avr-g++ -c -g -Os -Wall -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 /usr/share/arduino/hardware/arduino/avr/cores/MightyCore/main.cpp -o main.cpp.o
avr-g++ -c -g -Os -Wall -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 /usr/share/arduino/hardware/arduino/avr/cores/MightyCore/wiring.c -o wiring.o
avr-gcc -c -g -Os -Wall -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=atmega32 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_ATmega32 -DARDUINO_ARCH_AVR -I/usr/share/arduino/hardware/arduino/avr/cores/MightyCore -I/usr/share/arduino/hardware/arduino/avr/variants/mega32 /usr/share/arduino/hardware/arduino/avr/cores/MightyCore/hooks.c -o hooks.o
#avr-gcc -Wall -Os -Wl,--gc-sections -mmcu=atmega32 -o motor_control.ino.elf debug.cpp.o gcode_parser.cpp.o kinematics.cpp.o maths.cpp.o motor.cpp.o motor_control.ino.cpp.o msg.cpp.o pinio.cpp.o queue.cpp.o serial.cpp.o timer-avr.cpp.o motion_planner.cpp.o main.cpp.o wiring.o hooks.o -lm -Wl,--section-start=.siminfo=0x900000
avr-gcc -Wall -Os -Wl,--section-start=.siminfo=0x900000 -mmcu=atmega32 -o motor_control.ino.elf debug.cpp.o gcode_parser.cpp.o kinematics.cpp.o maths.cpp.o motor.cpp.o motor_control.ino.cpp.o msg.cpp.o pinio.cpp.o queue.cpp.o serial.cpp.o timer-avr.cpp.o motion_planner.cpp.o main.cpp.o wiring.o hooks.o -lm
hex: elf
avr-objcopy -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 motor_control.ino.elf motor_control.ino.eep
avr-objcopy -O ihex -R .eeprom motor_control.ino.elf motor_control.ino.hex
# Clean up dependency file
.PHONY: clean-depend
clean-depend: clean
$(RM) depend

33
README.md 100644
Wyświetl plik

@ -0,0 +1,33 @@
# Teathimble
Teathimble is a minimalistics firmware to control varity of stepper motor based machines. It runs on most AVR (so arduino as well) microcontrollers and fits into ATmega16 MCU, providing great base for many projects. Teathimble is a trimmed fork of [Teacup](https://github.com/Traumflug/Teacup_Firmware) - lean and efficient firmware for RepRap printers.
## Features
- Minimalistic code.
- Communication via buffered serial and text commands (G-code).
- True acceleration, interrupt based, with look-ahead and jerk calculation planning.
- Integer only math to save cpu cycles for performance boost.
- Up to 4 axis in straight or coreXY kinematics scheme.
- Decent performance: can run up to 48'000 evenly spaced steps/second on 20 MHz as mentioned by core developers.
## Work progress
Current code is checked on custom made arduino-like board top on ATmega32 to control automated [coil winding machine](https://gitlab.com/markol/Coil_winder). It is just a matter of formality to port configurations on other avaiable boards.
To run inside [simulator](https://reprap.org/wiki/SimulAVR) build project with enclosed makefile, you might also need [this arduino core](https://github.com/MCUdude/MightyCore) to turn custom board into arduino compatible.
## Source files description
Code is written in pure C, but source files are *.cpp* too keep it simple for arduino IDE.
| Name | Description |
|----------|:-------------:|
| config.h | Configuration definitions. |
|debug.cpp | Debugging aids. |
|gcode_parser.cpp| G-code interpreter, instructions and their actions definitions. |
|kinematics.cpp| Spearated code for different movement schemes. |
|maths.cpp| Calculation stuff, functions, constants, tables. |
|motion_planner.cpp| Ramping acceleration and lookahead related stuff. |
|motor.cpp| A rather complex block of math that figures out when to step each axis according to speed and acceleration profiles and received moves. |
|msg.cpp| For numbers parsing. |
|pinio.cpp| Initialise all I/O. |
|queue.cpp| The queue of moves received from the host. |
|serial.cpp| Serial buffers and communication management. |
|teathimble.ino.cpp| Code starts here. |
|teathimble.ino| Same as above, allows firmware to be built in Arduino IDE. |
|timer-avr.cpp| Timer management, used primarily by motor.c for timing steps. |

Wyświetl plik

@ -299,6 +299,12 @@ pins
// The PWM
// Port A isn't defined
#undef PA5
#define PA5_PIN PINA5
#define PA5_RPORT PINA
#define PA5_WPORT PORTA
#define PA5_PWM NULL
#define PA5_DDR DDRA
// Port B is fully available
#undef PB0

143
config.h
Wyświetl plik

@ -4,12 +4,28 @@
#include <Arduino.h>
#include "arduino_32U4.h"
/** \def KINEMATICS_STRAIGHT KINEMATICS_COREXY
This defines the type of kinematics your device uses. That's essential!
Valid values:
KINEMATICS_STRAIGHT
Motors move axis directions directly. This is the
traditional type, most popular. Set this for coil winding machine.
KINEMATICS_COREXY
A bot using CoreXY kinematics. Typical for CoreXY
are long and crossing toothed belts and a carriage
moving on the X-Y-plane.
*/
#define KINEMATICS_STRAIGHT
//#define KINEMATICS_COREXY
/** \def X_MIN X_MAX Y_MIN Y_MAX Z_MIN Z_MAX
Soft axis limits. Define them to your machine's size relative to what your
G-code considers to be the origin (typically the bed's center or the bed's
front left corner).
G-code considers to be the origin.
Note that relocating the origin at runtime with G92 will also relocate these
limits.
@ -18,23 +34,42 @@
about 250 bytes smaller. Enabling only some of them is perfectly fine.
Units: millimeters
Sane values: according to printer build room size
Sane values: according to device build room size
Valid range: -1000.0 to 1000.0
*/
/*
#define X_MIN 0.0
#define X_MAX 200.0
/**
* Note for coils winding machine:
* X axis is a winding motor
* Y axis is a wire guide motor
**/
//#define X_MIN 0.0
//#define X_MAX 200.0
#define Y_MIN 0.0
#define Y_MAX 200.0
#define Y_MAX 150.0
#define Z_MIN 0.0
#define Z_MAX 140.0
//#define Z_MIN 0.0
//#define Z_MAX 140.0
/** \def STEPS_PER_M_X STEPS_PER_M_Y STEPS_PER_M_Z STEPS_PER_M_E
Steps per meter ( = steps per mm * 1000 ), calculate these values
appropriate for your machine.
All numbers are integers, so no decimal point, please :-)
Valid range: 20 to 4'0960'000 (0.02 to 40960 steps/mm)
*/
/*steps per meter*/
#define STEPS_PER_M_X 1280000
#define STEPS_PER_M_Y 1280000
/**
* Note for coils winding machine:
* steps per 1000 reveloutions for Y winding motor
* X = 200 motor steps * 16 microsteps * 4 gear ratio * 1000 mm per meter
* Y = 48 motor steps * 16 microsteps * 1/1.0 M6 screw step * 1000 mm per meter
**/
#define STEPS_PER_M_X 12800000
#define STEPS_PER_M_Y 768000
/*#define STEPS_PER_M_Z 1280000
#define STEPS_PER_M_E 96271
*/
@ -42,33 +77,74 @@
Used when doing precision endstop search and as default feedrate.
(mm / min) 60 mm / min = 1 mm/sec
*/
#define SEARCH_FEEDRATE_X 400
#define SEARCH_FEEDRATE_Y 400
#define SEARCH_FEEDRATE_X 150
#define SEARCH_FEEDRATE_Y 150
//#define SEARCH_FEEDRATE_Z 400
/** \def MAXIMUM_FEEDRATE_X MAXIMUM_FEEDRATE_Y MAXIMUM_FEEDRATE_Z MAXIMUM_FEEDRATE_E
Used for G0 rapid moves and as a cap for all other feedrates. (mm / min)
*/
#define MAXIMUM_FEEDRATE_X 6000
#define MAXIMUM_FEEDRATE_Y 6000
#define MAXIMUM_FEEDRATE_X 180
#define MAXIMUM_FEEDRATE_Y 550
/*#define MAXIMUM_FEEDRATE_Z 6000
#define MAXIMUM_FEEDRATE_E 20000
*/
/** \def ACCELERATION
How fast to accelerate when using ACCELERATION_RAMPING. Start with 10 for
milling (high precision) or 1000 for printing.
High values affect aproximation accuracy for low speeds.
Units: mm/s^2
Useful range: 1 to 10'000
*/
#define ACCELERATION 100
#define ACCELERATION 10
/** \def ENDSTOP_CLEARANCE
When hitting an endstop, Teacup properly decelerates instead of doing an
aprupt stop to save your mechanics. Ineviteably, this means it overshoots
the endstop trigger point by some distance.
To deal with this, Teacup adapts homing movement speeds to what your
endstops can deal with. The higher the allowed acceleration ( = deceleration,
see #define ACCELERATION) and the more clearance the endstop comes with,
the faster Teacup will do homing movements.
Set here how many micrometers (mm * 1000) your endstop allows the carriage
to overshoot the trigger point. Typically 1000 or 2000 for mechanical
endstops, more for optical ones. You can set it to zero, in which case
SEARCH_FEEDRATE_{XYZ} is used, but expect very slow homing movements.
Units: micrometers
Sane values: 0 to 20000 (0 to 20 mm)
Valid range: 0 to 1000000
*/
#define ENDSTOP_CLEARANCE 2000
/** \def ENDSTOP_STEPS
Number of steps to run into the endstops intentionally. As endstops trigger
false alarm sometimes, Teacup debounces them by counting a number of
consecutive positives.
Use 4 or less for reliable endstops, 8 or even more for flaky ones.
Valid range: 1...255.
*/
#define ENDSTOP_STEPS 2
/** \def MILD_HOMING
Define this to prevent abrupt stop of movement when endstop is trigged. For lightweight mechanics
and low max speed or high acceleration values it is ok to keep this disabled.
*/
//#ifdef MILD_HOMING
/** \def LOOKAHEAD
Define this to enable look-ahead during *ramping* acceleration to smoothly
transition between moves instead of performing a dead stop every move.
Enabling look-ahead requires about 3600 bytes of flash memory.
*/
#define LOOKAHEAD
//#define LOOKAHEAD
/** \def MAX_JERK_X MAX_JERK_Y MAX_JERK_Z MAX_JERK_E
When performing look-ahead, we need to decide what an acceptable jerk to the
@ -114,11 +190,16 @@
*/
#define XONXOFF
/**************PINOUT****************/
/** \def PINOUT
***************PINOUT***************
* Here you can setup pin functions, depending on board configuration.
**/
#define X_STEP_PIN PC3 // 19 PC3
#define X_DIR_PIN PC2 // 18 PC2
#define X_MIN_PIN DIO3
//35 PA5
#define X_MIN_PIN PA5
#define X_MAX_PIN DIO2
#define X_ENABLE_PIN PC4 // 20 PC4
#define X_INVERT_DIR
@ -128,7 +209,8 @@
#define Y_STEP_PIN DIO9 //22 PC6
#define Y_DIR_PIN PC5 //21 PC5
#define Y_MIN_PIN DIO8
// 16 PD2
#define Y_MIN_PIN PD2
#define Y_MAX_PIN DIO7
#define Y_ENABLE_PIN DIO10 //23 PC7
#define Y_INVERT_DIR
@ -173,6 +255,18 @@
*/
#define MOVEBUFFER_SIZE 8
/** \def USE_INTERNAL_PULLUPS
Most controller chips feature internal pullup resistors on their input pins,
which get used for endstops by turning on this switch. Don't turn it on when
using endstops which need no pull resistor, e.g. optical endstops, because
pull resistors are counterproductive there.
One can't use USE_INTERNAL_PULLUPS and USE_INTERNAL_PULLDOWNS at the same
time, of course.
*/
#define USE_INTERNAL_PULLUPS
/** \def F_CPU
Actual CPU clock rate. #ifndef required for Arduino compatibility.
*/
@ -219,4 +313,9 @@ extern volatile uint8_t debug_flags;
#define BSS __attribute__ ((__section__ (".bss")))
#endif
#ifdef ENDSTOP_CLEARANCE
#define SEARCH_FAST (uint32_t)((double)60. * \
sqrt((double)2 * ACCELERATION * ENDSTOP_CLEARANCE / 1000.))
#endif
#endif /* _CONFIG_H */

Wyświetl plik

@ -1,5 +1,7 @@
#include "gcode_parser.h"
#include "queue.h"
#include "motor.h"
#include "pinio.h"
#include "serial.h"
#define IS_DIGIT(c) (c >= '0' && c <= '9')
@ -12,11 +14,12 @@
GCODE_PARAM params[8];
uint8_t current_parameter;
uint8_t option_all_relative = 0;
TARGET next_target;
// Parser is implemented as a finite state automata (DFA)
// This is pointer holds function with actions expected for current progress, each of these functions
// changes its value on state change
// represent one possible state
uint8_t (*current_state)(uint8_t c);
//a few state functions prototypes
@ -79,9 +82,15 @@ void parser_init()
next_target.f_multiplier = 256;
parser_reset();
}
// this function executes command after is parsed
void process_command()
// This function executes all possible commands after those are parsed
// Tinker with this to add new commands
uint8_t process_command()
{
DDA *dda;
uint8_t result = 0;
if (option_all_relative)
next_target.axis[X] = next_target.axis[Y] = 0;
for(int i = 1; i <= current_parameter; ++i)
{
switch(params[i].name)
@ -97,20 +106,121 @@ void process_command()
break;
}
}
// convert relative to absolute
if (option_all_relative) {
next_target.axis[X] += startpoint.axis[X];
next_target.axis[Y] += startpoint.axis[Y];
}
// params[0] is always a operation with code
switch(params[0].name)
{
case 'G':
//1
enqueue(&next_target);
switch(params[0].value)
{
case 1:
//? Example: G1
//?
//? Linear move
enqueue(&next_target); break;
case 28:
//? Example: G28
//?
//? home axis, y only
next_target.axis[X] = next_target.axis[Y] = 0;
home_pos_y();
// just set X axis pos as zero
current_position.axis[X] = startpoint.axis[X] = 0;
dda_new_startpoint();
break;
case 90:
//? Example: G90
//?
//? Absolute positioning
option_all_relative = 0;
break;
case 91:
//? Example: G91
//?
//? Relative positioning
option_all_relative = 1;
break;
default:
result = STATE_ERROR;
}
break;
case 'M':
//114
update_current_position();
sersendf_P(PSTR("X:%lq,Y:%lq,F:%lu\n"),
current_position.axis[X], current_position.axis[Y],
current_position.F);
switch(params[0].value)
{
case 0:
//? Example: M0
//?
//? Stop or unconditional stop
ATOMIC_START
dda = queue_current_movement();
if (dda != NULL)
{
update_current_position();
memcpy(&startpoint, &current_position, sizeof(TARGET));
dda->live = 0; dda->done = 1;
#ifdef LOOKAHEAD
dda->id--;
#endif
queue_flush();
queue_step() ;
dda_new_startpoint();
}
ATOMIC_END
break;
case 112:
//? Example: M112
//?
//? Any moves in progress are immediately terminated, then the controller
//? shuts down. All motors are turned off. Only way to
//? restart is to press the reset button on the master microcontroller.
//? See also M0.
//?
timer_stop();
queue_flush();
cli();
break;
case 114:
//? Example: M114
//?
//? Get current pos
update_current_position();
sersendf_P(PSTR("X:%lq,Y:%lq,F:%lu\n"),
current_position.axis[X], current_position.axis[Y],
current_position.F);
break;
case 119:
//? Example: M119
//?
//? Endstops status
//power_on();
endstops_on();
//delay_ms(10); // allow the signal to stabilize
#if defined(Y_MIN_PIN)
sersendf_P(PSTR("X:%d,Y:%d\n"), x_min(), y_min());
#endif
endstops_off();
break;
case 202: //set acceleration
break;
case 222: //set speed
break;
default:
result = STATE_ERROR;
}
break;
default:
result = STATE_ERROR;
}
return result;
}
@ -165,9 +275,9 @@ uint8_t parse_digit(uint8_t c)
// all done, this digit is a end of instruction
if(c == '\n' || c == '\r') {
//process instruction
process_command();
c = process_command();
parser_reset();
return 0;
return c;
}
if(c == '.')
{
@ -197,11 +307,10 @@ uint8_t start_parsing_number(uint8_t c)
return STATE_ERROR;
}
// parsing of new instruction starts from HERE
uint8_t gcode_parse_char(uint8_t c) {
uint8_t result, checksum_char = c;
result = current_state(c);
if IS_ENDING(c)
@ -211,4 +320,33 @@ uint8_t gcode_parse_char(uint8_t c) {
return 1;
}
return 0;
}
/// find Y MIN endstop position
void home_pos_y() {
#if defined Y_MIN_PIN
TARGET t = startpoint;
t.axis[Y] = -1000000;
if (SEARCH_FAST > SEARCH_FEEDRATE_Y)
t.F = SEARCH_FAST;
else
t.F = SEARCH_FEEDRATE_Y;
enqueue_home(&t, 0x04, 1);
if (SEARCH_FAST > SEARCH_FEEDRATE_Y) {
t.axis[Y] = +1000000;
t.F = SEARCH_FEEDRATE_Y;
enqueue_home(&t, 0x04, 0);
}
// set Y home
//queue_wait();
#ifdef Y_MIN
startpoint.axis[Y] = next_target.axis[Y] = (int32_t)(Y_MIN * 1000.);
#else
startpoint.axis[Y] = next_target.axis[Y] = 0;
#endif
dda_new_startpoint();
#endif
}

Wyświetl plik

@ -21,4 +21,7 @@ uint8_t gcode_parse_char(uint8_t c);
/// setup variables
void parser_init();
// help function, home axis position by hitting endstop
void home_pos_y();
#endif /* _GCODE_PARSE_H */

Wyświetl plik

@ -91,6 +91,14 @@ void dda_init(void) {
startpoint.f_multiplier = 256;
}
/*! Distribute a new startpoint to DDA's internal structures without any movement.
This is needed for example after homing or a G92. The new location must be in startpoint already.
*/
void dda_new_startpoint(void) {
axes_um_to_steps(startpoint.axis, startpoint_steps.axis);
}
/*! Set the direction of the 'n' axis
*/
static void set_direction(DDA *dda, uint8_t n, int32_t delta) {
@ -277,7 +285,7 @@ void dda_create(DDA *dda, const TARGET *target) {
}
if (DEBUG_DDA && (debug_flags & DEBUG_DDA))
sersendf_P(PSTR(" [ts:%lu"), dda->total_steps);
sersendf_P(PSTR(" [ts:%lu"), dda->total_steps);
if (dda->total_steps == 0) {
dda->nullmove = 1;
@ -559,11 +567,49 @@ void dda_clock() {
// in principle (but rarely) happen if endstops are checked not as
// endstop search, but as part of normal operations.
if (dda->endstop_check && ! move_state.endstop_stop) {
#ifdef X_MIN_PIN
if (dda->endstop_check & 0x01) {
if (x_min() == dda->endstop_stop_cond)
move_state.debounce_count_x++;
else
move_state.debounce_count_x = 0;
endstop_trigger = move_state.debounce_count_x >= ENDSTOP_STEPS;
}
#endif
#ifdef X_MAX_PIN
if (dda->endstop_check & 0x02) {
if (x_max() == dda->endstop_stop_cond)
move_state.debounce_count_x++;
else
move_state.debounce_count_x = 0;
endstop_trigger = move_state.debounce_count_x >= ENDSTOP_STEPS;
}
#endif
#ifdef Y_MIN_PIN
if (dda->endstop_check & 0x04) {
if (y_min() == dda->endstop_stop_cond)
move_state.debounce_count_y++;
else
move_state.debounce_count_y = 0;
endstop_trigger = move_state.debounce_count_y >= ENDSTOP_STEPS;
}
#endif
#ifdef Y_MAX_PIN
if (dda->endstop_check & 0x08) {
if (y_max() == dda->endstop_stop_cond)
move_state.debounce_count_y++;
else
move_state.debounce_count_y = 0;
endstop_trigger = move_state.debounce_count_y >= ENDSTOP_STEPS;
}
#endif
// If an endstop is definitely triggered, stop the movement.
if (endstop_trigger) {
// For always smooth operations, don't halt apruptly,
#ifdef MILD_HOMING
// For always smooth operations, don't halt abruptly,
// but start deceleration here.
ATOMIC_START
move_state.endstop_stop = 1;
@ -575,9 +621,13 @@ void dda_clock() {
move_state.step_no;
dda->rampdown_steps = move_state.step_no;
ATOMIC_END
// Not atomic, because not used in dda_step().
dda->rampup_steps = 0; // in case we're still accelerating
#else
dda->live = 0;
#endif
endstops_off();
}
} /* ! move_state.endstop_stop */
@ -638,6 +688,7 @@ void dda_clock() {
In case such a change happened, values in the new dda are more
recent than our calculation here, anyways.
*/
if (current_id == dda->id) {
dda->c = move_c;
dda->n = move_n;

Wyświetl plik

@ -146,8 +146,9 @@ typedef struct {
// Number the moves to be able to test at the end of lookahead if the moves
// are the same. Note: we do not need a lot of granularity here: more than
// MOVEBUFFER_SIZE is already enough.
uint8_t id;
#endif
uint8_t id;
/// Small variables. Many CPUs can access 32-bit variables at word or double
/// word boundaries only and fill smaller variables in between with gaps,

Wyświetl plik

@ -35,6 +35,17 @@ uint8_t queue_empty() {
return result;
}
/// dump queue for emergency stop.
/// Make sure to have all timers stopped with timer_stop() or
/// unexpected things might happen.
/// \todo effect on startpoint is undefined!
void queue_flush() {
// if the timer were running, this would require
// wrapping in ATOMIC_START ... ATOMIC_END.
mb_tail = mb_head;
movebuffer[mb_head].live = 0;
}
DDA *queue_current_movement() {
DDA* current;
@ -70,7 +81,7 @@ void enqueue_home(TARGET *t, uint8_t endstop_check, uint8_t endstop_stop_cond) {
new_movebuffer->endstop_stop_cond = endstop_stop_cond;
}
else {
// it's a wait for temp
// it's a wait for something
new_movebuffer->waitfor = 1;
}
dda_create(new_movebuffer, t);
@ -122,4 +133,4 @@ void next_move(void)
mb_tail = t;
dda_start(current_movebuffer);
}
}
}

Wyświetl plik

@ -11,6 +11,7 @@ extern DDA movebuffer[MOVEBUFFER_SIZE];
// queue status methods
uint8_t queue_full(void);
uint8_t queue_empty(void);
void queue_flush(void);
DDA *queue_current_movement(void);
/// Find the next DDA index after 'x', where 0 <= x < MOVEBUFFER_SIZE

1
runsim.sh 100644
Wyświetl plik

@ -0,0 +1 @@
simulavr -f teathimble.elf