Giter Site home page Giter Site logo

triffid / fived_on_arduino Goto Github PK

View Code? Open in Web Editor NEW
30.0 7.0 12.0 3.93 MB

Rewrite of reprap mendel firmware

Home Page: http://forums.reprap.org/read.php?147,33082

License: GNU General Public License v2.0

Java 0.06% Perl 0.73% Python 2.27% Shell 3.17% C 93.78%

fived_on_arduino's Introduction

THIS REPOSITORY IS OBSOLETE/ABANDONED, PLEASE SEE https://github.com/triffid/Teacup_Firmware FOR THE MOST RECENT VERSION

FILES WILL REMAIN HERE FOR A LITTLE WHILE AFTER WHICH THEY WILL BE REMOVED

##############################################################################

Rewrite of Reprap Mendel firmware:

* 100% integer computations
* serial transmit buffer
* can fit onto atmega168 depending on selected options
* works on atmega328p
* works on atmega644p
* porting to atmega1280 in progress
* will work on larger atmegas with minor porting

Forum Thread: http://forums.reprap.org/read.php?147
Post all queries, comments, etc here

Github: http://github.com/triffid/FiveD_on_Arduino
patches, issues go here

##############################################################################
#                                                                            #
# How to use                                                                 #
#                                                                            #
##############################################################################

1) COPY config.YOURBOARDHERE.h to config.h and edit to suit your electronics
2) check programming settings in Makefile (chip type, avrdude settings, etc)
3) make
4) make program
4a) if programming blank chip, make program-fuses
5) ./sender.sh
6) have a play, go to 1) if not right
7) try printing something!

##############################################################################
#                                                                            #
# Requirements                                                               #
#                                                                            #
##############################################################################

Compile:
	gnu make
	binutils, gcc, etc built for avr target (avr-gcc, avr-as, etc)
	avr-libc
Program:
	avrdude
	something that avrdude supports: bootloader, separate programmer, whatever

##############################################################################
#                                                                            #
# License                                                                    #
#                                                                            #
##############################################################################

This firmware is Copyright (C) 2009-2010 Michael Moon aka Triffid_Hunter

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

##############################################################################
#                                                                            #
# Rationale and History                                                      #
#                                                                            #
##############################################################################

I started building my electronics with only a regular arduino to test with.
This was perfectly sufficient for playing with the pololu stepper controllers and the max6675 I bought after reading about all the issues with thermistors that people were having. After a while I decided to check out the official firmware but it required an atmega644. I wondered why.
So, I decided to skim through the code to see what took up so much space. From what I could see, it was written by someone who was familiar with programming desktop systems and larger embedded devices, but didn't have much experience with small devices such as the atmega168 and atmega644.
This showed in the use of C++ which served only to make the code harder to read, and the prolific use of floating-point math, with some appearing even in interrupt context!
I came to the conclusion that there was no reason that the main body of code couldn't fit onto an atmega168 except for the burdensome and unnecessary overheads from object-oriented code and floating point math. A quick count assured me that the atmega168 had enough pins, but only barely, and I started reading the official firmware properly, with an eye to rewriting as much as possible in a fashion suitable for small microcontrollers.

Starting with an arduino skeleton library I had assembled over time, some of my test code and the official firmware, I hacked up a passable integer-only, straight C implementation of the dda, and wrote my own gcode parser from scratch which processed each character as it arrived (with some buffering of course) instead of waiting for a whole line and then trying to process it all at once.

As soon as my new firmware was able to run a few consecutive moves, I released it for peer review.

The forum thread http://forums.reprap.org/read.php?147,33082 has much of the history from this point on.

Markus Hitter was the first to send patches, and has done a significant amount of work on a number of different parts of this firmware, particularly math and sequencing.
Jake Poznanski did the initial port to official gen3 electronics with separate extruder board
Cefiar posted me some thermistors to sponsor addition of thermistor-reading code
Markus Amsler has done a significant amount of work on the new intercom protocol and the latest timer code, as well as tons of test results in the forum
Stephen Walter provided the excellent simulation code, plus some fascinating preprocessor abuse which makes configuration significantly easier

