Skip to content

Instantly share code, notes, and snippets.

@soundanalogous
Last active August 29, 2015 14:15
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save soundanalogous/3d6d3d3f76e3a529e2cc to your computer and use it in GitHub Desktop.
Save soundanalogous/3d6d3d3f76e3a529e2cc to your computer and use it in GitHub Desktop.
StandardFirmata features + Stepper motor + Ethernet
/*
* Firmata is a generic protocol for communicating with microcontrollers
* from software on a host computer. It is intended to work with
* any host computer software package.
*/
/*
Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved.
Copyright (C) 2010-2011 Paul Stoffregen. All rights reserved.
Copyright (C) 2009 Shigeru Kobayashi. All rights reserved.
Copyright (C) 2009-2015 Jeff Hoefs. All rights reserved.
Copyright (C) 2013 Norbert Truchsess. All rights reserved.
Copyright (C) 2014 Nicolas Panel. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
See file LICENSE.txt for further informations on licensing terms.
*/
#include <Firmata.h>
/*
* by default Firmata uses the Serial-port (over USB) of Arduino.
* NetworkFirmata may also comunicate over ethernet using tcp/ip.
* To configure this 'Network Firmata' to use the original WIZ5100-based
* ethernet-shield or Arduino Ethernet uncomment the includes of 'SPI.h' and 'Ethernet.h':
*/
#include <SPI.h>
#include <Ethernet.h>
#include <utility/EthernetClientStream.h>
EthernetClient client;
/*
* To configure 'Network Firmata' to use an ENC28J60 based board include
* 'UIPEthernet.h' (no SPI.h required). The UIPEthernet-library can be downloaded
* from: https://github.com/ntruchsess/arduino_uip
*/
//#include <UIPEthernet.h>
/*==============================================================================
* Network configuration for Network Firmata
*============================================================================*/
//replace with ip of server you want to connect to, comment out if using 'remote_host'
#define remote_ip IPAddress(192,168,0,1)
//replace with hostname of server you want to connect to, comment out if using 'remote_ip'
#define remote_host "server.local"
//replace with the port that your server is listening on
#define remote_port 3030
//replace with arduinos ip-address. Comment out if Ethernet-startup should use dhcp. Is ignored on Yun
#define local_ip IPAddress(192,168,0,6)
//replace with ethernet shield mac. It's mandatory every device is assigned a unique mac. Is ignored on Yun
const byte mac[] = {0x90, 0xA2, 0xDA, 0x0D, 0x07, 0x02};
#include <utility/DigitalInputFirmata.h>
DigitalInputFirmata digitalInput;
#include <utility/DigitalOutputFirmata.h>
DigitalOutputFirmata digitalOutput;
#include <utility/AnalogInputFirmata.h>
AnalogInputFirmata analogInput;
#include <utility/AnalogOutputFirmata.h>
AnalogOutputFirmata analogOutput;
#include <Servo.h>
#include <utility/ServoFirmata.h>
ServoFirmata servo;
#include <Wire.h>
#include <utility/I2CFirmata.h>
I2CFirmata i2c;
#include <utility/StepperFirmata.h>
StepperFirmata stepper;
#include <utility/FirmataExt.h>
FirmataExt firmataExt;
#include <utility/AnalogWrite.h>
#include <utility/FirmataReporting.h>
FirmataReporting reporting;
// dependencies for Network Firmata. Do not comment out.
#if defined remote_ip && defined remote_host
#error "cannot define both remote_ip and remote_host at the same time!"
#endif
#if defined remote_ip && !defined remote_host
#ifdef local_ip
EthernetClientStream stream(client, local_ip, remote_ip, NULL, remote_port);
#else
EthernetClientStream stream(client, IPAddress(0, 0, 0, 0), remote_ip, NULL, remote_port);
#endif
#endif
#if !defined remote_ip && defined remote_host
#ifdef local_ip
EthernetClientStream stream(client, local_ip, IPAddress(0, 0, 0, 0), remote_host, remote_port);
#else
EthernetClientStream stream(client, IPAddress(0, 0, 0, 0), IPAddress(0, 0, 0, 0), remote_host, remote_port);
#endif
#endif
/*==============================================================================
* FUNCTIONS
*============================================================================*/
void systemResetCallback()
{
// pins with analog capability default to analog input
// otherwise, pins default to digital output
for (byte i = 0; i < TOTAL_PINS; i++) {
if (IS_PIN_ANALOG(i)) {
// turns off pullup, configures everything
Firmata.setPinMode(i, ANALOG);
} else if (IS_PIN_DIGITAL(i)) {
// sets the output to 0, configures portConfigInputs
Firmata.setPinMode(i, OUTPUT);
}
}
firmataExt.reset();
}
/*==============================================================================
* SETUP()
*============================================================================*/
void setup()
{
#ifdef local_ip
Ethernet.begin((uint8_t *)mac, local_ip); //start ethernet
#else
Ethernet.begin((uint8_t *)mac); //start ethernet using dhcp
#endif
delay(1000);
Firmata.setFirmwareVersion(FIRMATA_MAJOR_VERSION, FIRMATA_MINOR_VERSION);
/* analogWriteCallback is declared in AnalogWrite.h */
Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
firmataExt.addFeature(digitalInput);
firmataExt.addFeature(digitalOutput);
firmataExt.addFeature(analogInput);
firmataExt.addFeature(analogOutput);
firmataExt.addFeature(servo);
firmataExt.addFeature(i2c);
firmataExt.addFeature(stepper);
firmataExt.addFeature(reporting);
/* systemResetCallback is declared here (in ConfigurableFirmata.ino) */
Firmata.attach(SYSTEM_RESET, systemResetCallback);
// Network Firmata communicates with Ethernet-shields over SPI. Therefor all
// SPI-pins must be set to IGNORE. Otherwise Firmata would break SPI-communication.
// add Pin 10 and configure pin 53 as output if using a MEGA with Ethernetshield.
// No need to ignore pin 10 on MEGA with ENC28J60, as here pin 53 should be connected to SS:
// ignore SPI and pin 4 that is SS for SD-Card on Ethernet-shield
for (byte i = 0; i < TOTAL_PINS; i++) {
if (IS_PIN_SPI(i)
|| 4 == i
// || 10==i //explicitly ignore pin 10 on MEGA as 53 is hardware-SS but Ethernet-shield uses pin 10 for SS
) {
Firmata.setPinMode(i, IGNORE);
}
}
// pinMode(PIN_TO_DIGITAL(53), OUTPUT); configure hardware-SS as output on MEGA
pinMode(PIN_TO_DIGITAL(4), OUTPUT); // switch off SD-card bypassing Firmata
digitalWrite(PIN_TO_DIGITAL(4), HIGH); // SS is active low;
// start up Network Firmata:
Firmata.begin(stream);
systemResetCallback(); // reset to default config
}
/*==============================================================================
* LOOP()
*============================================================================*/
void loop()
{
/* DIGITALREAD - as fast as possible, check for changes and output them to the
* stream buffer using Firmata.write() */
digitalInput.report();
/* STREAMREAD - processing incoming messagse as soon as possible, while still
* checking digital inputs. */
while (Firmata.available()) {
Firmata.processInput();
}
if (reporting.elapsed()) {
/* ANALOGREAD - do all analogReads() at the configured sampling interval */
analogInput.report();
// report i2c data for all device with read continuous mode enabled
i2c.report();
}
stepper.update();
#if !defined local_ip
if (Ethernet.maintain())
{
stream.maintain(Ethernet.localIP());
}
#endif
}
@soundanalogous
Copy link
Author

To Use:

  1. Download and install ConfigurableFirmata 2.6.2 into the libraries folder within the Arduino application. See installation instructions in the readme.
  2. Copy the contents of this gist into a new Arduino sketch file.
  3. You need to use either the remote_ip address (line 47) or the remote_host (line 49). Comment out the one you are not using (or the compiler will throw an error).
  4. On lines 47 - 55, update the IP addresses, port number and mac address to match those you are using
  5. If you are using an Arduino Mega, uncomment line 170.
  6. Don't change anything else!
  7. Compile and upload to your board.

Known issues:

  • Servo motor does not work on pins higher than 14.
  • This sketch will use over 80% of the memory on an Arduino Uno. It is recommend that you use an Arduino Mega or other board that has more memory than an Arduino Uno (or other ATmega328-based board). An Uno will still work, but it is possible you could have issue is transferring large data packets.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment