за три для приехали халявные магниты и новые энкодеры AS5055
до этого успел найти в Питере диаметрально намагниченные магниты.
теперь у меня куча разного хлама..
итак, сегодня удалось все таки прикрепить магнит на задний конец вала.
и оно таки крутится и угол меняется ) наконецто !
но есть свои глюки..
когда вал стоит - угол все равно меняется +-2 градуса. какойто шум чтоли.. надо какото побороть.
и еще - нужно както оптимизировать алгоритм работы скетча.
прошу советов на этот счет.
по идее нужно делать проверку энкодера очень часто, чтобы при максимальной скорости прокрутки вала, код успевал отработать и выдавать результат о положении вала.
то есть наверное за каждый шаг вала (их всего 200 за полный оборот) нужно высчитывать данные датчика.. это нужно както синхронизировать, чтобы не было пропусков..
пока код выглядит так, намиксовал найденной в инете.
правда чето мотор сильно греется..
#define enablePin 3
#define MicroStep1Pin 4
#define MicroStep2Pin 5
#define MicroStep3Pin 6
#define setupTimeInMicroSec 1
int dirPin = 8;
int stepperPin = 7;
void setFullStep() {
digitalWrite(MicroStep1Pin, LOW);
digitalWrite(MicroStep2Pin, LOW);
digitalWrite(MicroStep3Pin, LOW);
delayMicroseconds(setupTimeInMicroSec);
}
void step(boolean dir,int steps) {
digitalWrite(dirPin,dir);
delay(500);
for(int i=0;i<steps;i++) {
digitalWrite(stepperPin, HIGH);
delayMicroseconds(1000);
digitalWrite(stepperPin, LOW);
delayMicroseconds(1000);
}
}
//###########################
const int ledPin = 13; // LED connected to digital pin 13, used as a heartbeat
const int clockPin = 9; // output to clock
const int CSnPin = 10; // output to chip select
const int inputPin = 11; // read AS5045
int inputstream = 0; // one bit read from pin
long packeddata = 0; // two bytes concatenated from inputstream
long angle = 0; // holds processed angle value
long anglemask = 262080; // 0x111111111111000000: mask to obtain first 12 digits with position info
long statusmask = 63; // 0x000000000000111111; mask to obtain last 6 digits containing status info
long statusbits; // holds status/error information
int DECn; // bit holding decreasing magnet field error data
int INCn; // bit holding increasing magnet field error data
int OCF; // bit holding startup-valid bit
int COF; // bit holding cordic DSP processing error data
int LIN; // bit holding magnet field displacement error data
int debug = 1; // SET THIS TO 0 TO DISABLE PRINTING OF ERROR CODES
void setup() {
pinMode(dirPin, OUTPUT);
pinMode(stepperPin, OUTPUT);
setFullStep();
//#########################
Serial.begin(9600);
pinMode(ledPin, OUTPUT); // visual signal of I/O to chip: heartbeat
pinMode(clockPin, OUTPUT); // SCK
pinMode(CSnPin, OUTPUT); // CSn -- has to toggle high and low to signal chip to start data transfer
pinMode(inputPin, INPUT); // SDA
}
void loop() {
step(true,1);
delay(1000);
//##########################
// CSn needs to cycle from high to low to initiate transfer. Then clock cycles. As it goes high
// again, data will appear on sda
digitalWrite(CSnPin, HIGH); // CSn high
digitalWrite(clockPin, HIGH); // CLK high
delay(1000); // wait for 1 second for no particular reason
digitalWrite(ledPin, HIGH); // signal start of transfer with LED
digitalWrite(CSnPin, LOW); // CSn low: start of transfer
delay(100); // delay for chip -- 1000x as long as it needs to be
digitalWrite(clockPin, LOW); // CLK goes low: start clocking
delay(10); // hold low for 10 ms
for (int x=0; x < 18; x++) // clock signal, 18 transitions, output to clock pin
{
digitalWrite(clockPin, HIGH); // clock goes high
delay(10); // wait 10ms
inputstream = digitalRead(inputPin); // read one bit of data from pin
//Serial.print(inputstream, DEC); // useful if you want to see the actual bits
packeddata = ((packeddata << 1) + inputstream); // left-shift summing variable, add pin value
digitalWrite(clockPin, LOW);
delay(10); // end of one clock cycle
} // end of entire clock cycle
//Serial.println(" ");
digitalWrite(ledPin, LOW); // signal end of transmission
// lots of diagnostics for verifying bitwise operations
//Serial.print("packed:");
//Serial.println(packeddata,DEC);
//Serial.print("pack bin: ");
// Serial.println(packeddata,BIN);
angle = packeddata & anglemask; // mask rightmost 6 digits of packeddata to zero, into angle.
//Serial.print("mask: ");
//Serial.println(anglemask, BIN);
//Serial.print("bin angle:");
//Serial.println(angle, BIN);
//Serial.print("angle: ");
//Serial.println(angle, DEC);
angle = (angle >> 6); // shift 18-digit angle right 6 digits to form 12-digit value
//Serial.print("angleshft:");
//Serial.println(angle, BIN);
//Serial.print("angledec: ");
//Serial.println(angle, DEC);
angle = angle * 0.08789; // angle * (360/4096) == actual degrees
Serial.print("angle: "); // and, finally, print it.
Serial.println(angle, DEC);
//Serial.println("--------------------");
//Serial.print("raw: "); // this was the prefix for the bit-by-bit diag output inside the loop.
if (debug)
{
statusbits = packeddata & statusmask;
DECn = statusbits & 2; // goes high if magnet moved away from IC
INCn = statusbits & 4; // goes high if magnet moved towards IC
LIN = statusbits & 8; // goes high for linearity alarm
COF = statusbits & 16; // goes high for cordic overflow: data invalid
OCF = statusbits & 32; // this is 1 when the chip startup is finished.
if (DECn && INCn) { Serial.println("magnet moved out of range"); }
else
{
if (DECn) { Serial.println("magnet moved away from chip"); }
if (INCn) { Serial.println("magnet moved towards chip"); }
}
if (LIN) { Serial.println("linearity alarm: magnet misaligned? Data questionable."); }
if (COF) { Serial.println("cordic overflow: magnet misaligned? Data invalid."); }
}
packeddata = 0; // reset both variables to zero so they don't just accumulate
angle = 0;
}