ch05

Resource Files

Resouce files for the boxing clock. Includes images and sounds. bca-res-boxing-clock-android.tar.gz.

multipleImages.py

#!/usr/bin/env python
# multipleImages.py - Display image in a window.
# (c) Kimmo Karvinen & Tero Karvinen http://BotBook.com
 
import gtk, os
 
dir="data"
pixbufs=[]
image=None
pos=0
 
def loadImages():
    for file in os.listdir(dir):
        filePath=os.path.join(dir, file)
        pix=gtk.gdk.pixbuf_new_from_file(filePath)
        pixbufs.append(pix)
        print("Loaded image "+filePath)
 
def keyEvent(widget, event):
    global pos
    key = gtk.gdk.keyval_name(event.keyval)
    if key=="space" or key=="Page_Down":
        pos+=1
        image.set_from_pixbuf(pixbufs[pos])
    elif key=="b" or key=="Page_Up":
        pos-=1
        image.set_from_pixbuf(pixbufs[pos])
    else:
        print("Key "+key+" was pressed")
 
def main():
    global image
    window = gtk.Window()
    window.connect("destroy", gtk.main_quit)
    window.connect("key-press-event", keyEvent)
    image=gtk.Image()
    window.add(image)
    loadImages()
    image.set_from_pixbuf(pixbufs[pos])
 
    window.show_all()
    gtk.main()
 
if __name__=="__main__":
    main()

printSerial.pde

// printSerial.pde - Print test data to serial port.    
// (c) Kimmo Karvinen & Tero Karvinen http://BotBook.com

void setup()
{
    Serial.begin(9600); // bit/s
}

void loop()
{
    Serial.print("F ");
    delay(500);
    Serial.print("B ");
    delay(1000);
    Serial.print(" FFFF ");
    delay(500);
    Serial.print(" http://botbook.com ");
    delay(2000);
}

Read_3_Ping_Sensors.pde

/* Read 3 Ping Sensors
   Based on code by
   David A. Mellis and Tom Igoe
   Joe Saavedra, 2010
   http://BotBook.com
 */

const int leftPing = 2;
const int centerPing = 3;
const int rightPing = 4;

void setup() 
{
  Serial.begin(9600); // bit per second
}

void loop()
{
  Serial.print("Left: ");
  getDistance(leftPing);
  Serial.print("Center: ");
  Serial.println(getDistance(centerPing)); 
  Serial.print("Right: ");
  Serial.println(getDistance(rightPing)); 
  Serial.println();
  
  delay(250); // ms
}

int getDistance(int pingPin)
{
  long duration, inches, cm;

  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);

  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);

  inches = microsecondsToInches(duration);
  cm = microsecondsToCentimeters(duration);
  
  //return(inches);
  return(cm);
}

long microsecondsToInches(long microseconds)
{
  return microseconds / 74 / 2;
}

long microsecondsToCentimeters(long microseconds)
{
  return microseconds / 29 / 2;
}

blink.pde

// (c) Kimmo Karvinen & Tero Karvinen http://BotBook.com

int ledPin = 2;

void setup()
{
    pinMode(ledPin, OUTPUT); 
}
void loop()
{
    digitalWrite(ledPin, HIGH); 
    delay(500); 4
    digitalWrite(ledPin, LOW); 
    delay(500);
} 

imageHello.py

# imageHello.py - Display image in a window.
# (c) Kimmo Karvinen & Tero Karvinen http://BotBook.com
 
import gtk, os
 
window = gtk.Window()
window.connect("destroy", gtk.main_quit)
 
image=gtk.Image()
window.add(image)
image.set_from_file(os.path.join("data", "image1.jpg"))
 
window.show_all()
gtk.main()

windowHello.py

#!/usr/bin/env python
# windowHello.py - Create a window with a button.  
# (c) Kimmo Karvinen & Tero Karvinen http://BotBook.com
import gtk
 
window = gtk.Window()
window.connect("destroy", gtk.main_quit)
 
button = gtk.Button("Hello PyGTK - BotBook.com")
window.add(button)
 
window.show_all()
 
gtk.main()

interactivePainting.py

#!/usr/bin/env python
# interactivePainting.py - Choose full screen image by waving hand. 
# (c) Kimmo Karvinen & Tero Karvinen http://BotBook.com

import gtk, os, serial, gobject

# Global variables

dir="data"
pixbufs=[]
image=None
bg=None
pos=0
ser=None
reel=None
x=0
w=0
speed=0

