Hack Notes CVA 090405

From Noisebridge
Jump to: navigation, search

Hacknotes 2009-04-03

We have lots of parts, now it's a question of how to attack this biotch. We want two anklets, should we build them in parallel or in series? Answer; a bit of both.

Contents

[edit] Ready

  • Skory is too gimpy to sew well, Eric will sew up the second armature while Skory tests out the RBBBs he soldered up yesterday and get looking into building the new circuit.
  • One BUB and one RBBB needed some hot, soldery attention. Now all work, yey!

[edit] Steady

  • Breadboard up a circuit running multiple pagermotors with one shift register.
  • Shift register confounded Skory, but Eric got it going with "some" help from Lamont's code. (Thanks!)

[edit] Here's that code

/* Skory & Eric
 * Compass Vibro-Anklet
 * We Rule, April 2, 2009
 */


/* Some code from:
 * 2009-03-24, pager motor test, lamont lucas
 */
/*
Some Hitachi HM55B Compass reading code copied from: kiilo kiilo@kiilo.org
License:  http://creativecommons.org/licenses/by-nc-sa/2.5/ch/
 */

// define the pins used to run the shift registers 
int enable_low = 10;  //enable outputs, low = on
int serial_in  = 12; 
int ser_clear_low = 9;  //pulse low to zero out the shift buffer
int RCK  = 7;  //RCK, push the serial buffer to the outputs
int SRCK = 8;  //

#include <math.h>

//// define pins used to operate the digital compass (HM55B)
byte CLK_pin = 11;
byte EN_pin = 5;
byte DIO_pin = 4;

int X_Data = 0;
int Y_Data = 0;
int angle;

int status;
unsigned long serialTimer = millis();

void setup() {
  pinMode(enable_low, OUTPUT);  // set shift register pins as outputs
  pinMode(serial_in, OUTPUT);
  pinMode(ser_clear_low, OUTPUT);
  pinMode(RCK, OUTPUT);
  pinMode(SRCK, OUTPUT);
  
  // use some serial for debugging
  Serial.begin(115200);
  Serial.println("Setting up board");
  
  // make sure we start out all off
  digitalWrite(enable_low, HIGH);
  // this should wipe out the serial buffer on the shift register
  digitalWrite(ser_clear_low, LOW);
  delay(100);   //delay in ms
  
  // the TPIC6b595 clocks work on a rising edge, so make sure they're low to start.
  digitalWrite(RCK, LOW);
  digitalWrite(SRCK, LOW);
  
  digitalWrite(ser_clear_low, HIGH);   //we are now clear to write into the serial buffer

  Serial.println("Board is setup");

  // setup for HM55B compass chip
  pinMode(EN_pin, OUTPUT);
  pinMode(CLK_pin, OUTPUT);
  pinMode(DIO_pin, INPUT);

  HM55B_Reset();
}


void loop() {
  // make the compass get a reading
  HM55B_StartMeasurementCommand(); // necessary!!
  delay(40); // the data is ready 40ms later
  status = HM55B_ReadCommand();
  Serial.print(status); // read data and print Status
  Serial.print(" ");
  X_Data = ShiftIn(11); // Field strength in X
  Y_Data = ShiftIn(11); // and Y direction
  Serial.print(X_Data); // print X strength
  Serial.print(" ");
  Serial.print(Y_Data); // print Y strength
  Serial.print(" ");
  digitalWrite(EN_pin, HIGH); // ok deselect chip
  angle = 180 * (atan2(-1 * Y_Data , X_Data) / M_PI); // angle is atan( -y/x) !!!
  Serial.print(angle); // print angle
  Serial.println(" ");

  // debugging line 
  //TurnOnMotor(2);
  
  
  // 6 motors without overlap 
  if ((angle > -30) and (angle < 30)) {
    TurnOnMotor(1);
  }

  if ((angle > -90) and (angle < -30)) {
    TurnOnMotor(2);
  }

  if ((angle > -150) and (angle < -90)) {
    TurnOnMotor(3);
  } 
  
  if (((angle > 150) and (angle < 180)) or ((angle < -150) and (angle > -180))){
    TurnOnMotor(4);
  }

  if ((angle > 30) and (angle < 90)) {
    TurnOnMotor(6);
  }

  if ((angle > 90) and (angle < 150)) {
    TurnOnMotor(5);
  } 
  

  /*
  // 4 motors without overlap 
  if ((angle > -45) and (angle < 45)) {
    TurnOnMotor(1);
  }

  if ((angle > -135) and (angle < -45)) {
    TurnOnMotor(2);
  }

  if (((angle > 135) and (angle < 180)) or ((angle < -135) and (angle > -180))){
    TurnOnMotor(3);
  }

  if ((angle > 45) and (angle < 135)) {
    TurnOnMotor(4);
  } 
  */
    

}



//// FUNCTIONS