Many others have given patches, encouragement and suggestions without which this firmware may never be what it is today.


##############################################################################
#                                                                            #
# Architectural Overview                                                     #
#                                                                            #
##############################################################################

FiveD on Arduino is quite similar to the official firmware in some ways, and markedly different in others. FiveD on Arduino has as much modularity as I could get away with without sacrificing efficiency.

// FIXME: make next paragraph easier to read
At startup, the code in mendel.c is run first. This initialises all the modules that need it, then starts polling the clock flags and feeding incoming serial characters to the gcode parser. The gcode parser processes each character individually, keeping track via internal state rather than buffering a line and skipping back and forth. The gcode parser converts floating values to integer or fixed-point representations as soon as it encounters a non-numeric character. It calls many module functions directly, but the most interesting part is move creation, where it passes a target position and speed to enqueue()[dda_queue.c] which adds it to the queue, and fires up dda_start()[dda.c] if the queue was empty. dda_start initialises the dda, figures out the stepper directions and first step timeout and a few other bits of housekeeping, then sets the timer for the appropriate timeout. When the timer fires, it calls dda_step()[dda.c] which sends all the step signals then figures out the next step timeout based on acceleration and speed settings. When the last step has been made, the dda "dies" (sets 'live' property to 0) after which queue_step[dda_queue.c] advances the queue read pointer and starts the next dda.

It is necessary to keep interrupts very short on small microcontrollers, and I have endeavoured to keep them all as short as possible. Unfortunately, dda_step[dda.c] is fairly large. I simply hope that it doesn't take so much time that it interferes with the other interrupts too much.


##############################################################################
#                                                                            #
# Interesting code sections                                                  #
#                                                                            #
##############################################################################

The serial ringbuffers are critical for good communication, but for some reason the official arduino libraries don't implement a tx queue, all but preventing sending stuff from interrupt context. As long as the queues have a length of 2^n, we can use bitwise operations rather than numerical comparison to trim the read and write pointers. The serial send function (serial_writechar[serial.c]) is necessarily careful about checking if it's in an interrupt and only waiting for space in the queue if it's not.
The dda queue is also a ringbuffer, although its implementation is harder to see as it's embedded in lots of other stuff.

The gcode parser shows how to parse each character as it comes in, so 99% of a command can be processed before the EOL is even received. It started off as a simple state machine, which then grew and shrank and morphed until it was both smaller and more functional. (FIXME: obsoleted by input-float branch if we ever merge it)

The fixed-point stuff is fun, although we have to manually ensure that the decimal point stays in the right spot. decfloat_to_int[gcode.h] is used to convert incoming floats to integer implementations by starting off with a (very!) crude floating point implementation, then choosing appropriate scaling factors within the gcode parser itself. This allows us to do a little stuff that looks like floating-point math without the burdensome overhead of a full fp implementation.

The PID code in heater.c is probably quite generalisable, and seems to work well when tuned. Google knows of plenty of PID tuning guides.

##############################################################################
#                                                                            #
# Resources                                                                  #
#                                                                            #
##############################################################################

Forum thread: http://forums.reprap.org/read.php?147,33082
Source Repository: http://github.com/triffid/FiveD_on_Arduino
Wiki Page: http://objects.reprap.org/wiki/FiveD_on_Arduino

##############################################################################
#                                                                            #
# File descriptions                                                          #
#                                                                            #
##############################################################################

*** analog.[ch]
This is the analog subsystem. Only used if you have a thermistor or ad595

*** arduino.h, arduino_[chip].h
Pin mappings and helper functions for various atmegas

*** clock.[ch]
Regular functions that run in main loop rather than an interrupt

*** config.h.dist, config.h, config.*.h
Configuration for your electronics and hardware. Copy config.h.dist to config.h, edit config.h to suit