# Pixbuf manipulation

def fitRect(thing, box):
    # scale
    scaleY=float(box.height)/thing.height
    scaleX=float(box.width)/thing.width
    scale=min(scaleY, scaleX)
    thing.width=scale*thing.width
    thing.height=scale*thing.height
    # center
    thing.x=box.width/2-thing.width/2
    thing.y=box.height/2-thing.height/2
    return thing

def scaleToBg(pix, bg):
    fit=fitRect(
        gtk.gdk.Rectangle(0,0, pix.get_width(), pix.get_height()),
        gtk.gdk.Rectangle(0,0, bg.get_width(), bg.get_height())
    )
    scaled=pix.scale_simple(fit.width, fit.height, gtk.gdk.INTERP_BILINEAR)
    ret=bg.copy()
    scaled.copy_area(
        src_x=0, src_y=0,
        width=fit.width, height=fit.height, 
        dest_pixbuf=ret, 
        dest_x=fit.x, dest_y=fit.y
    )
    return ret

def newPix(width, height, color=0x000000ff):
    pix=gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, width , height)
    pix.fill(color)
    return pix

def catenate(left, right): 
    "Return a Pixbuf with 'right' catenated on the right side of 'left'. "
    assert left.get_width()==right.get_width() 
    assert left.get_height()==right.get_height()
    reel=newPix(left.get_width()+right.get_width(), left.get_height()) 
    left.copy_area( 
        src_x=0, src_y=0,
        width=left.get_width(), height=right.get_height(), 
        dest_pixbuf=reel, 
        dest_x=0, dest_y=0
    )
    right.copy_area(
        src_x=0, src_y=0,
        width=right.get_width(), height=right.get_height(), 
        dest_pixbuf=reel, 
        dest_x=left.get_width(), dest_y=0
    )
    return reel 

def getBox(pix, x, width): 
    "Return Pixbuf, a slice of pix, starting at x, given width. "
    buf=newPix(width, pix.get_height())
    pix.copy_area(
        src_x=x, src_y=0, 
        width=width, height=pix.get_height(), 
        dest_pixbuf=buf, dest_x=0, dest_y=0)
    return buf

# File reading

def loadImages():
    global pixbufs
    for file in os.listdir(dir):
        filePath=os.path.join(dir, file)
        pix=gtk.gdk.pixbuf_new_from_file(filePath)
        pix=scaleToBg(pix, bg)
        pixbufs.append(pix)
        print("Loaded image "+filePath)

# Controls

def go(relativePos):
    global pos, reel, x, speed
    last=len(pixbufs)-1
    if pos<0:
        pos=last
    elif pos>last:
        pos=0
    
    if 0<relativePos:
        print("Next")
        if pos==last: 
            right=0
        else:
            right=pos+1 
        reel=catenate(pixbufs[pos], pixbufs[right])
        x=0 
        speed=60
    if relativePos<0:
        print("prev")
        if pos==0:
            left=last
        else:
            left=pos-1
        reel=catenate(pixbufs[left], pixbufs[pos])
        x=w
        speed=-60
    print("pos == "+str(pos))
    pos+=relativePos 

def animateSlide():
    global reel, x, speed
    if speed!=0: 
        x+=speed
        if x>=w or x<=0: 
            speed=0
        print x, reel
        pix=getBox(reel, x, w) 
        image.set_from_pixbuf(pix) 
    return True

def keyEvent(widget, event):
    global pos, image
    key = gtk.gdk.keyval_name(event.keyval)
    if key=="space" or key=="Page_Down":
        go(1)
    elif key=="b" or key=="Page_Up":
        go(-1)
    elif key=="q" or key=="F5" or key=="ESC":
        gtk.main_quit()
    else:
        print("Key "+key+" was pressed")

def pollSerial():
    if ser.inWaiting()<=0:
        #print("No data waiting in serial buffer.")
        return True # call again later
    cmd=ser.read(size=1)
    print("Serial port read: \"%s\"" % cmd)
    if cmd=="F":
        go(1)
    elif cmd=="B":
        go(-1)
    return True

# Main 

