Initial Commit
@@ -0,0 +1,43 @@
|
||||
import processing.io.*;
|
||||
I2C i2c;
|
||||
|
||||
// HMC6352 is a digital compass module using I2C
|
||||
// datasheet: https://www.sparkfun.com/datasheets/Components/HMC6352.pdf
|
||||
// see setup.png in the sketch folder for wiring details
|
||||
|
||||
void setup() {
|
||||
//printArray(I2C.list());
|
||||
i2c = new I2C(I2C.list()[0]);
|
||||
setHeadingMode();
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
float deg = getHeading();
|
||||
println(deg + " degrees");
|
||||
line(width/2, height/2, width/2+sin(radians(deg))*width/2, height/2-cos(radians(deg))*height/2);
|
||||
}
|
||||
|
||||
void setHeadingMode() {
|
||||
i2c.beginTransmission(0x21);
|
||||
// command byte for writing to EEPROM
|
||||
i2c.write(0x77);
|
||||
// address of the output data control byte
|
||||
i2c.write(0x4e);
|
||||
// give us the plain heading
|
||||
i2c.write(0x00);
|
||||
i2c.endTransmission();
|
||||
}
|
||||
|
||||
float getHeading() {
|
||||
i2c.beginTransmission(0x21);
|
||||
// command byte for reading the data
|
||||
i2c.write(0x41);
|
||||
byte[] in = i2c.read(2);
|
||||
i2c.endTransmission();
|
||||
// put bytes together to tenth of degrees
|
||||
// & 0xff makes sure the byte is not interpreted as a negative value
|
||||
int deg = (in[0] & 0xff) << 8 | (in[1] & 0xff);
|
||||
// return degrees
|
||||
return deg / 10.0;
|
||||
}
|
||||
|
After Width: | Height: | Size: 194 KiB |
@@ -0,0 +1,27 @@
|
||||
import processing.io.*;
|
||||
I2C i2c;
|
||||
|
||||
// MCP4725 is a Digital-to-Analog converter using I2C
|
||||
// datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/22039d.pdf
|
||||
|
||||
void setup() {
|
||||
//printArray(I2C.list());
|
||||
i2c = new I2C(I2C.list()[0]);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(map(mouseX, 0, width, 0, 255));
|
||||
setAnalog(map(mouseX, 0, width, 0.0, 1.0));
|
||||
}
|
||||
|
||||
// outputs voltages from 0V to the supply voltage
|
||||
// (works with 3.3V and 5V)
|
||||
void setAnalog(float fac) {
|
||||
fac = constrain(fac, 0.0, 1.0);
|
||||
// convert to 12 bit value
|
||||
int val = int(4095 * fac);
|
||||
i2c.beginTransmission(0x60);
|
||||
i2c.write(val >> 8);
|
||||
i2c.write(val & 255);
|
||||
i2c.endTransmission();
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import processing.io.*;
|
||||
MCP4725 dac;
|
||||
|
||||
void setup() {
|
||||
//printArray(I2C.list());
|
||||
dac = new MCP4725(I2C.list()[0], 0x60);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(map(mouseX, 0, width, 0, 255));
|
||||
dac.setAnalog(map(mouseX, 0, width, 0.0, 1.0));
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import processing.io.I2C;
|
||||
|
||||
// MCP4725 is a Digital-to-Analog converter using I2C
|
||||
// datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/22039d.pdf
|
||||
|
||||
class MCP4725 extends I2C {
|
||||
int address;
|
||||
|
||||
// there can be more than one device connected to the bus
|
||||
// as long as they have different addresses
|
||||
MCP4725(String dev, int address) {
|
||||
super(dev);
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
// outputs voltages from 0V to the supply voltage
|
||||
// (works with 3.3V and 5V)
|
||||
void setAnalog(float fac) {
|
||||
fac = constrain(fac, 0.0, 1.0);
|
||||
// convert to 12 bit value
|
||||
int val = int(4095 * fac);
|
||||
beginTransmission(address);
|
||||
write(val >> 8);
|
||||
write(val & 255);
|
||||
endTransmission();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import processing.io.*;
|
||||
|
||||
// 0.96" 128x64 OLED display ("SKU 346540")
|
||||
SSD1306 oled;
|
||||
|
||||
void setup() {
|
||||
size(128, 64);
|
||||
|
||||
// the display can be set to one of these two addresses: 0x3c (default) or 0x3d
|
||||
// (they might be listed as 0x7a and 0x7b on the circuit board)
|
||||
|
||||
// you might need to use a different interface on other SBCs
|
||||
oled = new SSD1306("i2c-1", 0x3c);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(0);
|
||||
stroke(255);
|
||||
line(0, 0, 127, 63);
|
||||
line(0, 63, 127, 0);
|
||||
oled.sendImage(get());
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
import processing.io.I2C;
|
||||
|
||||
// SSD1306 is a small, inexpensive 128x64 pixels monochrome OLED display
|
||||
// available online as "0.96" 128x64 OLED display", SKU 346540
|
||||
// or from Adafruit
|
||||
// datasheet: https://www.adafruit.com/datasheets/SSD1306.pdf
|
||||
|
||||
class SSD1306 extends I2C {
|
||||
int address;
|
||||
|
||||
// there can be more than one device connected to the bus
|
||||
// as long as they have different addresses
|
||||
SSD1306(String dev, int address) {
|
||||
super(dev);
|
||||
this.address = address;
|
||||
init();
|
||||
}
|
||||
|
||||
protected void init() {
|
||||
writeCommand(0xae); // turn display off
|
||||
writeCommand(0xa8, 0x3f); // set multiplex ratio to the highest setting
|
||||
writeCommand(0x8d, 0x14); // enable charge pump
|
||||
writeCommand(0x20, 0x00); // set memory addressing mode to horizontal
|
||||
writeCommand(0xd5, 0x80); // set display clock divide ratio & oscillator frequency to default
|
||||
writeCommand(0xd3, 0x00); // no display offset
|
||||
writeCommand(0x40 | 0x00); // set default display start line
|
||||
|
||||
// use the following two lines to flip the display
|
||||
writeCommand(0xa0 | 0x01); // set segment re-map
|
||||
writeCommand(0xc8); // set COM output scan direction
|
||||
|
||||
writeCommand(0xda, 0x12); // set COM pins hardware configuration
|
||||
writeCommand(0xd9, 0xf1); // set pre-charge period to 241x DCLK
|
||||
writeCommand(0xdB, 0x40); // set VCOMH deselect level
|
||||
writeCommand(0xa4); // display RAM content (not all-on)
|
||||
writeCommand(0xa6); // set normal (not-inverted) display
|
||||
|
||||
// set this since we don't have access to the OLED's reset pins (?)
|
||||
writeCommand(0x21, 0, 127); // set column address
|
||||
writeCommand(0x22, 0, 7); // set page address
|
||||
|
||||
writeCommand(0x81, 0xcf); // set contrast
|
||||
writeCommand(0x2e); // deactivate scroll
|
||||
writeCommand(0xaf); // turn display on
|
||||
}
|
||||
|
||||
void invert(boolean inverted) {
|
||||
if (inverted) {
|
||||
writeCommand(0xa7);
|
||||
} else {
|
||||
writeCommand(0xa6);
|
||||
}
|
||||
}
|
||||
|
||||
void sendImage(PImage img) {
|
||||
sendImage(img, 0, 0);
|
||||
}
|
||||
|
||||
void sendImage(PImage img, int startX, int startY) {
|
||||
byte[] frame = new byte[1024];
|
||||
img.loadPixels();
|
||||
for (int y=startY; y < height && y-startY < 64; y++) {
|
||||
for (int x=startX; x < width && x-startX < 128; x++) {
|
||||
if (128 <= brightness(img.pixels[y*img.width+x])) {
|
||||
// this isn't the normal (scanline) mapping, but 8 pixels below each other at a time
|
||||
// white pixels have their bit turned on
|
||||
frame[x + (y/8)*128] |= (1 << (y % 8));
|
||||
}
|
||||
}
|
||||
}
|
||||
sendFramebuffer(frame);
|
||||
}
|
||||
|
||||
void sendFramebuffer(byte[] buf) {
|
||||
if (buf.length != 1024) {
|
||||
System.err.println("The framebuffer should be 1024 bytes long, with one bit per pixel");
|
||||
throw new IllegalArgumentException("Unexpected buffer size");
|
||||
}
|
||||
|
||||
writeCommand(0x00 | 0x0); // set start address
|
||||
writeCommand(0x10 | 0x0); // set higher column start address
|
||||
writeCommand(0x40 | 0x0); // set start line
|
||||
|
||||
// send the frame buffer as 16 byte long packets
|
||||
for (int i=0; i < buf.length/16; i++) {
|
||||
super.beginTransmission(address);
|
||||
super.write(0x40); // indicates data write
|
||||
for (int j=0; j < 16; j++) {
|
||||
super.write(buf[i*16+j]);
|
||||
}
|
||||
super.endTransmission();
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeCommand(int arg1) {
|
||||
super.beginTransmission(address);
|
||||
super.write(0x00); // indicates command write
|
||||
super.write(arg1);
|
||||
super.endTransmission();
|
||||
}
|
||||
|
||||
protected void writeCommand(int arg1, int arg2) {
|
||||
super.beginTransmission(address);
|
||||
super.write(0x00);
|
||||
super.write(arg1);
|
||||
super.write(arg2);
|
||||
super.endTransmission();
|
||||
}
|
||||
|
||||
protected void writeCommand(int arg1, int arg2, int arg3) {
|
||||
super.beginTransmission(address);
|
||||
super.write(0x00);
|
||||
super.write(arg1);
|
||||
super.write(arg2);
|
||||
super.write(arg3);
|
||||
super.endTransmission();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import processing.io.*;
|
||||
color bgcolor = 0;
|
||||
|
||||
// GPIO numbers refer to different phyiscal pins on various boards
|
||||
// On the Raspberry Pi GPIO 4 is physical pin 7 on the header
|
||||
// see setup.png in the sketch folder for wiring details
|
||||
|
||||
void setup() {
|
||||
GPIO.pinMode(4, GPIO.INPUT);
|
||||
GPIO.attachInterrupt(4, this, "pinEvent", GPIO.RISING);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(bgcolor);
|
||||
}
|
||||
|
||||
// this function will be called whenever GPIO 4 is brought from LOW to HIGH
|
||||
void pinEvent(int pin) {
|
||||
println("Received interrupt");
|
||||
if (bgcolor == 0) {
|
||||
bgcolor = color(255);
|
||||
} else {
|
||||
bgcolor = color(0);
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 193 KiB |
@@ -0,0 +1,39 @@
|
||||
import processing.io.*;
|
||||
LED leds[];
|
||||
|
||||
// the Raspberry Pi has two build-in LEDs we can control
|
||||
// led0 (green) and led1 (red)
|
||||
|
||||
void setup() {
|
||||
String available[] = LED.list();
|
||||
print("Available: ");
|
||||
println(available);
|
||||
|
||||
// create an object for each LED and store it in an array
|
||||
leds = new LED[available.length];
|
||||
for (int i=0; i < available.length; i++) {
|
||||
leds[i] = new LED(available[i]);
|
||||
}
|
||||
|
||||
frameRate(1);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
// make the LEDs count in binary
|
||||
for (int i=0; i < leds.length; i++) {
|
||||
if ((frameCount & (1 << i)) != 0) {
|
||||
leds[i].brightness(1.0);
|
||||
} else {
|
||||
leds[i].brightness(0.0);
|
||||
}
|
||||
}
|
||||
println(frameCount);
|
||||
}
|
||||
|
||||
void keyPressed() {
|
||||
// cleanup
|
||||
for (int i=0; i < leds.length; i++) {
|
||||
leds[i].close();
|
||||
}
|
||||
exit();
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import processing.io.*;
|
||||
SPI spi;
|
||||
|
||||
// MCP3001 is a Analog-to-Digital converter using SPI
|
||||
// datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/21293C.pdf
|
||||
// see setup.png in the sketch folder for wiring details
|
||||
|
||||
void setup() {
|
||||
//printArray(SPI.list());
|
||||
spi = new SPI(SPI.list()[0]);
|
||||
spi.settings(500000, SPI.MSBFIRST, SPI.MODE0);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
// dummy write, actual values don't matter
|
||||
byte[] out = { 0, 0 };
|
||||
byte[] in = spi.transfer(out);
|
||||
// some input bit shifting according to the datasheet p. 16
|
||||
int val = ((in[0] & 0x1f) << 5) | ((in[1] & 0xf8) >> 3);
|
||||
// val is between 0 and 1023
|
||||
background(map(val, 0, 1023, 0, 255));
|
||||
}
|
||||
|
After Width: | Height: | Size: 66 KiB |
@@ -0,0 +1,22 @@
|
||||
import processing.io.SPI;
|
||||
|
||||
// MCP3001 is a Analog-to-Digital converter using SPI
|
||||
// datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/21293C.pdf
|
||||
|
||||
class MCP3001 extends SPI {
|
||||
|
||||
MCP3001(String dev) {
|
||||
super(dev);
|
||||
settings(500000, SPI.MSBFIRST, SPI.MODE0);
|
||||
}
|
||||
|
||||
float getAnalog() {
|
||||
// dummy write, actual values don't matter
|
||||
byte[] out = { 0, 0 };
|
||||
byte[] in = transfer(out);
|
||||
// some input bit shifting according to the datasheet p. 16
|
||||
int val = ((in[0] & 0x1f) << 5) | ((in[1] & 0xf8) >> 3);
|
||||
// val is between 0 and 1023
|
||||
return val/1023.0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import processing.io.*;
|
||||
MCP3001 adc;
|
||||
|
||||
// see setup.png in the sketch folder for wiring details
|
||||
|
||||
void setup() {
|
||||
//printArray(SPI.list());
|
||||
adc = new MCP3001(SPI.list()[0]);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(adc.getAnalog() * 255);
|
||||
}
|
||||
|
After Width: | Height: | Size: 66 KiB |
@@ -0,0 +1,27 @@
|
||||
import processing.io.SPI;
|
||||
|
||||
// MCP3008 is a Analog-to-Digital converter using SPI
|
||||
// other than the MCP3001, this has 8 input channels
|
||||
// datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/21295d.pdf
|
||||
|
||||
class MCP3008 extends SPI {
|
||||
|
||||
MCP3008(String dev) {
|
||||
super(dev);
|
||||
settings(500000, SPI.MSBFIRST, SPI.MODE0);
|
||||
}
|
||||
|
||||
float getAnalog(int channel) {
|
||||
if (channel < 0 || 7 < channel) {
|
||||
System.err.println("The channel needs to be from 0 to 7");
|
||||
throw new IllegalArgumentException("Unexpected channel");
|
||||
}
|
||||
byte[] out = { 0, 0, 0 };
|
||||
// encode the channel number in the first byte
|
||||
out[0] = (byte)(0x18 | channel);
|
||||
byte[] in = transfer(out);
|
||||
int val = ((in[1] & 0x03) << 8) | (in[2] & 0xff);
|
||||
// val is between 0 and 1023
|
||||
return val/1023.0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import processing.io.*;
|
||||
MCP3008 adc;
|
||||
|
||||
// see setup.png in the sketch folder for wiring details
|
||||
|
||||
void setup() {
|
||||
//printArray(SPI.list());
|
||||
adc = new MCP3008(SPI.list()[0]);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(adc.getAnalog(0) * 255);
|
||||
fill(adc.getAnalog(1) * 255);
|
||||
ellipse(width/2, height/2, width * 0.75, width * 0.75);
|
||||
}
|
||||
|
After Width: | Height: | Size: 68 KiB |
@@ -0,0 +1,34 @@
|
||||
import processing.io.*;
|
||||
|
||||
// see setup.png in the sketch folder for wiring details
|
||||
// for more reliable operation it is recommended to power
|
||||
// the servo from an external power source, see setup_better.png
|
||||
|
||||
SoftwareServo servo1;
|
||||
SoftwareServo servo2;
|
||||
|
||||
void setup() {
|
||||
size(400, 300);
|
||||
servo1 = new SoftwareServo(this);
|
||||
servo1.attach(17);
|
||||
servo2 = new SoftwareServo(this);
|
||||
servo2.attach(4);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(0);
|
||||
stroke(255);
|
||||
strokeWeight(3);
|
||||
|
||||
// we don't go right to the edge to prevent
|
||||
// making the servo unhappy
|
||||
float angle = 90 + sin(frameCount / 100.0)*85;
|
||||
servo1.write(angle);
|
||||
float y = map(angle, 0, 180, 0, height);
|
||||
line(0, y, width/2, y);
|
||||
|
||||
angle = 90 + cos(frameCount / 100.0)*85;
|
||||
servo2.write(90 + cos(frameCount / 100.0)*85);
|
||||
y = map(angle, 0, 180, 0, height);
|
||||
line(width/2, y, width, y);
|
||||
}
|
||||
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 71 KiB |
@@ -0,0 +1,20 @@
|
||||
import processing.io.*;
|
||||
|
||||
// GPIO numbers refer to different phyiscal pins on various boards
|
||||
// On the Raspberry Pi GPIO 4 is physical pin 7 on the header
|
||||
// see setup.png in the sketch folder for wiring details
|
||||
|
||||
void setup() {
|
||||
GPIO.pinMode(4, GPIO.INPUT);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
// sense the input pin
|
||||
if (GPIO.digitalRead(4) == GPIO.HIGH) {
|
||||
fill(255);
|
||||
} else {
|
||||
fill(204);
|
||||
}
|
||||
stroke(255);
|
||||
ellipse(width/2, height/2, width*0.75, height*0.75);
|
||||
}
|
||||
|
After Width: | Height: | Size: 193 KiB |
@@ -0,0 +1,25 @@
|
||||
import processing.io.*;
|
||||
boolean ledOn = false;
|
||||
|
||||
// GPIO numbers refer to different phyiscal pins on various boards
|
||||
// On the Raspberry Pi GPIO 4 is physical pin 7 on the header
|
||||
// see setup.png in the sketch folder for wiring details
|
||||
|
||||
void setup() {
|
||||
GPIO.pinMode(4, GPIO.OUTPUT);
|
||||
frameRate(0.5);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
// make the LED blink
|
||||
ledOn = !ledOn;
|
||||
if (ledOn) {
|
||||
GPIO.digitalWrite(4, GPIO.LOW);
|
||||
fill(204);
|
||||
} else {
|
||||
GPIO.digitalWrite(4, GPIO.HIGH);
|
||||
fill(255);
|
||||
}
|
||||
stroke(255);
|
||||
ellipse(width/2, height/2, width*0.75, height*0.75);
|
||||
}
|
||||
|
After Width: | Height: | Size: 194 KiB |
@@ -0,0 +1,56 @@
|
||||
import processing.io.*;
|
||||
|
||||
// using a capacitor that gets charged and discharged, while
|
||||
// measuring the time it takes, is an inexpensive way to
|
||||
// read the value of an (analog) resistive sensor, such as
|
||||
// a photocell
|
||||
// kudos to ladyada for the original tutorial
|
||||
|
||||
// see setup.png in the sketch folder for wiring details
|
||||
|
||||
int max = 0;
|
||||
int min = 9999;
|
||||
|
||||
void setup() {
|
||||
}
|
||||
|
||||
void draw() {
|
||||
int val = sensorRead(4);
|
||||
println(val);
|
||||
|
||||
// track largest and smallest reading, to get a sense
|
||||
// how we compare
|
||||
if (max < val) {
|
||||
max = val;
|
||||
}
|
||||
if (val < min) {
|
||||
min = val;
|
||||
}
|
||||
|
||||
// convert current reading into a number between 0.0 and 1.0
|
||||
float frac = map(val, min, max, 0.0, 1.0);
|
||||
|
||||
background(255 * frac);
|
||||
}
|
||||
|
||||
int sensorRead(int pin) {
|
||||
// discharge the capacitor
|
||||
GPIO.pinMode(pin, GPIO.OUTPUT);
|
||||
GPIO.digitalWrite(pin, GPIO.LOW);
|
||||
delay(100);
|
||||
// now the capacitor should be empty
|
||||
|
||||
// measure the time takes to fill it
|
||||
// up to ~ 1.4V again
|
||||
GPIO.pinMode(pin, GPIO.INPUT);
|
||||
int start = millis();
|
||||
while (GPIO.digitalRead(pin) == GPIO.LOW) {
|
||||
// wait
|
||||
}
|
||||
|
||||
// return the time elapsed
|
||||
// this will vary based on the value of the
|
||||
// resistive sensor (lower resistance will
|
||||
// make the capacitor charge faster)
|
||||
return millis() - start;
|
||||
}
|
||||
|
After Width: | Height: | Size: 64 KiB |