Hacking Arduino Mega/RAMPS 3D Printer Shield to Control Any Project

by dcaditz in Circuits > Arduino

13908 Views, 8 Favorites, 0 Comments

Hacking Arduino Mega/RAMPS 3D Printer Shield to Control Any Project

IMG_1933.jpg

Introduction

The Arduino Mega and Ramps Shield combination is a popular hardware platform for controlling FFF 3D printers. The Arduino Mega 2560 R3, based on the ATmega2560 micro-controller, is a powerful MCU board with 54 digital I/O pins, 16 analog inputs, 256K flash memory, numerous serial comm options, and 6 timer/counters that can be used to perform tasks at precise intervals outside the main loop using interrupt service routines (ISRs). The RAMPS 1.4 shield takes advantage of these MEGA capabilities to control 3D printers. It offers:

  • 5 stepper motor driver sockets
  • 4 servo driver sockets
  • 3 thermister inputs
  • 6 end stop inputs
  • 3 high current MOSFET driven heater/fan outputs
  • SD Card reader inputs
  • LCD Display connector

Best of all, it is relatively inexpensive to purchase a kit containing an Arduino Mega, RAMPS 1.4, LCD display, stepper motor drivers, and cables. Just search for 'RAMPS 1.4 kit.' (Note: newer versions of RAMPS may be available when you read this instructable.)

The MEGA/RAMPS hardware combination is commonly controlled using open source MARLIN firmware to provide all necessary capabilities for 3D printers. However, there is nothing stopping us from taking advantage of this powerful hardware platform for other uses by running different firmware. Also, there is (almost) nothing stopping us from using the RAMPS inputs and outputs for other purposes. For example, the thermister inputs could equally be used for other types of sensors and with a little care, the heater/fan outputs could be used to power e.g., DC motors, solenoids or other devices.

This instructable describes the basics of writing firmware for the Mega/RAMPS hardware platform that you can then adapt for your own amazing project. Below I provide several example applications for the MEGA/RAMPS platform using a thermistor temperature sensor, servo, LCD display and click encoder. (I just happened to have these components available in my parts bin....) I will post other Instructables that use more of the features of the RAMPS board in the future.

We will use the Arduino IDE to code our firmware. You can download the IDE from the Arduino website here. If you have not used it before, you might find the Getting Started guide helpful. There are also lots of nice example projects that come with the IDE.

Supplies

Arduino IDE

RAMPS 1.4 kit including:

  • Arduino Mega 2560 R3
  • RAMPS 1.4 shield
  • LCD display with rotary encoder control knob and SD card reader
  • Stepper motor drivers
  • Cables

(Kit can be obtained from numerous vendors. I used this one from Amazon)

  • NTC Thermister
  • Mini servo

Pin Mapping

RAMPS1.4schematic.png

Our firmware will read and write data to various pins on the Arduino Mega MCU board. However, our sensors and actuators will be connected to various pins on the RAMPS shield. We need to map the Mega pins to the RAMPS pins to control our devices. We can create a pin map by studying the RAMPS schematic, which is copied above. For example, from the schematic we see that the X-min endstop input is connected to digital pin D3 on the Mega shield. You can trace through all of the connections that you want to use and make a pin mapping. Alternatively, you can go to the MARLIN firmware Github page and find the pins_RAMPS.h header file and copy the MARLIN pin mappings. Easier yet, you can copy my pin_map.h file, however please note that this is not a complete set of mappings. If you need more functionality, or you are using a different LCD display controller than I used in Step 3, you may have to use one of the other methods to define the correct mappings that will work for your project.

Downloads

Sample Code - Retro Thermometer Example

MEGA RAMPS SERVO_bb.png
MEGA RAMPS Retro Thermometer

Here I provide a basic sketch to demonstrate the process of writing custom firmware for the MEGA/RAMPS hardware platform. I wanted to keep it simple, but also demonstrate some of the capabilities of the hardware. The code creates a simple thermometer resembling an old retro bi-metal spring dial thermometer. The hardware is, of course, overkill for this application, but it is a good starting point for understanding the capabilities of this platform.

You will need the following additional hardware:

  1. NTC Thermister (e.g., this one )
  2. Mini servo (e.g., this one)

The image shows the hardware setup. The RAMPS board is plugged into an Arduino MEGA not shown in the Fritzing image. (Note that the + and - for the servo power bus are mistakenly switched in the Fritzing RAMPS image.)

