support Sharp GP2Y0A02YK0F

////////////////////////////////////////////////
// This Arduino example demonstrates bidirectional operation of a 
// Sharp GP2Y0A02YK0F distance sensor.
////////////////////////////////////////////////

#include "math.h"

unsigned long now       = 0;

const byte ir_num       = 1;
int ir_pin[]            = { A0 };
const byte read_num     = 40;
int reads[ ir_num ][ read_num ];        // the reads from the analog input

int ir_read( int i ){
  static int read_id[] = { 0, 0 };      // the index of the current reading
  static int total[]   = { 0, 0 };      // the running total
  static int average[] = { 0, 0 };      // the average
  total[ i ] = total[ i ] - reads[ i ][ read_id[ i ] ];
  reads[ i ][ read_id[ i ] ] = analogRead( ir_pin[ i ] );
  total[ i ] = total[ i ] + reads[ i ][ read_id[ i ] ];
  read_id[ i ]++;
  if( read_id[ i ] >= read_num ) read_id[ i ] = 0;
  average[ i ] = total[ i ] / read_num;
  return average[ i ];
}

void ir_parse(){
  static int ir_val[] = { 0, 0 };      // variable to store the value coming from the sensor
  static unsigned long ir_start = 0;
  static int ir_step  = 40;
  static int ir_min   = 170;
 
  if( now - ir_start > ir_step ){
    ir_val[ 0 ] = constrain( ir_read( 0 ) - ir_min, 0, 800 );
    if( ir_val[ 0 ] > 0 )Serial.println( ir_val[ 0 ] );
  }
}

//////////////////////////////////////////////////////////////////////////////

void setup() {
  for ( int i = 0; i < ir_num; i++ ) {
    for ( int thisReading = 0; thisReading < read_num; thisReading++ ) {
      reads[ i ][ thisReading ] = 0;
    }
  }  
  Serial.begin(9600);
  Serial.println( "start sharp setup" );
}

//////////////////////////////////////////////////////////////////////////////
void loop(){
  now = millis();
  ir_parse();
}

support vma401

Een stepper motor wordt aangedreven door de vier spoelen rondom de kern beurtelings te activeren. De tussenliggende tijd bepaalt de snelheid.

De 1-of-2-fase methode geeft de kleinste stap met gemiddelde kracht.
De 2-fase methode geeft de grootste kracht.

In dit voorbeeld kiezen we voor de grootste precisie, de 1-2 fase methode.
De arduino pinnen worden beurtelings hoog of laag gezet om de gekoppelde spoelen activeren. Dat kan natuurlijk in een loop, dat werkt op ieder model Arduino maar geeft een minder vloeiende beweging.
Door gebruik te maken van port manipulatie, worden de pinnen in 1 handeling hoog of laag gezet. Omdat port manipulatie per model verschillend wordt geactiveerd, is deze methode modelafhankelijk, onderstaande sketch is voor de Arduino Uno.

Verbind:

  • De stuurpinnen van de controller met digitale pinnen 2,3,4 en 5 van de Arduino.
  • De + en pinnen met de Arduino 5v poort en ground, of een andere voeding tot 12v. Vergeet dan niet de ground van die voeding te verbinden met de ground van de Arduino!

download zip-file

////////////////////////////////////////////////
// steppenmotor: 28BYJ-48, 4-phase, 8-beat motor, geared down by factor of 68.
// step angle 5.625/64, operating Frequency 100pps, current draw 92mA, ULN2003 interface board.
// Motor will run alternately left and right at random intervals.
////////////////////////////////////////////////

// binary 360 degree patterns of active pins
byte coils[8] = { B00000110, B00001110, B00001010, B00011010, B00010010, B00110010, B00100010, B00100110 };
int coil_dir = 1;
int coil_cur = 0;
byte coil_num = 8;

int run_step = 800;
int run_target = 4096;
int run_pos = 0;

unsigned long run_start = 0;  // use time - not delay() - to free the loop foor other processes
unsigned long run_now = 0;

//////////////////////////////////////////////////////////////////////////////
void setup() {
  DDRD = DDRD | B00111100; //declare the coil pins in section D as outputs
}

//////////////////////////////////////////////////////////////////////////////
void loop(){
  run_now = micros();
  if( run_now - run_start > run_step ){
    run_start = run_now;
    bounce();
    run_coils();
  }
}

//////////////////////////////////////////////////////////////////////////////
boolean run_circle(){
  switch( coil_dir ){
    case -1:
    return( run_pos > run_target );
    break;
    case 1:
    return( run_pos < run_target );
    break;
  }
}

void bounce(){
  if( !run_circle() ){
    run_pos = 0;
    coil_dir = -coil_dir;
    run_target = random( 8 ) * 512 * coil_dir;
  }
  run_pos += coil_dir;
}

void run_coils (){
  PORTD = coils[ coil_cur ];
  coil_cur += coil_dir;
  if( coil_cur<0 || coil_cur > coil_num ){
    if( coil_cur < 0 ) coil_cur = coil_num;
    else coil_cur = 0;
  }
}