def main():
    global bg, image, ser, w
    
    w=gtk.gdk.screen_width()
    h=gtk.gdk.screen_height()
    window = gtk.Window()
    window.connect("destroy", gtk.main_quit)
    window.connect("key-press-event", keyEvent)
    window.fullscreen()
    bg=newPix(w, h)
    loadImages()
    image=gtk.image_new_from_pixbuf(pixbufs[pos])
    
    ser = serial.Serial('/dev/ttyUSB0&#8217;, 9600, timeout=0)
    gobject.timeout_add(100, pollSerial)
    
    gobject.timeout_add(30, animateSlide) 
    
    window.add(image)
    window.show_all()
    gtk.main()

if __name__ == "__main__":
    main()

handWaveFull.py

#!/usr/bin/env python
# handWaveFull.py - Choose full screen image by waving hand. 
# (c) Kimmo Karvinen & Tero Karvinen http://BotBook.com
 
import gtk, os, serial, gobject
 
# Global variables
 
dir="data"
pixbufs=[]
image=None
bg=None
pos=0
ser=None
 
# Pixbuf manipulation
 
def fitRect(thing, box):
    # scale
    scaleX=float(box.width)/thing.width
    scaleY=float(box.height)/thing.height
    scale=min(scaleY, scaleX)
    thing.width=scale*thing.width
    thing.height=scale*thing.height
    # center
    thing.x=box.width/2-thing.width/2
    thing.y=box.height/2-thing.height/2
    return thing
 
def scaleToBg(pix, bg):
    fit=fitRect(
        gtk.gdk.Rectangle(0,0, pix.get_width(), pix.get_height()),
        gtk.gdk.Rectangle(0,0, bg.get_width(), bg.get_height())
    )
    scaled=pix.scale_simple(fit.width, fit.height, gtk.gdk.INTERP_BILINEAR)
    ret=bg.copy()
    scaled.copy_area(
        src_x=0, src_y=0,
        width=fit.width, height=fit.height, 
        dest_pixbuf=ret, 
        dest_x=fit.x, dest_y=fit.y
    )
    return ret
 
def newPix(width, height, color=0x000000ff):
    pix=gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, width , height)
    pix.fill(color)
    return pix
 
# File reading
 
def loadImages():
    global pixbufs
    for file in os.listdir(dir):
        filePath=os.path.join(dir, file)
        pix=gtk.gdk.pixbuf_new_from_file(filePath)
        pix=scaleToBg(pix, bg)
        pixbufs.append(pix)
        print("Loaded image "+filePath)
 
# Controls
 
def go(relativePos): 
    global pos
    pos+=relativePos
 
    last=len(pixbufs)-1 
    if pos<0:
        pos=last
    elif pos>last:
        pos=0
 
    image.set_from_pixbuf(pixbufs[pos])
 
def keyEvent(widget, event):
    global pos, image
    key = gtk.gdk.keyval_name(event.keyval)
    if key=="space" or key=="Page_Down":
        go(1) 
    elif key=="b" or key=="Page_Up":
        go(-1)
    elif key=="q" or key=="F5":
        gtk.main_quit()
    else:
        print("Key "+key+" was pressed")
 
def pollSerial():
    cmd=ser.read(size=1)
    print("Serial port read: \"%s\"" % cmd)
    if cmd=="F":
        go(1)
    elif cmd=="B":
        go(-1)
    return True
 
# Main 
 
def main():
    global bg, image, ser
    bg=newPix(gtk.gdk.screen_width(), gtk.gdk.screen_height())
    loadImages()
    image=gtk.image_new_from_pixbuf(pixbufs[pos])
 
    ser = serial.Serial('/dev/ttyUSB1', 9600, timeout=0)
    gobject.timeout_add(100, pollSerial)
 
    window = gtk.Window()
    window.connect("destroy", gtk.main_quit)
    window.connect("key-press-event", keyEvent)
    window.fullscreen()
    window.add(image)
    window.show_all()
    gtk.main()
 
if __name__ == "__main__":
    main()

readSerial.py

#!/usr/bin/env python
# readSerial.py - Read serial port and print to screen
# (c) Kimmo Karvinen & Tero Karvinen http://BotBook.com

import serial, sys
 
# File name will be different if you are on Windows or Mac OS X
ser = serial.Serial("/dev/ttyUSB1", 9600)
 
if (ser):
    print("Serial port " + ser.portstr + " opened.")
 
while True:
    sys.stdout.write (ser.read(1))
    sys.stdout.flush()

gtkserial.py

#!/usr/bin/env python
# gtkserial.py - Read serial port with GTK.
# (c) Kimmo Karvinen & Tero Karvinen http://BotBook.com
import serial, gtk, gobject, sys
 
