pain

3 min read Original article ↗

For the opcode version, on the PC side:

#include <stdio.h>
#include <sys/ptrace.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdlib.h>
#include <lo/lo.h>
#include <sys/user.h> 

int main (int argc, char *argv[]) {

  long long counter = 1; // machine instruction counter
  int  wait_val;         // child's return value
  int  pid;              // child's process id

  struct user_regs_struct red;
  unsigned int x,y,xy,ya,yb,yc,yd,ye,yf,yg,yh,yi,err,signo;
  unsigned char buffer[8];
  int exitf=0; 

  pid=strtoul(argv[1], NULL, 10);
  ptrace(PTRACE_ATTACH,pid,0,0);
  wait(&wait_val);

  if (ptrace(PTRACE_SINGLESTEP,pid,NULL,NULL) != 0)
    perror("ptracex:");

  while(!exitf){
    ptrace(PTRACE_SINGLESTEP,pid,NULL,signo);
    x=ptrace(PTRACE_GETREGS,pid,NULL,&red);
    wait(&wait_val);

    ya=red.eip;   
    if (ya>0) {
      yb=ptrace(PTRACE_PEEKDATA,pid,ya,NULL);
      printf("%c",yb%255);
    }

    if ((signo = WSTOPSIG(wait_val)) == SIGTRAP) {
      signo = 0;
    }

    if ((signo == SIGHUP) || (signo == SIGINT)) {
      ptrace(PTRACE_CONT, pid, 0, signo);
      printf("Child took a SIGHUP or SIGINT. We are done\n");
      exitf=0;
      break;
    }

  }

}

Compiles as

gcc traceopcode.c -otraceop

and then:

./traceop PROCESSID > /dev/ttyUSB0

with simple serial to servo or motor driver (L298) code running on Arduino:

/* L298

---> pins:

- from left to right on board:

1-GND 
2-supply
3-logic
4-enable->PWM
5-dir?
6-dir?
7 (far right) -> 51

- PWM2 as enable
- 52 and 53 as direction (which way?)
- 51 as sensing (pull high and is inverted)

*/

int dir1=52;
int dir2=53;
int sens=51;

void setup() {
  unsigned char x=0; long lk;
  pinMode(dir1, OUTPUT);
  pinMode(dir2, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(sens, INPUT);
  digitalWrite(sens, HIGH);
  Serial.begin(9600);

  // zero cd-needle

  while (x==0){
  x=digitalRead(sens); // switches when x=1;
  digitalWrite(dir1, HIGH); // dir2=low/1=high == IN
  digitalWrite(dir2, LOW);
  analogWrite(2, 255); // 128-255 
  }

  analogWrite(2, 0); // 128-255 

}

void loop() {
  int ll, oldll; unsigned char rr;
  long lll,x;

  rr=0;
  if (Serial.available() > 0) {
  rr = Serial.read();
  }

  // move to char within limit! == 38000 // with new psu= half 
    lll=(int)(rr*100);
    //        lll=0;
  for (x=0;x<lll;x++){
  digitalWrite(dir2, HIGH); // dir2=low/1=high == IN
  digitalWrite(dir1, LOW);
  //  digitalWrite(2,HIGH);
  analogWrite(2, 255); // 128-255 
  }
  analogWrite(2, 0); // 128-255 

  // back up till HIT!

  x=0;

  while (x==0){
  x=digitalRead(sens); // switches when x=1;
  digitalWrite(dir1, HIGH); // dir2=low/1=high == IN
  digitalWrite(dir2, LOW);
  analogWrite(2, 255); // 128-255 
  }
}
/* one SERVO */

#include <MegaServo.h>
#define NBR_SERVOS 1  // the number of servos, up to 48 for Mega, 12 for other boards
#define FIRST_SERVO_PIN 2 

MegaServo Servos[NBR_SERVOS] ; // max servos is 48 for mega, 12 for other boards

int pos = 0;      // variable to store the servo position 
int potPin = 0;   // connect a pot to this pin.

void setup()
{

  Serial.begin(9600);
  for( int i =0; i < NBR_SERVOS; i++)
    Servos[i].attach( FIRST_SERVO_PIN +i, 800, 2200);
}

void loop()
{ 

  pos=pos%148; // adjust for fingers

  if (Serial.available() > 0) {
    // read the incoming byte:
    pos = (100+(Serial.read()%80));
  }

  for( int i =0; i <NBR_SERVOS; i++) 
    Servos[i].write(pos);   
    delay(1);   
}