void TurnOnMotor(int which){
  // accept which from 1 to 8
  // send message to shift register as appropiate
  digitalWrite(enable_low, HIGH);
  delayMicroseconds(100);  //slow and steady
  switch(which){
    case 1:
      shiftOut(serial_in, SRCK, LSBFIRST, B10000000);
      break;
    case 2:
      shiftOut(serial_in, SRCK, LSBFIRST, B01000000);
      break;
    case 3:
      shiftOut(serial_in, SRCK, LSBFIRST, B00100000);
      break;
    case 4:
      shiftOut(serial_in, SRCK, LSBFIRST, B00010000);
      break;
    case 5:
      shiftOut(serial_in, SRCK, LSBFIRST, B00001000);
      break;
    case 6:
      shiftOut(serial_in, SRCK, LSBFIRST, B00000100);
      break;
    case 7:  // not used in current armature
      shiftOut(serial_in, SRCK, LSBFIRST, B00000010);
      break;
    case 8:  // not used in current armature
      shiftOut(serial_in, SRCK, LSBFIRST, B00000001);
      break;
    case 9:  //turn all on
      shiftOut(serial_in, SRCK, LSBFIRST, B11111111);
      break;
    default:
      // turn them all off
      shiftOut(serial_in, SRCK, LSBFIRST, B00000000);
  } 
  //in all cases, pulse RCK to pop that into the outputs
  delayMicroseconds(100);
  digitalWrite(RCK, HIGH);
  delayMicroseconds(100);
  digitalWrite(RCK, LOW);
  analogWrite(enable_low, 80);
}










//HM55B Functions
void ShiftOut(int Value, int BitsCount) {
  for(int i = BitsCount; i >= 0; i--) {
    digitalWrite(CLK_pin, LOW);
    if ((Value & 1 << i) == ( 1 << i)) {
      digitalWrite(DIO_pin, HIGH);
      //Serial.print("1");
    }
    else {
      digitalWrite(DIO_pin, LOW);
      //Serial.print("0");
    }
    digitalWrite(CLK_pin, HIGH);
    delayMicroseconds(1);
  }
}

int ShiftIn(int BitsCount) {
  int ShiftIn_result;
    ShiftIn_result = 0;
    pinMode(DIO_pin, INPUT);
    for(int i = BitsCount; i >= 0; i--) {
      digitalWrite(CLK_pin, HIGH);
      delayMicroseconds(1);
      if (digitalRead(DIO_pin) == HIGH) {
        ShiftIn_result = (ShiftIn_result << 1) + 1; 
      }
      else {
        ShiftIn_result = (ShiftIn_result << 1) + 0;
      }
      digitalWrite(CLK_pin, LOW);
      delayMicroseconds(1);
    }
  //Serial.print(":");

// below is difficult to understand:
// if bit 11 is Set the value is negative
// the representation of negative values you
// have to add B11111000 in the upper Byte of
// the integer.
// see: http://en.wikipedia.org/wiki/Two%27s_complement
  if ((ShiftIn_result & 1 << 11) == 1 << 11) {
    ShiftIn_result = (B11111000 << 8) | ShiftIn_result; 
  }


  return ShiftIn_result;
}

void HM55B_Reset() {
  pinMode(DIO_pin, OUTPUT);
  digitalWrite(EN_pin, LOW);
  ShiftOut(B0000, 3);
  digitalWrite(EN_pin, HIGH);
}

void HM55B_StartMeasurementCommand() {
  pinMode(DIO_pin, OUTPUT);
  digitalWrite(EN_pin, LOW);
  ShiftOut(B1000, 3);
  digitalWrite(EN_pin, HIGH);
}

int HM55B_ReadCommand() {
  int result = 0;
  pinMode(DIO_pin, OUTPUT);
  digitalWrite(EN_pin, LOW);
  ShiftOut(B1100, 3);
  result = ShiftIn(3);
  return result;
}
  • Crimped some ribbon cable and soldered pager motors to it spaced to fit in the little pockets of our armature.
  • Added a hole to take the wire leading away from the ribbon cable so it can attach to the top of the main circuit board on the exterior of the armature.

Cva-0.jpg

  • Next we need to figure out how to design a minimally sized circuit board to:
    1. Fit in the bigger pockets of our armature (though sticking up vertically well past the top of the band will be necessary).
    2. Allow for the mounting of the compass chip perpendicular to the board. (The board will be vertical and the chip needs to be horizontal until we get our little hands on that much-coveted third-axis!)
    3. Have convenient jacks to plug/unplug battery packs.
    4. Be somehow encased in a happy little box of some sort.

[edit] Go

  • Solution!
    1. Hide the shift register under the RBBB Cva-1.jpg
    2. Add some right-header pins at the end, have those plug into a tiny perpendicular board for the compass chip. Cva-2.jpg
    3. Have the socket for the motors' ribbon cable and the socket for the batteries dangle on external wires. This is slightly less solid of a design, but is more flexible and will make soldering MUCH easier.Cva-6.jpg
    4. If you arrange the shift register correctly under the RBBB, four out of five of the data pins between the two can just be bridged across without wires. Cva-3.jpg
  • Soldering lessons:
    • If your brain is capacious enough, figure out maximal alignment before soldering anything, or you'll end up soldering obnoxious little wires for hours.
    • If you try to be too neat, however, you will waste a great deal of time soldering in impossibly tight corners, only likely to realize that you have planned your optimistically ├╝ber-efficient circuit wrong and have to get out the solder-wick and go crazy...

Cva-4.jpg

  • (Notes on pin rearrangements breadboard vs. final board. This is just for my own reference.)
Board:		SR	RB	Rig:	SR	RB
		3	13		3	12
		8	5		8	9
	(pwm)	9	6		9	10
		12	11		12	7
		13	9		13	8
Board:		Co	RB	Rig:	Co	RB
		1	11		1	4
		2	11		2	4
		4	6		4	11
		5	4		5	5

[edit] Parts List; Things We Wish We'd Had or Had More of

  • Female clips for battery connectors (Maybe get from Al Lashers on Monday They don't have any. Dang.)
  • Shaftless pager motors (mega-bulk?)
  • Wire Strippers for 28 gage (very small) wires
Personal tools