# File name will be different if you are on Windows or Mac OS X
ser = serial.Serial('/dev/ttyUSB1', 9600)
 
def pollSerial():
    sys.stdout.write(ser.read(1))
    sys.stdout.flush()
    return True
 
if (ser):
    print("Serial port " + ser.portstr + " opened.")
    gobject.timeout_add(100, pollSerial)
 
gtk.main()

Processing_Code_for_the_Painting.txt

// http://BotBook.com
import processing.serial.*;

int slideStep = 75;    // how many pixels to slide in/out 

// The current image and the next image to display
PImage currentImage, nextImage; 

// The index of the current image.
int imgIndex = 0; 

// Keeps track of the horizontal slide position. A negative number
// indicates sliding in from the left.
int slideOffset; 

// All the image files found in this sketch&#8217;s data/ directory.
String[] fileList; 

// A serial port that we use to talk to Arduino.
Serial myPort;

// This class is used to filter the list of files in the data directory
// so that the list includes only images.
class FilterImages implements java.io.FilenameFilter { 

  public boolean accept(File dir, String fname) {
    String[] extensions = {".png", ".jpeg", ".gif", ".tga", ".jpg"};
    
    // Don&#8217;t accept a file unless it has one of the specified extensions
    for (int i = 0; i < extensions.length; i++) { 
      if (fname.toLowerCase().endsWith( extensions[i])) {
        return true;
      }
    } 
    return false;
  }
}

// This loads the filenames into the fileList
void loadFileNames() { 
  java.io.File dir = new java.io.File(dataPath(""));
  fileList = dir.list(new FilterImages());
}


// The Processing setup method that&#8217;s run once
void setup() {

  size(screen.width, screen.height); // Go fullscreen

  loadFileNames();   // Load the filenames

  /* This centers images on the screen. To work correctly with
   this mode, we'll be using image coordinates from the center
   of the screen (1/2 of the screen height and width) .
   */
  imageMode(CENTER); 

  // Load the current image and resize it.
  currentImage = loadImage(dataPath("") + fileList[0]); 
  currentImage.resize(0, height);

  println(Serial.list()); 

  myPort = new Serial(this, Serial.list()[0], 9600); 
}

// Go to the next image
void advanceSlide() { 
  imgIndex++; // go to the next image
  if (imgIndex >= fileList.length) { // make sure we're within bounds
    imgIndex = 0;
  }
  slideOffset = width; // Start sliding in from the right
}

void reverseSlide() {
  imgIndex--; // go to the previous image
  if (imgIndex < 0) { // make sure we're within bounds
    imgIndex = fileList.length - 1;
  }
  slideOffset = width * - 1; // Start sliding in from the left
}

void draw() {

  // Put up a black background and display the current image.
  background(0);
  image(currentImage, width/2, height/2); 

  // Is the image supposed to be sliding?
  if (slideOffset != 0) { 

    // Load the next image at the specified offset.
    image(nextImage, slideOffset + width/2, height/2);
    if (slideOffset > 0) { // Slide from the right (next) 
      slideOffset -= slideStep;
      if (slideOffset < 0) {
        slideOffset = 0;
      }
    }
    if (slideOffset < 0) { // Slide from the left (previous)
      slideOffset += slideStep;
      if (slideOffset > 0) {
        slideOffset = 0;
      }
    }
    if (slideOffset == 0) { 
      currentImage = nextImage;
    }
  } 
  else {

    // If we're not sliding, read the serial port.
    if (myPort.available() > 0) {

      char inByte = myPort.readChar();
      print(inByte); // Displays the character that was read

      if (inByte == 'F') { // Forward
        advanceSlide(); 
      }
      if (inByte == 'B') { // Backward
        reverseSlide();
      }

      // Load and resize the next image
      nextImage = loadImage(dataPath("") + fileList[imgIndex]); 
      nextImage.resize(0, height);
    }
  }
}

ping.pde

/* Ping))) Sensor
  
   This sketch reads a PING))) ultrasonic rangefinder and returns the
   distance to the closest object in range. To do this, it sends a pulse
   to the sensor to initiate a reading, then listens for a pulse 
   to return. The length of the returning pulse is proportional to 
   the distance of the object from the sensor.
     
   The circuit:
    * +V connection of the PING))) attached to +5V
    * GND connection of the PING))) attached to ground
    * SIG connection of the PING))) attached to digital pin 7

   http://www.arduino.cc/en/Tutorial/Ping
   
   created 3 Nov 2008
   by David A. Mellis
   modified 30 Jun 2009
   by Tom Igoe
 
 */

