Joseph
Published © GPL3+

Wave

An application that helps people with poor motor control improve their fine motor skills though virtual-physical interactions

IntermediateFull instructions provided1,295
Wave

Things used in this project

Hardware components

Photon
Particle Photon
×1
Wii Remote
×1
Wii Remote IR Sensor PCB
×1

Software apps and online services

Firebase

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Schematics

Wave Motion Breadboard View

Unfortunately, I did not have access to the Wii IR Sensor PCB schematics. So instead, I've included the necessary connections between the sensor and the Particle Photon.

Wave Motion Top View

The top view of a physical Wave Motion.

Wave Motion Sketch

Code

Main Code

C/C++
#include "PVision.h"

PVision ircam;
byte result;
int xCoord = 0;
int yCoord = 0;
int size = 1;
int counter = 0;

int oldX = 0;
int oldY = 0;
int repeatCounter = 0;

bool init = false;
char coordinates[64];

void same(int x, int y) {
  if (x == oldX && y == oldY) {
    repeatCounter++;
    if (repeatCounter >= 10) {
      init = false;
    }
  } else {
    oldX = x;
    oldY = y;
  }
}

void setup() {
  Serial.begin(38400);
  ircam.init();
  Spark.publish("login");
  delay(1000);
}

void loop() {
  result = ircam.read();
  if (init) counter++;

  if (result & POINT) {
    init = true;
    xCoord = ircam.Point.X;
    yCoord = ircam.Point.Y;
    size = ircam.Point.Size;
  }

  same(xCoord, yCoord); // prevents sending an update when no movement was detected

  if (init && counter == 23) { // prevents sending updates every iteration
    sprintf(coordinates, "{\"X\": %u, \"Y\": %u, \"Size\": %u}", xCoord, yCoord, size);
    Spark.publish("Coordinates", coordinates);
    counter %= 23;
  }

  delay(50);
}

PVision.cpp

C/C++
Library to initialize and run the IR sensor
// Library derived from Steve Hobley and Kako

#include "PVision.h"

void PVision::Write_2bytes(byte d1, byte d2) {
    Wire.beginTransmission(IRslaveAddress);
    Wire.write(d1); Wire.write(d2);
    Wire.endTransmission();
}

PVision::PVision() {
	Point.number = 1;
}

void PVision::init () {
    IRsensorAddress = 0xB0;
    IRslaveAddress = IRsensorAddress >> 1;

    Wire.begin();

    Write_2bytes(0x30,0x01); delay(10);
    Write_2bytes(0x30,0x08); delay(10);
    Write_2bytes(0x06,0x90); delay(10);
    Write_2bytes(0x08,0xC0); delay(10);
    Write_2bytes(0x1A,0x40); delay(10);
    Write_2bytes(0x33,0x33); delay(10);
    delay(100);

    Serial.println("Initiating...");
}

byte PVision::read() {
    Wire.beginTransmission(IRslaveAddress);
    Wire.write(0x36);
    Wire.endTransmission();

    Wire.requestFrom(IRslaveAddress, 16);
    for (i=0; i<16; i++) {
       data_buf[i]=0;
    }

    i=0;

    while(Wire.available() && i < 16) {
        data_buf[i] = Wire.read();
        i++;
    }

    pointCount = 0;

    Point.X = data_buf[1];
    Point.Y = data_buf[2];
    s = data_buf[3];
    Point.X += (s & 0x30) <<4;
    Point.Y += (s & 0xC0) <<2;
    Point.Size = (s & 0x0F);

    pointCount |= (Point.Size < 15)? POINT : 0;

    return pointCount;
}

PVision.h

C/C++
Library to initialize and run the IR sensor
// Library derived from Steve Hobley and Kako

#ifndef PVision_h
#define PVision_h

#include "application.h"

#define POINT 0x01

struct Blob {
   	int X;
   	int Y;
   	int Size;
   	byte number;
};

class PVision {

public:
  PVision();

	void init();
	byte read();

	Blob Point;

private:
	int IRsensorAddress;
	int IRslaveAddress;
	byte data_buf[16];
	int i;
	int s;

	void Write_2bytes(byte d1, byte d2);
	byte pointCount;

};

#endif

Credits

Joseph

Joseph

1 project • 1 follower
I love hardware. I love the internet. I love chicken.

Comments