*** copier.[ch]
A totally untested and currently unused chunk of code for copying firmware to another identical chip

*** crc.[ch]
block crc16 routine

*** createTemperatureLookup.py
A python script to generate your TemperatureTable.h

*** dda.[ch]
A rather complex block of math that figures out when to step each axis according to speed and acceleration profiles and received moves

*** dda_queue.[ch]
The queue of moves received from the host.

*** debug.[ch]
Debugging aids

*** delay.[ch]
Delay functions

*** FiveD_on_Arduino.pde
Allows firmware to be built in arduino ide

*** func.sh
Lots of host-side shell scripts for talking to firmware

*** gcode_parse.[ch]
Gcode parser. Scaling of factors to internally used integer or fixed point happens here too.

*** gcode_process.[ch]
Gcodes actually get executed here after being parsed.

*** graycode.c
routines to drive stepper h-bridges directly instead of step/dir

*** heater.[ch]
Heater management, including PID and PWM algorithms, and some configuration parameters

*** home.[ch]
Home using endstop routines

*** intercom.[ch]
Gen3 serial link control and communication

*** LICENSE
Gnu GPL2 license

*** Makefile
instructions for make on how to build firmware. has a list of modules to build which may need to be updated every so often

*** mendel.c
Firmware startup and main loop code

*** pinio.h
A few I/O primitives

*** README
this file

*** sender.sh
A simple talker

*** serial.[ch]
Serial management and buffers

*** sermsg.[ch]
Functions for sending primitive messages and values to host

*** sersendf.[ch]
A small, crude printf implementation

*** temp.[ch]
Temperature sensor management, includes some configuration parameters

*** ThermistorTable.h
linear interpolation table for your thermistor, maps analog reading -> temperature

*** timer.[ch]
Timer management, used primarily by dda.c for timing steps

*** watchdog.[ch]
Watchdog management. resets chip if firmware locks up or does something strange

fived_on_arduino's People

Contributors

amsler avatar casainho avatar dpslwk avatar eclecticc avatar jgilmore avatar sw avatar traumflug avatar triffid avatar vik avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

fived_on_arduino's Issues

Clash between stepper timer and serial communication

Recently I started to run larger GCode sections and have run several hundred lines successfully. The unfortunate truth is however, in some rare circumstances FiveD on Arduino drops steps. If the drops happen in the middle of a longer movement, you can hear these drops, as the sound coming from the stepper motors sounds a lot rougher than normal. Sometimes one axis even stops entirely for a second or two, just to continue the same movement as if nothing happened. Again, you can hear the difference easily and the pause in movement isn't a pause in the controller sending something to the stepper drivers.

Once I've found a sequence exposing the problem, I could repeat it reliably.

One part of the diagnosis is, if you send these GCode sequences line by line to the controller, everything runs fine.

To diagnose further, I was even brave enough to add some debug messages into dda_step(), below line 470:

if (dda->step_no % 100 == 0) {
    serwrite_uint32(dda->c);
    serial_writechar(' ');
}

With ACCELERATION_RAMPING turned on (to enable the used variables), this nicely outputs the current speed at a rate the serial channel can follow easily.