const int pingPin = 2;

void setup() 
{
  Serial.begin(9600);
}

void loop()
{
  long duration, inches, cm;

  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);

  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);

  inches = microsecondsToInches(duration);
  cm = microsecondsToCentimeters(duration);
  
  Serial.print(inches);
  Serial.print("in, ");
  Serial.print(cm);
  Serial.print("cm");
  Serial.println();
  
  delay(100);
}

long microsecondsToInches(long microseconds)
{
  return microseconds / 74 / 2;
}

long microsecondsToCentimeters(long microseconds)
{
  return microseconds / 29 / 2;
}

Testing_the_Circuit_Using_LEDs.pde

/* Read 3 Ping Sensors
 Based on code by
 David A. Mellis, Tom Igoe,
 Kimmo Karvinen and Tero Karvinen
 Updated by Joe Saavedra, 2010
 http://BotBook.com
 */

const int leftPing = 2; 
const int centerPing = 3;
const int rightPing = 4;

const int leftLed = 5;
const int centerLed = 6;
const int rightLed = 7;

const int maxD = 20; // cm; maximum hand distance

void setup()
{
  Serial.begin(9600);
  pinMode(leftLed, OUTPUT);
  pinMode(centerLed, OUTPUT);
  pinMode(rightLed, OUTPUT);
}

void loop()
{
  ping(leftPing, leftLed);
  ping(centerPing, centerLed); 
  ping(rightPing, rightLed); 
  delay(50);
}

boolean ping(int pingPin, int ledPin)
{
  int d = getDistance(pingPin); // cm
  boolean pinActivated = false;
  if (d < maxD) { 
    digitalWrite(ledPin, HIGH);
    pinActivated = true;
  } else {
    digitalWrite(ledPin, LOW);
    pinActivated = false;
  }
  return pinActivated;
}

int getDistance(int pingPin)
{
  long duration, inches, cm;

  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);

  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);

  inches = microsecondsToInches(duration);
  cm = microsecondsToCentimeters(duration);
  
  return(cm); // You could also return inches
}

long microsecondsToInches(long microseconds)
{
  return microseconds / 74 / 2;
}

long microsecondsToCentimeters(long microseconds)
{
  return microseconds / 29 / 2;
}

Detect_direction_of_hand_wave.pde

/* Interactive Painting - Detect direction of hand wave
 Based on code by
 David A. Mellis, Tom Igoe,
 Kimmo Karvinen, and Tero Karvinen
 Updated by Joe Saavedra, 2010
 http://BotBook.com
 */

int slide = 0;

boolean left=false;
boolean center=false;
boolean right=false;

int leftPing = 2; 
int centerPing = 3;
int rightPing = 4;

int ledPin = 13;
int leftLedPin = 5; 
int centerLedPin = 6;
int rightLedPin = 7;

int maxD = 20; // cm 

long int lastTouch = -1; // ms
int resetAfter = 2000; // ms
int afterSlideDelay = 500; //ms; all slides ignored after successful slide
int afterSlideOppositeDelay = 1500;
// left slides ignored after successful right slide

int SLIDELEFT_BEGIN      = -1; // Motion was detected from right
int SLIDELEFT_TO_CENTER  = -2; // Motion was detected from right to center

int SLIDENONE = 0;             // No motion detected

int SLIDERIGHT_BEGIN     = 1;  // Motion was detected from left
int SLIDERIGHT_TO_CENTER = 2;  // Motion was detected from left to center

void setup() {
  Serial.begin(9600); // bit/s
  pinMode(leftLedPin, OUTPUT);  
  pinMode(centerLedPin, OUTPUT);
  pinMode(rightLedPin, OUTPUT);
}

void loop() {
  left = ping(leftPing, leftLedPin);
  center = ping(centerPing, centerLedPin);
  right = ping(rightPing, rightLedPin);

  if (left || center || right) {
    lastTouch=millis();
  }

  if (millis()-lastTouch>resetAfter ) {
    slide=0;
    digitalWrite(ledPin, LOW);
    // Serial.println("Reset slide and timer. ");
  }

  if (slide >= SLIDENONE) { // only if we are not already in opposite move
    if ( (left) && (!right) )
      slide = SLIDERIGHT_BEGIN;
    if (center && (slide == SLIDERIGHT_BEGIN))
      slide = SLIDERIGHT_TO_CENTER;
    if (right && (slide == SLIDERIGHT_TO_CENTER))
      slideNow('R');
  }

  if (slide <= SLIDENONE) {    
    if (right && (!left))
      slide = SLIDELEFT_BEGIN;
    if (center && slide == SLIDELEFT_BEGIN)
      slide = SLIDELEFT_TO_CENTER;
    if (left && slide == SLIDELEFT_TO_CENTER) {
      slideNow('L');
    }
  }
  delay(50);
}

