Category Archives: code

Auto eject on Ultimaker 1

Here’s my g-code that pushes the stretchy bracelet off from building platform:
G1 X130 ; little bit to the right so that the fan hits the object
G1 Y195 ; Brings the bed all the way forward – so the ram is behind the part
G1 Z0.2 ; Lift the nozzle slightly so it doesn’t scrape along the bed during the ramming movement
G1 Y0 F6000 ; Sends the bed moving backwards, print impacts ram and is pushed off front of bed onto paper chute

Pin interrupts on Atmega 168 + 328 (Arduino)

From http://arduino.cc/forum/index.php?topic=80928.0

From http://arduino.cc/forum/index.php?topic=80928.0

/*
* Theory: all IO pins on Atmega168 are covered by Pin Change Interrupts.
* The PCINT corresponding to the pin must be enabled and masked, and
* an ISR routine provided. Since PCINTs are per port, not per pin, the ISR
* must use some logic to actually implement a per-pin interrupt service.
*/

/* Pin to interrupt map:
* D0-D7 = PCINT 16-23 = PCIR2 = PD = PCIE2 = pcmsk2
* D8-D13 = PCINT 0-5 = PCIR0 = PB = PCIE0 = pcmsk0
* A0-A5 (D14-D19) = PCINT 8-13 = PCIR1 = PC = PCIE1 = pcmsk1
*/

Setup:

PCMSK2 |= (1<<PCINT23);
PCICR |= (1 << PCIE2);
PCMSK0 |= (1<<PCINT0);
PCICR |= (1 << PCIE0);
ISR(PCINT2_vect)




ISR(PCINT0_vect)
{
code here
}

Arduino Due performance on sin()

Tested running 100.000 sin() calls and it took 2594 milliseconds. That means you make call sin() at 38.55kHz. If you want to make 44.1kHz sound in real-time there’s no way you can use the sin() method.

Here’s the code I used

void SpeedTest()
{
float f = 1.23;

Serial.println(millis());

for (uint32_t i=0; i<10000; i++)
{
f=sin(f);
f=sin(f);
f=sin(f);
f=sin(f);
f=sin(f);

f=sin(f);
f=sin(f);
f=sin(f);
f=sin(f);
f=sin(f);

}

Serial.println(millis());

Serial.println(f);

}

Heading difference

A problem that pops up always. When needing to calculate heading difference between two compass courses?