However, each time a number is sent, you hear a little knock from the stepper motors. Eventually, the controller (168' Arduino) hangs up entirely, it's LED flickers and the serial connection is no longer responsive. Pressing the reset button isn't sufficient, I have to power-cycle the thing to get it back to life.

My current conclusion is, steps get lost in a movement if serial communications is busy at the same time. These two timers don't work independently from each other, but get into each other's way.

Undoubtly, I'd like to reduce serial communication's interrupt priority, but how would one achieve that?

BTW., most movements run at about 4000 steps/second.

Store steps/mm in eeprom

it can be a bit cumbersome to rebuild the firmware when changing microstepping on the drivers, so it would be nice if the step/mm can be runtime adjusted. It doesn't need to be the actual steps/mm, but could a LUT or something similar.

Timing not entirely accurate

When testing new features I recognized acceleration is no longer accurate for higher speeds. It's difficult to describe, but ramping up is fine and at about 80% of the end speed, speed jumps to that end speed immediately. At lower speed this happens unnoticed, but at 600 mm/min, which translates to 3200 steps/s here, one can hear that well. Not sure wether this also involves step losses, but it also prevents me from maxing out my stepper motors.

Whatever, I tracked it down to this commit: http://github.com/triffid/FiveD_on_Arduino/commit/92eb4c97cae2b4773f86e6ba666dd4cb3af6ca19 , more precisely the timer reset in line 107 (file timer.c). If I comment out this single line in the current version, everything works well again.

Probably there's a reason why this code in timer.c was introduced, so I'm holding back from just reverting the commit. Please enlighten me :-)

STEPS_PER_MM_{X|Y|Z|E} should be more precise

Currently we use STEPS_PER_MM values to calculate the required number of steps from a given position. However, for half-stepping, belt-driven machines this is not precise enough. The correct value would be about 8.12 STEPS_PER_MM, bringing in an dimension error of about 15% when using the next integer (8).

My idea goes towards using STEPS_PER_M, so precision is increased by a factor of 1000. Didn't have a chance to view this in the light of numerical accuracy/overflow, however.

Problems compiling ...

Hi
Just been trying to compile your code and get the following errors (using make)

CC mendel.o
CC serial.o
CC dda.o
CC gcode.o
CC timer.o
CC clock.o
CC temp.o
CC sermsg.o
CC dda_queue.o
CC watchdog.o
CC debug.o
CC sersendf.o
LINK mendel.elf
OBJCOPY mendel.hex
OBJDUMP mendel.lst
SYM mendel.sym
0 [main] perl 1784 open_stackdumpfile: Dumping stack trace to perl.exe.stackdump
SIZE Atmega168 Atmega328p
bin/sh: objdump: command not found
0 [main] perl 4012 open_stackdumpfile: Dumping stack trace to perl.exe.stackdump
ake: *** [size] Error 5

Stackdump gives

MSYS-1.0.12 Build:2010-02-05 01:08
Exception: STATUS_ACCESS_VIOLATION at eip=68008DAA
eax=300A5360 ebx=305926EC ecx=00020CCC edx=00000770 esi=00000000 edi=305900D4
ebp=0023FED0 esp=0023FEAC program=d:\Program Files\Git\bin\perl.exe
cs=001B ds=0023 es=0023 fs=003B gs=0000 ss=0023
Stack trace:
Frame Function Args
0023FED0 68008DAA (305900D4, 00000770, 00000003, 680044EA)
0023FF20 6800466B (00003F6F, 805584A0, 0023FF60, 00401EF0)
0023FF40 68004C5F (00401068, 30064AD1, 00E7A5E8, 89E7A570)
0023FF60 68004C98 (00000000, 00000000, 80544EDC, 00000000)
0023FF90 00401DB8 (00401068, 00000001, 00000006, B20EAD04)
0023FFC0 0040103D (30064AD1, 300A92EC, 7FFDE000, 80544C7D)
0023FFF0 7C817077 (00401000, 00000000, 78746341, 00000020)
End of stack trace

Any ideas as to why this is happening?

Help geatly appreciated as your code looks cool.

Bodgeit

SD card and fat16 support

I love being able to start a build on my makerbot and unplug the computer to do something else. Being able to use SD on a 328 or bigger would rock!

Firmware should check behaviour of heated elements for plausibility

This is a feature request.

Temperature sensors becoming loose might result in a situation where the temperature readout of one of the heaters becomes unrelated to the actual temperature of the heated element. Likely, the heater would turn on and never again turn off, regardless how hot the heated element is. Actually, this can cause an unattended machine to melt down or even catch fire.

A plausibility check would watch the temperature rising as the heater is switched on, and switch it off in case there's no, or no sufficient rise in temperature.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.