boolean ping(int pingPin, int ledPin) {  bk

  int d = getDistance(pingPin); //cm  bl
  boolean pinActivated = false;
  if (d < maxD) {
    digitalWrite(ledPin, HIGH);
    pinActivated = true;
  } 
  else {
    digitalWrite(ledPin, LOW);
    pinActivated = false;
  }
  return pinActivated;
}


int getDistance(int pingPin) { 

  long duration, inches, cm;
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);
  pinMode(pingPin, INPUT);
  
  duration = pulseIn(pingPin, HIGH);

  inches = microsecondsToInches(duration);
  cm = microsecondsToCentimeters(duration);
  
  //return(inches);
  return(cm);
}


void slideNow(char direction) {
  if ('R' == direction) bm
     Serial.println("F");
  if ('L' == direction)
     Serial.println("B");
  digitalWrite(ledPin, HIGH);
  delay(afterSlideDelay); bn
  slide = SLIDENONE;
}


long microsecondsToInches(long microseconds) {

  return microseconds / 74 / 2;
}

long microsecondsToCentimeters(long microseconds) {

  return microseconds / 29 / 2;
}

fullScreenScale.py

#!/usr/bin/env python
# fullScreenScale.py - Show image scaled to full screen
# (c) Kimmo Karvinen & Tero Karvinen http://BotBook.com
 
import gtk, os
 
def fitRect(thing, box):
    # scale
    scaleX=float(box.width)/thing.width
    scaleY=float(box.height)/thing.height
    scale=min(scaleY, scaleX)
    thing.width=scale*thing.width
    thing.height=scale*thing.height
    # center
    thing.x=box.width/2-thing.width/2
    thing.y=box.height/2-thing.height/2
    return thing
 
def scaleToBg(pix, bg):
    fit=fitRect(
        gtk.gdk.Rectangle(0,0, pix.get_width(), pix.get_height()),
        gtk.gdk.Rectangle(0,0, bg.get_width(), bg.get_height())
    )
    scaled=pix.scale_simple(fit.width, fit.height, gtk.gdk.INTERP_BILINEAR)
    ret=bg.copy()
    scaled.copy_area(
        src_x=0, src_y=0,
        width=fit.width, height=fit.height, 
        dest_pixbuf=ret, 
        dest_x=fit.x, dest_y=fit.y
    )
    return ret
 
def newPix(width, height, color=0x000000ff):
    pix=gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, width , height)
    pix.fill(color)
    return pix
 
def main(): bs
    pix=gtk.gdk.pixbuf_new_from_file(os.path.join("data", "image1.jpg"))
    window = gtk.Window()
    window.connect("destroy", gtk.main_quit)
    window.fullscreen()
 
    bg=newPix(gtk.gdk.screen_width(), gtk.gdk.screen_height())
    pixFitted=scaleToBg(pix, bg)

    image=gtk.image_new_from_pixbuf(pixFitted)
    window.add(image)
    window.show_all()
    gtk.main()
 
if __name__ == "__main__":
    main()

Connecting_Arduino_with_Processing.txt

import processing.serial.*; 

// A serial port that we use to talk to Arduino.
Serial myPort; 


// The Processing setup method that&#8217;s run once
void setup() { 

  size(320, 320); // create a window 

  // List all the available serial ports: 
  println(Serial.list());

  /* On some computers, Arduino will usually be connected to
   the first serial port. If not, change the 0 to the
   correct one (examine the output of the previous line
   of code to figure out which one to use). */
  myPort = new Serial(this, Serial.list()[0], 9600);
}


/* The draw() method is called up to 60 times a second
 unless you change the frame rate of Processing.
 
 Normally, it is used to update the graphics onscreen,
 but we're just polling the serial port here.
 */
void draw() { 

  // Put up a black background.
  background(0);

  // Read the serial port.
  if (myPort.available() > 0) { 

    char inByte = myPort.readChar();
    print(inByte); // Displays the character that was read
  }
}