float calculateHeadError(float heading, float target)
{
#define PI2 PI*2.0
while (heading<0) heading += PI2;
while (target<0) target += PI2;

while (heading>PI2) heading -= PI2;
while (target>PI2) target -= PI2;

float res = heading-target;

if ((headingPI))
{
res =(heading+PI2)-target;
}

if ((heading>PI) && (target {
res= (heading)-(target+PI2);
}
return res;
}

Great way to keep your server in correct time with PHP

This really works. From here: http://www.xenocafe.com/tutorials/php/ntp_time_synchronization/index.php

#!/usr/bin/php -q
<?php
  // ntp time servers to contact
  // we try them one at a time if the previous failed (failover)
  // if all fail then wait till tomorrow
  $time_servers = array("time.nist.gov",
                        "nist1.datum.com",
                        "time-a.timefreq.bldrdoc.gov",
                        "utcnist.colorado.edu");

  // date and clock programs (change for your system)
  $date_app  = "/bin/date";
  $clock_app = "/sbin/clock";

  // a flag and number of servers
  $valid_response = false;
  $ts_count = sizeof($time_servers);

  // time adjustment
  // I'm in California and the clock will be set to -0800 UTC [8 hours] for PST
  // you will need to change this value for your region (seconds)
  $time_adjustment = 0;

  for ($i=0; $i<$ts_count; $i++) {
    $time_server = $time_servers[$i];
    $fp = fsockopen($time_server, 37, $errno, $errstr, 30);
    if (!$fp) {
      echo "$time_server: $errstr ($errno)\n";
      echo "Trying next available server...\n\n";
    } else {
      $data = NULL;
      while (!feof($fp)) {
        $data .= fgets($fp, 128);
      }
      fclose($fp);

      // we have a response...is it valid? (4 char string -> 32 bits)
      if (strlen($data) != 4) {
        echo "NTP Server {$time_server} returned an invalid response.\n";
        if ($i != ($ts_count - 1)) {
          echo "Trying next available server...\n\n";
        } else {
          echo "Time server list exhausted\n";
        }
      } else {
        $valid_response = true;
        break;
      }
    }
  }

  if ($valid_response) {
    // time server response is a string - convert to numeric
    $NTPtime = ord($data{0})*pow(256, 3) + ord($data{1})*pow(256, 2) + ord($data{2})*256 + ord($data{3});
    // convert the seconds to the present date & time
    // 2840140800 = Thu, 1 Jan 2060 00:00:00 UTC
    // 631152000  = Mon, 1 Jan 1990 00:00:00 UTC
    $TimeFrom1990 = $NTPtime - 2840140800;
    $TimeNow = $TimeFrom1990 + 631152000;
    // set the system time
    $TheDate = date("m/d/Y H:i:s", $TimeNow + $time_adjustment);
    $success = exec("$date_app -s \"$TheDate\"");
    // set the hardware clock (optional) - you may want to comment this out
    exec("$clock_app --systohc");
    echo "The server's date and time was set to $success\n";
  } else {
    echo "The system time could not be updated. No time servers available.\n";
  }
?>

Better colors for Arduino IDE

With just small changes you can make Arduino IDE better for your eyes. Try this, change theme.txt that is located in /Applications/Arduino.app/Contents/Resources/Java/lib/theme, dunno about Windows.

# GUI – STATUS
status.notice.fgcolor = #000000
status.notice.bgcolor = #54919e
status.error.fgcolor = #ffffff
status.error.bgcolor = #662000
status.edit.fgcolor = #000000
status.edit.bgcolor = #cc9900
status.font = SansSerif,plain,12

# GUI – TABS
# settings for the tabs at the top
# (tab images are stored in the lib/theme folder)
header.bgcolor = #216886
header.text.selected.color = #1a1a00
header.text.unselected.color = #ffffff
header.text.font = SansSerif,plain,12

# GUI – CONSOLE
console.font = Monospaced,plain,11
console.font.macosx = Monaco,plain,10
console.color = #000000
console.output.color = #cccccc
console.error.color = #ff3000

# GUI – BUTTONS
buttons.bgcolor = #044f6f
buttons.status.font = SansSerif,plain,12
buttons.status.color = #ffffff

# GUI – LINESTATUS
linestatus.color = #ffffff
linestatus.bgcolor = #044f6f

# EDITOR – DETAILS

# foreground and background colors
editor.fgcolor = #ffffff
editor.bgcolor = #000000

# highlight for the current line
editor.linehighlight.color=#005500
# highlight for the current line
editor.linehighlight=true

# caret blinking and caret color
editor.caret.color = #FF00FF

# color to be used for background when ‘external editor’ enabled
editor.external.bgcolor = #c8d2dc

# selection color
editor.selection.color = #888888

# area that’s not in use by the text (replaced with tildes)
editor.invalid.style = #7e7e7e,bold

# little pooties at the end of lines that show where they finish
editor.eolmarkers = false
editor.eolmarkers.color = #999999

# bracket/brace highlighting
editor.brackethighlight = true
editor.brackethighlight.color = #FF0000

# TEXT – KEYWORDS

# e.g abstract, final, private
editor.keyword1.style = #00FFFF,plain

# e.g. beginShape, point, line
editor.keyword2.style = #00FFFF,plain

# e.g. byte, char, short, color
editor.keyword3.style = #FF00FF,bold

# TEXT – LITERALS

# constants: e.g. null, true, this, RGB, TWO_PI
editor.literal1.style = #5599CC,plain

# p5 built in variables: e.g. mouseX, width, pixels
editor.literal2.style = #00FFFF,plain

# e.g. + – = /
editor.operator.style = #00FFFF,plain

# ?? maybe this is for words followed by a colon
# like in case statements or goto
editor.label.style = #7e7e7e,bold

# TEXT – COMMENTS
editor.comment1.style = #7e7e7e,plain
editor.comment2.style = #7e7e7e,plain

# LINE STATUS – editor line number status bar at the bottom of the screen
linestatus.font = SansSerif,plain,10
linestatus.height = 20

Reset Arduino programmatically

This code resets Arduino – in-line – in program, whenever called. Ugly, but works.


// definition
void(* resetFunc) (void) = 0; //declare reset function @ address 0

Source: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1288779911/3#3

BMP085 with Arduino (tested & working)

I tested & corrected and this code really works.


// BMP08 with Arduino

// DANGER: The BMP08 accepts 1.8 to 3.6 Volts – so no chance to connect it directly to 5 Volts.

// Connect VCC to VCC and GND to GND, SCL goes to analogue pin 5, SDA to analogue pin4.
// Notice! Sparkfun breakoutboard contains already 4.7K pull ups,
// If not using pre-built pull-ups:
// --> Add some pull up resistors (1K to 20K, most often something like 4.7K) between SDA, SCL and VCC finishes the setup.

// References: http://interactive-matter.org/2009/12/arduino-barometric-pressure-sensor-bmp085/ and http://news.jeelabs.org/2009/02/19/hooking-up-a-bmp085-sensor/
// Specification: http://www.bosch-sensortec.com/content/language1/downloads/BST-BMP085-DS000-05.pdf
// SparkFun breakout board: http://www.sparkfun.com/commerce/product_info.php?products_id=9694

#include "Wire.h"

#define I2C_ADDRESS 0x77

const unsigned char oversampling_setting = 3; //oversamplig for measurement
const unsigned char pressure_waittime[4] = { 5, 8, 14, 26 };

//just taken from the BMP085 datasheet
int ac1;
int ac2;
int ac3;
unsigned int ac4;
unsigned int ac5;
unsigned int ac6;
int b1;
int b2;
int mb;
int mc;
int md;

void setup()
{
Serial.begin(9600); // start serial for output
Serial.println("Setting up BMP085");
Wire.begin();
bmp085_get_cal_data();
}
void bmp085_read_temperature_and_pressure(int& temperature, long& pressure);
void loop()
{
int temperature = 0;
long pressure = 0;

bmp085_read_temperature_and_pressure(&temperature,&pressure);
Serial.print(temperature,DEC);
Serial.print(" ");
Serial.print(pressure,DEC);
Serial.println();
delay(100);
}

void bmp085_read_temperature_and_pressure(int* temperature, long* pressure) {
int ut= bmp085_read_ut();
long up = bmp085_read_up();
long x1, x2, x3, b3, b5, b6, p;
unsigned long b4, b7;

//calculate the temperature
x1 = ((long)ut - ac6) * ac5 >> 15;
x2 = ((long) mc << 11) / (x1 + md);
b5 = x1 + x2;
*temperature = (b5 + 8) >> 4;

//calculate the pressure
b6 = b5 - 4000;
x1 = (b2 * (b6 * b6 >> 12)) >> 11;
x2 = ac2 * b6 >> 11;
x3 = x1 + x2;

//b3 = (((int32_t) ac1 * 4 + x3)<> 2;

if (oversampling_setting == 3) b3 = ((int32_t) ac1 * 4 + x3 + 2) << 1;
if (oversampling_setting == 2) b3 = ((int32_t) ac1 * 4 + x3 + 2);
if (oversampling_setting == 1) b3 = ((int32_t) ac1 * 4 + x3 + 2) >> 1;
if (oversampling_setting == 0) b3 = ((int32_t) ac1 * 4 + x3 + 2) >> 2;

x1 = ac3 * b6 >> 13;
x2 = (b1 * (b6 * b6 >> 12)) >> 16;
x3 = ((x1 + x2) + 2) >> 2;
b4 = (ac4 * (uint32_t) (x3 + 32768)) >> 15;
b7 = ((uint32_t) up - b3) * (50000 >> oversampling_setting);
p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2;

x1 = (p >> 8) * (p >> 8);
x1 = (x1 * 3038) >> 16;
x2 = (-7357 * p) >> 16;
*pressure = p + ((x1 + x2 + 3791) >> 4);

}

unsigned int bmp085_read_ut() {
write_register(0xf4,0x2e);
delay(5); //longer than 4.5 ms
return read_int_register(0xf6);
}

void bmp085_get_cal_data() {
Serial.println("Reading Calibration Data");
ac1 = read_int_register(0xAA);
Serial.print("AC1: ");
Serial.println(ac1,DEC);
ac2 = read_int_register(0xAC);
Serial.print("AC2: ");
Serial.println(ac2,DEC);
ac3 = read_int_register(0xAE);
Serial.print("AC3: ");
Serial.println(ac3,DEC);
ac4 = read_int_register(0xB0);
Serial.print("AC4: ");
Serial.println(ac4,DEC);
ac5 = read_int_register(0xB2);
Serial.print("AC5: ");
Serial.println(ac5,DEC);
ac6 = read_int_register(0xB4);
Serial.print("AC6: ");
Serial.println(ac6,DEC);
b1 = read_int_register(0xB6);
Serial.print("B1: ");
Serial.println(b1,DEC);
b2 = read_int_register(0xB8);
Serial.print("B2: ");
Serial.println(b1,DEC);
mb = read_int_register(0xBA);
Serial.print("MB: ");
Serial.println(mb,DEC);
mc = read_int_register(0xBC);
Serial.print("MC: ");
Serial.println(mc,DEC);
md = read_int_register(0xBE);
Serial.print("MD: ");
Serial.println(md,DEC);
}

long bmp085_read_up() {
write_register(0xf4,0x34+(oversampling_setting<<6));
delay(pressure_waittime[oversampling_setting]);

unsigned char msb, lsb, xlsb;
Wire.beginTransmission(I2C_ADDRESS);
Wire.send(0xf6); // register to read
Wire.endTransmission();

Wire.requestFrom(I2C_ADDRESS, 3); // read a byte
while(!Wire.available()) {
// waiting
}
msb = Wire.receive();
while(!Wire.available()) {
// waiting
}
lsb |= Wire.receive();
while(!Wire.available()) {
// waiting
}
xlsb |= Wire.receive();
return (((long)msb<<16) | ((long)lsb<<8) | ((long)xlsb)) >>(8-oversampling_setting);
}

void write_register(unsigned char r, unsigned char v)
{
Wire.beginTransmission(I2C_ADDRESS);
Wire.send(r);
Wire.send(v);
Wire.endTransmission();
}

char read_register(unsigned char r)
{
unsigned char v;
Wire.beginTransmission(I2C_ADDRESS);
Wire.send(r); // register to read
Wire.endTransmission();

Wire.requestFrom(I2C_ADDRESS, 1); // read a byte
while(!Wire.available()) {
// waiting
}
v = Wire.receive();
return v;
}

int read_int_register(unsigned char r)
{
unsigned char msb, lsb;
Wire.beginTransmission(I2C_ADDRESS);
Wire.send(r); // register to read
Wire.endTransmission();

Wire.requestFrom(I2C_ADDRESS, 2); // read a byte
while(!Wire.available()) {
// waiting
}
msb = Wire.receive();
while(!Wire.available()) {
// waiting
}
lsb = Wire.receive();
return (((int)msb<<8) | ((int)lsb));
}

Links: http://sensorapp.net/?p=278