Microcontroller Firmware Hints

From RepRap
Revision as of 16:10, 1 July 2009 by Adrianbowyer (talk | contribs) (Driving Steppers with the Extruder Controller V2.2 (Arduino inside...))
Jump to: navigation, search

Compiling and downloading Arduino Firmware using Windows

  • Fresh Install Arduino version 011 software.
  • Copy sub directories in reprap-arduino-firmware-1.3/library (or any later version downloaded from sourceforge https://reprap.svn.sourceforge.net/svnroot/reprap) directory to Arduino hardware/libraries directory.
  • With reprap-arduino-firmware-1.3 you should end up with 14 sub directories below /libraries.
  • Open the appropriate Single_Arduino_SNAP.pde in arduino.
  • Compile.
  • You will see an error regarding obsolete header file.
  • BUT it will compile without error.
  • If you change a file in libraries which you invariably have to do to match your thermister/thermocouple delete the object file ?????.o
  • Otherwise it will not recompile using the changes

Sanguino Firmware

The Sanguino is an Arduino clone using the Atmega644p chip instead of the Atmeg168. The clone is software compatible except that the pins are moved around a bit.

  • First, install the arduino software. Version 12 is noted as being somewhat buggy, but can be used with these steps. Copy files into the arduino directory from the sanguino 1.3 folder as explained on the sanguino website under the section "use it". Follow the instructions to the letter.
  • if an error saying something about an undefined "byte" error, then go into the parameters.h tab and add the following early in the file

// from [www.arduino.cc]

// and [publications.gbdirect.co.uk]

typedef uint8_t byte;

This should solve the problem of undefined type "byte".

Note: the first 2 lines aren't really needed, but include the places where the solver of the problem learnt how to fix the issue.

  • Make any changes in the code that you need to as described on the software page. The most common change is removing the double slash in front of #use thermistor in the thermistor tale section if you are using the standard (ie cheaper) thermistor method of temperature analysis.
  • Assuming your code compiles correctly, attempt to upload the code to your sanguino, if it works first time, then you're very lucky. But most likely you'll get an error something like.

avrdude: stk500_getsync(): not in sync: resp=0x30 avrdude: stk500_disable(): protocol error, expect=0x14, resp=0x51

The solution is simple. Get one finger on the reboot button on your sanguino, then use the other one to hit "upload to I/O board". Now count to 10 and press the reset. After a few seconds, the light on the sanguino should start flashing like crazy(most likely a bit of flashing at first, then a period of flashing so fast the light is almost perminently lit up). If the same error comes back,do it again, but count to 10 a bit slower. This should allow the code to upload

  • explination of the above problem and note to developers:

This error is a side effect of using the arduino software to work on a sanguino. Long story short, the normal arduino uses a timeout period of about 20 seconds(it waits for the "I'm done uploading" message from the sanguino for 20 seconds). Because for a normal arduino, the code shouldn't take longer than 10 seconds to compile before it gets sent to the board. Sanguino's can store code 4 times as long, thus they should have a time out of about 30 seconds, but instead the arduino software waits 20 seconds, and assumes something has gone wrong and stops it all working. The next sanguino software needs to includes something to increase the upload timeout to 30 seconds or so to allow for longer code to be uploaded.

Initial testing on a Sanguino.

If you've just soldered up your Sanguino a good first program to run is Blink. You can find it from the menu in the Arduino host software at File => Sketchbook => Examples => Digital => Blink

The program will toggle “digital pin 13” which is pin 19 on the Atmega644p chip and the leg labelled 13 on the Sanguino board. This pin does not have an LED attached so you will see nothing flash.

If you want to see something flash change the line “int ledPin = 13;” to “int ledPin = 0;”. Compile and upload this and it will toggle digital pin 0 causing the red debug LED to flash.

Refer to the schematic and the pin-out diagram

Compiling and downloading Arduino Firmware using OSX

( Based on some information from here: http://reprap.org/bin/view/Main/Generation2Electronics#Program_the_Arduino )

  • Fresh Install Arduino version 012 software, including USB to serial drivers. follow this page: http://arduino.cc/en/Guide/MacOSX We suggest installing the software to the /Applications/arduino-0012/ folder.
  • Download the most recent RepRap Arduino firmware source: http://sourceforge.net/project/showfiles.php?group_id=159590&package_id=256565
  • Copy sub directories in reprap-arduino-firmware-1.3/library (or any later version downloaded from sourceforge https://reprap.svn.sourceforge.net/svnroot/reprap) directory to Arduino hardware/libraries directory.
  • With reprap-arduino-firmware-1.3 you should end up with 18 sub directories below /libraries.
  • If you were to try to "build" your sketch now, it would error out with math.h or stdlib.h errors.
  • To fix, edit the arduino-0012/hardware/cores/arduino/wiring.h and comment out the 7 defines listed here ( or surround them in a #ifdef like below, which is equivalent) :
  1. ifdef USE_PESKY_MACROS
  2. define int(x) ((int)(x))
  3. define char(x) ((char)(x))
  4. define long(x) ((long)(x))
  5. define byte(x) ((uint8_t)(x))
  6. define float(x) ((float)(x))
  7. define abs(x) ((x)>0?(x):-(x))
  8. define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
  9. endif
  • start the Arduino 12.app
  • Open the appropriate Single_Arduino_SNAP.pde in arduino.
  • Compile.
  • You will see an error regarding obsolete header file.
  • BUT it will compile without error.
  • If you change a file in libraries which you invariably have to do to match your thermister/thermocouple delete the object file ?????.o
  • Otherwise it will not recompile using the changes

Arduino Firmware using Ubuntu Linux

After downloading the linux firmware from the arduino site, If you cannot select the ttyUSB0 port from the arduino software menu - the entire tools/serial port menu is greyed out - the it could be a permission problem for /dev/ttyUSB0 If you run as root

 sudo ./arduino

then the USB port can be selected and it can be uploaded.

You can also add your normal user to the 'dialout' group ( through the System>Administration>Users and Groups menu). After rebooting, you can then run the arduino software as your normal user.

Note this also causes problems for the RepRap host software (can't open port /dev/usb0) and also for any G-Code uploaders (like ReplicatorG)

Driving Steppers with the Extruder Controller V2.2 (Arduino inside...)

RepRap Detail

This short Arduino program shows how to use the two H-bridge chips in the Extruder Controller V2.2 to drive a stepper. Note that it deliberately messes up on-board Timer 0 in order to drive the PWM (i.e. analogWrite(...) ) at very high frequency. This means that calls to delay(N) will no longer wait N milliseconds, but will come back 64 times faster.

The program uses the potentiometer on the board to turn the current to the motor up and down.

/*
 * How to drive a stepper with the RepRap Extruder controller v2.2
 *
 * Adrian Bowyer 1 July 2009
 *
 */
 
// Control pins for the A3949 chips

#define H1D 7
#define H1E 5
#define H2D 8
#define H2E 6
#define POT 0

// We will half-step;  coilPosition will take values between 0 and 7 inclusive

byte coilPosition;

// This variable stores the value (0..255) of the on-board potentiometer.  This is used 
// to vary the PWM mark-space values in analogWrites() to the enable pins, hence 
// controlling the effective motor current.

byte potValue;
bool h1Enable;
bool h2Enable;


void setup()
{
  pinMode(H1D, OUTPUT);
  pinMode(H1E, OUTPUT);  
  pinMode(H2D, OUTPUT);
  pinMode(H2E, OUTPUT);
  pinMode(POT, INPUT);
  
  // Change the frequency of Timer 0 so that PWM on pins H1E and H2E goes at
  // a very high frequency (64kHz see: 
  // http://tzechienchu.typepad.com/tc_chus_point/2009/05/changing-pwm-frequency-on-the-arduino-diecimila.html)
  // ****NOTE  This will mess up timings in the delay() and similar functions; they will no longer work in
  // milliseconds, but 64 times faster.
  
  //First clear all three prescaler bits:
  
  TCCR0B &= ~(0x07); //AND the value in TCCR0B with binary number "11111000"
  TCCR0B |= 1; //OR the value in TCCR0B with binary number "00000001"
  
  coilPosition = 0;  
}

// Demo program just spins the motor.  

void loop()                     // run over and over again
{
  motor_click();
  coilPosition++;
  coilPosition &= 7;
  
  // Remember the value fed to delay is not 1000 milliseconds, but about
  // 15.6 ms (= 1000/64).
  
  delay(1000);
}

// This writes the appropriate pattern to the output pins for
// the value of coilPosition.

void motor_click()
{
  // Disable the coils
  
  digitalWrite(H1E, 0);
  digitalWrite(H2E, 0);
  
  // Which of the 8 possible patterns do we want?
  // The commented out setPower(...) lines could
  // be used to run the coils at constant power (with
  // half-stepping not each step is equal).  Just
  // use the value of the argument to setPower(...) to
  // scale the PWM values.
  
  switch(coilPosition) 
  {
  case 7:
    //setPower((stepPower >> 1) + (stepPower >> 3));
    digitalWrite(H1D, 1);    
    digitalWrite(H2D, 1);
    h1Enable = true;
    h2Enable = true;    
    break;
    
  case 6:
    //setPower(stepPower);
    digitalWrite(H1D, 1);    
    digitalWrite(H2D, 1);
    h1Enable = true;
    h2Enable = false;   
    break; 
    
  case 5:
    //setPower((stepPower >> 1) + (stepPower >> 3));
    digitalWrite(H1D, 1);
    digitalWrite(H2D, 0);
    h1Enable = true;
    h2Enable = true; 
    break;
    
  case 4:
    //setPower(stepPower);
    digitalWrite(H1D, 1);
    digitalWrite(H2D, 0);
    h1Enable = false;
    h2Enable = true; 
    break;
    
  case 3:
    //setPower((stepPower >> 1) + (stepPower >> 3));
    digitalWrite(H1D, 0);
    digitalWrite(H2D, 0);
    h1Enable = true;
    h2Enable = true; 
    break; 
    
  case 2:
    //setPower(stepPower);
    digitalWrite(H1D, 0);
    digitalWrite(H2D, 1);
    h1Enable = true;
    h2Enable = false; 
    break;
    
  case 1:
    //setPower((stepPower >> 1) + (stepPower >> 3));
    digitalWrite(H1D, 0);
    digitalWrite(H2D, 1);
    h1Enable = true;
    h2Enable = true; 
    break;
    
  case 0:
    //setPower(stepPower);
    digitalWrite(H1D, 1);
    digitalWrite(H2D, 1);
    h1Enable = false;
    h2Enable = true; 
    break; 
    
  }
  
  // How much is the pot turned up?
  // Divide it by 4 to spread the valid readings out a bit.
  // This is about right for a 1A 3-ohm/coil stepper.
  
  potValue = analogRead(POT)>>2;
  
  // Send the appropriate PWM values
  
  if(h1Enable)
    analogWrite(H1E, potValue);
  else
    analogWrite(H1E, 0);
    
  if(h2Enable)
    analogWrite(H2E, potValue);
  else
    analogWrite(H2E, 0);
}