The sketch reads ambient temperature using the NTC (negative temperature coefficient) thermistor, commonly used for 3D printer heat bed temperature measurement, connected to the TEMP_0_PIN pin on the RAMPS. Based on the temperature reading, the code will control the position of a Mini servo connected to SERVO0 on the RAMPS. Note that you may have to install a jumper on the RAMPS board between VCC and 5V (the jumper pins near the reset button) to supply power to the servo.

Here are the steps to get this demo working:

  1. Save the above code files into a directory named MEGA_RAMPS_SERVO and open it in the Arduino IDE.
  2. Assemble the MEGA, RAMPS, thermistor and servo as shown in the above diagram and connect it to your computer via USB
  3. Compile and upload the code. Heat and cool the Thermistor tip and watch the servo adjust.
  4. If you want, you can print out a paper dial and make a thermometer. (I made a simple 3D printed dial that you can see in the above video.)

The thermistor is modeled using three adjustable parameters in thermistor.h:

Ro = 100000.

beta = 3950.      

To = 298

Basically we are saying that the thermistor has a resistance of 100kOhm at 25 deg C (298 deg Kelvin) and changes with temperature according to a beta parameter of 3950. You may have to adjust these for your particular thermistor. Read this for a deeper explanation. The value of R1 = 4700 Ohm is set by the bias resistor on the RAMPS board (you might want to check this on your board).

The code does AnalogRead() on TEMP_0_PIN at 2 second intervals and filters the result with an exponential filter using the library Ewma.h. The stability of the result is controlled by the value in the filter instantiator, Ewma adcFilter2(0.05);

You can adjust the temperature range and sensitivity using the map function in the loop code. I mapped 0-100 deg C to 180 to 0 degrees of rotation of the servo using:

pos = map(Temp_C, 0, 100, 180, 0);

.

Adding a Display - Digital Thermometer Example

IMG_1915.jpg

Your RAMPS kit probably includes an LCD display with an integrated click encoder and beeper as well as cables and a display interface board. My kit came with a Full Graphic Smart Controller by RepRap Discount. You may have to modify the LCD and encoder sections of your pin_map.h file if you are using a different controller. It may be helpful to study the pins_RAPMS.h file in MARLIN firmware to determine the correct mapping for your display controller.

In this Instructable we will control this display using the u8g2lib graphics library. You will have to install this library in your Arduino environment and include it in your sketch. If you are using a different display you may have to modify the code a bit. The u8g2 wiki has clear instructions for many different displays.

The MEGA communicates with the display using a three-wire SPI (Serial Peripheral Interface) bus. (CS = chip select, SLKC = clock, SID = serial input data). You will therefore have to include the SPI library. The SPI bus is connected to the following pins on the RAMPS board (see pin_map.h).

SLCK -> DOGLCD_SCK

CS -> DOGLCD_CS

SID -> DOGLCD_MOSI

U8g2 instantiates the LCD object using:

U8G2_ST7920_128X64_1_SW_SPI u8g2(U8G2_R0, DOGLCD_SCK , DOGLCD_MOSI, DOGLCD_CS );

Then, in the setup routine, we call:

u8g2.begin();

To write to the display we use:

do {
	u8g2.setCursor(10, 35);
	u8g2.print("write something");
	while ( u8g2.nextPage() );

The attached sketch files use the NTC thermistor and LCD display to create a digital thermometer. When the temperature is above 25C the beeper will emit a beep.

Responding to User Input - Click Encoder

ARDUINO MEGA/RAMPS menu demo

I use the click encoder implementation from https://github.com/0xPIT/encoder/tree/arduino. The encoder's rotational position and button clicks are polled every 1 ms using an ISR (interrupt service routine) on TIMER2 and stored in the encoder object.

ISR(TIMER2_COMPA_vect)
{
encoder->service();
}

The values are accessed as needed in the main loop:

  value += encoder->getValue();

and

ClickEncoder::Button b = encoder->getButton();

The thermistor temperature reading is also put into an ISR on TIMER1 and the delay(1000) function is eliminated from the loop. Using ISRs instead of putting this functionality directly in the loop increases responsiveness to user input, as handling polling in the loop would subject it to possible delay due to other code competing for clock cycles. It also allows the thermistor to be read at intervals on the order of seconds without pausing the loop.

The example sketch provides the following functionality:

  • On startup, it displays temperature in deg C
  • One click of encoder displays a menu
  • The user rotate the encoder to select either Celsius, Fahrenheit, or Kelvin
  • Click on the selected menu item switches to selected units and displays temperature reading