Зерттеулерді санап көруге тырысқан елеулі нәтижелер

Мен енді үмітсіз қалдым және көмекке мұқтаж.

Мен автоматтандырылған обсерваторияны құрып жатырмын және қазір байқаушы күмбезді айналдыруды бақылауға тырысамын. Күмбез қадамдық қозғалтқыш көмегімен бұрылады және ол жақсы жұмыс істейді. Күмбездің айналуы, күмбездің қозғалатындығын тексеру үшін айналмалы кодтаушыға айналады. Ре - квадрат типі болса да, мен тек екі каналдан RE реакцияларын есептеймін, өйткені менде бағыт туралы ақпарат қажет емес.

Мен қазір не істеуге тырыссам, раковиналардың әрқайсысы арасында қанша қозғалтқыш қозғалысының импульсінің болғанын санау керек. Мұның негізі күмбез қозғалысын қадағалау және кептелісті анықтау. Іс жүзіндегі қозғалтқыш импульсінің барлық күмбез позицияларын есептеу үшін пайдаланылатын болады.

Оған қол жеткізу үшін мен ULN2803A инвертирующего аралық және Arduino Nano бар кішкентай тақта жасадым. Нано Реквизиттерді есепке алу үшін Pin өзгертулерді D11 және D12 пинктерінде пайдаланады. Pin D7, сондай-ақ, ол қазіргі уақытта жоқ болса да, Home Position ұстанымын бақылау үшін пайдаланылады. Қозғалтқыш импульстері аралық арқылы D2 (INT0) порты арқылы жіберіледі және қозғалтқыш бағыты D3 (INT1) түйреу үшін буфер арқылы жіберіледі. Сыртқы үзілістер қозғалтқыш бағытына байланысты жоғары немесе төмен қозғалтқыш импульстарын есептеу үшін пайдаланылады.

Қосымша ақпарат үшін, Velleman VM110 USB шығып қалу тақтасы бар, ол сонымен қатар айналмалы кодтаушы кенелерді алады. Бұл айналмалы кодтау білігін қолмен айналдырған кезде менің тақтамды бірдей жауап беретіндігін тексерудің қарапайым әдісін береді.

Жақсы - өкінішке орай, бұл ұзақ уақытқа созылған, бірақ қазір таңқаларлық.

РС-ді қозғалтқышсыз айналдырғанда бәрі жақсы. Мен Velleman тақтасы ретінде төрт есе көп импульс алып отырамын, себебі координатордың толық циклдерінде емес, әр көтерілу мен құлдырауды енгізе отырып Pin Changes қолданамын. Бұл алдын-ала айтылғандай орын алады және барлығы жақсы және тұрақты.

БІР - қозғалтқышты іске қосқан кезде, кодерлерді жылжытқан сайын жүздеген RE шағылысымды аламын, кейде кодексті көтермей-ақ ұлғайтады.

Ашық жауап - бұл РФО-ның кейбір түрі, бірақ мен оны жою үшін қолымнан келгеннің бәрін жасадым. Қозғалтқыш драйвері мен Nano board, оны қуат беретін корпусында, қозғалтқышқа арналған кабель экрандалған кабель болып табылады және менде төрт қозғалтқыштың әрқайсысында 10UH түтіктер бар. Ақыр соңында, кез келген RFI қуат желілерін төмендететін минимумды төмендету үшін қозғалтқыш қорабына кіретін қуат көзіне фильтр орнатқанмын.

ULN2803A буферін пайдалану бұл жұмысты жасауға менің соңғы әрекетім болды. Бұрын сигналдар Nano шпалдарына тікелей барды. Аралықпен кіріс жағында 20 кг көтеріліп, шығу кезінде 10 кг-ны көтерді. Бұл Velleman тақтасының кіріс тізбегінің тікелей көшірмесі болатын, ол мені қиындықсыз жұмыс істеді.

Механикалық импульстарға кірігімдегі Наноға менің көзқарасым бойынша қарадым, олар 70 ш.с. ұзақтылығы мен 497 Гц жиілігінің өткір қырлы импульсы. Мен Accelstepper кітапханасын 500 Гц-ге дейін пульстің жылдамдығын орнатқан кезде жаман емеспін.

Мен қазір бағдарламалық қамтамасыз ету мәселесі деп ойлаймын. Бұл мені таңғалдырмайды, өйткені мен бұл үшін өте жаңа, тек маған қажетті нәрсені жасау үшін әрбір кезеңде жеткілікті түрде үйренуге тырысамын. Мен кодты тіркедім - бұл проблемаларымға қатысы жоқ I2C материалдарының көптігінен айырылған нұсқасы.

Қайтадан ақпарат үшін. attachInterrupt() функциясын пайдаланып көрдім және тиісті тіркеулерді тікелей орнату арқылы - ешқандай айырмашылық жоқ!

Қалай болғанда да, мен шынымен де шын мәнінде бұл біреуді сұрыптауға көмектесетініне сенімдімін.

Құрметпен, Хью

/*          
ABoard3  
ROTATION MONITORING AND POSITION
Version AB3_stripped
*****************************PURPOSE*****************************************
This sketch is used on an Arduino Nano to count the motor pulses from ABoard1
and the Rotary Encoder ticks. The motor pulse count between encoder ticks is
used to detect dome jamming.
****************************INPUTS*******************************************
PIN CHANGE INTERRUPTS
**********ROTARY ENCODER INPUT*********
The rotary encoder is a Bourns ENA1J-B28 L00064L 1139M MEX 64 cycle per turn
optical encoder. This is connected to ABoard3 Pins D11 and D12. These pins
connect to Channel A and Channel B respectively. Pin change interrupts are used
to receive the rotary encoder output.
(The output pulses from the rotary encoder is also sent to the Velleman board
for use by LesveDomeNet for finding dome position)
*********HOME POSITION INPUT*********
The home position sensor is an Omron EESX671 Optical Sensor.
The sensor output is connected to ABoard3 Pin D7.
Pin change interrupt PCINT21 records activation/deactivation of the sensor.
EXTERNAL INTERRUPTS
*********MOTOR PULSE INPUT***********
The pulses sent to the G251X stepper driver are also sent to Aboard3 Pin D2.
This pin is the External Interrupt pin, vector INT0
*********MOTOR DIRECTION INPUT********
Motor direction is input to ABoard3 from ABoard2. ABoard2 pin, pnVmInRotMotor
(AB2:A0{54}) is connected to Velleman pins DI4 and DO2 and also to AB3:D3.
AB3:D3 is an External Interrupt pin, vector INT1.
*/

#include                        
#include "streaming.h"                        
#include "I2C_AnythingHEG.h"   
#include                     

//CONSTANTS                       
//PIN ASSIGNMENTS For ABOARD3
const uint8_t pnMotorPulse = 2;      //Port PD2, INT0, ISR(INT0_vect){}
const uint8_t pnMotorDirection = 3;  //Port PD3, INT1, ISR(INT1_vect){}
const uint8_t pnDomeAtHome = 7;      //Port PD7, PCINT23,ISR(PCINT2_vect){}
const uint8_t pnREChanA = 11;        //Port PB3, PCINT3, ISR(PCINT0_vect){}
const uint8_t pnREChanB = 12;        //Port PB4, PCINT4, ISR(PCINT0_vect){}

//*****************EXPERIMENTAL STUFF FOR PULSE COUNTING*******************************                  
uint16_t volatile myTest = 0;
int32_t volatile ratioCount = 0L;
int32_t volatile totalCount = 0L;
int32_t volatile tickCount = 0L;
uint8_t volatile halftickCount = 0;
int32_t volatile addPulse = 0L; 

void setup() {
  //**********************************SERIAL FOR DEBUG ONLY************************
  Serial.begin(115200);
  //*************************INPUT PIN MODE SETUP**********************************
  //NOTE Set all UNUSED PCINT0:5 pins (D8, D9, D10, D11) to OUTPUT.
  //and set the value to LOW
  //The actual pins used to receive interrupts have external 10k pull-ups.
  //This is to reduce susceptibility to interference causing false triggering.
  pinMode(pnMotorPulse, INPUT); //D2
  pinMode(pnMotorDirection, INPUT); //D3
  pinMode(pnDomeAtHome, INPUT); //D7
  pinMode(pnREChanA, INPUT); //D11
  pinMode(pnREChanB, INPUT); //D12
  pinMode(4, OUTPUT); //D4
  digitalWrite(4, LOW);
  pinMode(8, OUTPUT); //D8
  digitalWrite(8, LOW);
  pinMode(9, OUTPUT); //D9
  digitalWrite(9, LOW);
  pinMode(10, OUTPUT); //D10
  digitalWrite(10, LOW);
  //******************SET UP AddPulse According to Motor Direction******************
  //This is needed to make sure the pulse counting starts in the correct direction
  //as the direction is only checked in the ISR after a change has occurred.
  //If Motor Direction is AntiClockwise, change to Subtract a pulse
  if( digitalRead(pnMotorDirection)) {
    addPulse = 1L;
  } else {
    addPulse = -1L;
  }
  //**************************SET UP PIN CHANGE INTERRUPTS**************************
  //Set the Pin Change Interrupt Masks
  //Clear all bits to start with
  PCMSK0 &= 0b00000000; //Clear all bits
  PCMSK1 &= 0b00000000; //Clear all bits
  PCMSK2 &= 0b00000000; //Clear all bits
  //Mask for PCINTs 0 through 7 is PCMSK0 (Rotary Encoder Pulses)
  //Need to allow interrupts on PCINT3 and PCINT4, so set bits 3 and 4
  //PCINT3 is Nano  pin D11 and PCINT4 is Nano pin D12
  //Use a compound bitwise OR to set the bits
  PCMSK0 |= 0b00011000; //Enable PCINT3 ONLY (bit 3)
  //Interrupt on pins 11 and 12, RE Ticks
  //Mask for PCINTs 16through 23 is PCMSK2 (Home Position)
  //Need to allow interrupts on PCINT23 so set bit 7
  PCMSK2 |= 0b10000000; //Interrupt on pin 7, Home Position Sensor activated
  //Now enable the interrupts (TURN THEM ON) by setting bits in PCICR
  //PCICR is Pin Change Interupt Control Register.Set bit 0 (PCIE0)  
  //to enable interrupts PCINT0:7 This catches PCINT3 and 4 - RE Ticks
  //Set bit 2 (PCIE2) to enable interrupts PCINT16:23. Catches PCINT21 - Home Position Sensor
  PCICR &= 0b00000000; //Clear PCICR register 
  PCICR |= 0b00000001; //Set bit 0 - Catches PCINT3 & PCINT4 - RE Ticks
  PCICR |= 0b00000100; //Set bit 2 - Catch PCINT21 - Home Position Sensor
  //**************************SET UP 'EXTERNAL INTERRUPTS'**************************
  //Interupts on External Interrupt Pins D2 (INT0) and D3 (INT1).
  //INT0 (Nano pin D2)occurs when a stepper motor driver pulse is received
  //INT1 (Nano pin D3)occurs when the ABoard2 pin, pnVmInRotMotor toggles 
  //indicating a motor direction change.
  //To use the 'External Interrupts' the following registers need to be set-up:         
  //EICRA External Interrupt Control Register A       
  //Need to set Interrupt Sense Control bits ISC11 .. ISC00 (bits 3:0 in EICRA)
  //ISC01     ISC00 (INT0)    Interrupt
  //ISC11     ISC01 (INT1)    Generated by
 // 0         0             Low level on Pin
 // 0         1             Any Logical Change
 // 1         0             Falling Edge
 // 1         1             Rising Edge
  //First clear all bits, then set as follows:  
  //For INT1 - Motor Direction - Generate on ANY LOGICAL CHANGE     
  //bit 3 ISC11 0     
  //bit 2 ISC10 1 This combination = Any logical change causes interrupt 
  //For INT0 - Stepper Motor Pulses  - Generate on RISING EDGE      
  //bit 1 ISC01 1     
  //bit 0 ISC00 1 This combination = Rising edge of pulse causes interrupt
  //NOTE: To provide some immunity to RFI, Aboard3:Pins 2 & 3 are pulled high
  //using 10k resistors. 
  //So, code is
  EICRA &= 0b00000000; //Clear EICRA register
  EICRA |= 0b00000111;//Set bits 0,1 and 2 in EICRA register
  //EIMSK External Interrupt Mask Register        
  //Need to set External Interrupt Request Enables INT1 & INT0  (bits 1:0)          
  //First clear both bits, then set as follows: 
  //bit 1  INT1  1 External interrupt pin (D3) enabled   
  //bit 0  INT0  1 External interrupt pin (D2) enabled   
  //So, code is
  EIMSK &= 0b00000000; //Clear EIMSK register
  EIMSK |= 0b00000011;//Set bits 0 and 1 in EIMSK register
  //NOTE: Setting EIMSK TURNS ON THE EXTERNAL INTERRUPTS
  //************VARIABLE INITIALISATION*********
  myCommand = 0;
  myTest = 0;
  tickCount = 0L;
  totalCount = 0L;
} //END of setup

void loop() {
  //******************************COMMAND ACTIONS******************************
  if (myTest == 3) (
    //RE tick
    Serial << "Tick Count = " << tickCount << "  totalCount = " << totalCount << "\n";
    myTest = 0;
  }
}
//*************************FUNCTIONS/ISRs FROM HEREON*************************
ISR(INT0_vect) {
  //Triggered by stepper motor drive pulse from ABoard1
  totalCount = totalCount + addPulse;
}
ISR(INT1_vect) {
  //Triggered by a change in motor direction
  if(digitalRead(pnMotorDirection)) {
    addPulse = 1L;
  } else {
    addPulse = -1L;
  }
}
ISR(PCINT0_vect) {
  //Triggered by a ROTARY ENCODER TICK
  halftickCount++;
  if (halftickCount == 2) {
    //Make count same as Velleman
    tickCount++;
    halftickCount = 0;
    myTest = 3;
  }
}
ISR(PCINT2_vect) {
  //Triggered by activation of Home Position Sensor
  myTest = 4;
}
0
1) Сізде ауқым бар, сіз оны қозғалтқыш импульстарын қарау үшін қолдандыңыз. Сондай-ақ кодтаушы импульстерді қарастырдыңыз ба? Олар қалай көрінеді? 2) Квадратуралық кодерде, мен бір арнаның кез-келген уақытта «шапшаң» болуын күтемін. Содан кейін кодты әдеттегі жолмен қолдансаңыз, +1, -1, +1, -1 ... нөлге дейін қосу керек. 3) AVR I/O тіркелімдерін орнату үшін стандартты идиома PCMSK0 = _BV (PCINT3) | _BV (PCINT4); , қарағанда PCMSK0 & = 0b00000000; PCMSK0 | = 0b00011000; , кем дегенде, AVR бағдарламасымен таныс адамдарға арналған.
қосылды автор Sprogz, көзі
PCMSK0 & = 0b00000000;//барлық биттерді өшіру - PCMSK0 = 0; көп емес пе? Сонымен бірге Гербеннің жауабымен келісемін. Үзілістермен орнатылған көп байттық айнымалыларға қол жеткізуді «сақтау» әрекетін орындап көріңіз. <�үзілістерді »қараңыз.
қосылды автор Nick Gammon, көзі
Quadrature encoder шығысы мен Arduino арасындағы дұрыс ортақ орын бар ма? Солай болса, @EdgarBonet дұрыс. Квадратура коэффициенттері ақылды секілді секіре алады, сондықтан сіз шынымен кодты дұрыс оқып, қадамдық бағытты және әрбір оқылымнан анықтау керек. Осылайша, егер ол +1 және одан кейін -1, немесе кез-келген басқа тізбекті 100 рет қайталаса, онда сіз жаңа орынның қандай екенін білесіз және сол арқылы сіз оны бұзып жібердіңіз. Әрбір квадратураның шығуына 2.2uF қақпағын қосып көріңіз, аппараттық қамтамасыз етуді азайтуға көмектесу үшін.
қосылды автор meepsh, көзі
Шифрлаушыны дұрыс оқып шығу - сізге шынымен мұқтаж деп тапқан бағдарламалық жасақтама.
қосылды автор meepsh, көзі
Айналмалы кодтаушы электрлік немесе оптикалық ма? Мен сөндіргішіне немесе оптикалық ресивердің шекараға соғылып кетуіне байланысты мәселе бар ма деп сұраймын. Егер бұлай болса, оны шешуге көмектесетін бір тәсілі - квад кодталған импульстарды дұрыс ажырату болып табылады. Бұл блог жазба төрт кодтық импульстарды декодтаудың сенімді әдісін көрсетеді: thewanderingengineer.com/2014/08/11/… Regads,
қосылды автор CMaster, көзі
Процессорда пікірталас жасаудың баламасы, осы мақсатқа арналған чипті пайдалану болып табылады. Сәйкес келетін мына: elmelectronics.com/ic/elm402 Құрметпен,
қосылды автор CMaster, көзі

1 жауаптар

Кейбір айнымалылар үшін int32_t пайдаланудың қажеті жоқ. 8 биттік процессордағы 8 биттен астам айнымалы мәндерді пайдалану проблемасы, мәнді алу үшін процессорға 4 оқиды. Олардың ортасында үзіліс орын алуы мүмкін, бұл ескі мәннің кейбір биттері және жаңадан бірнеше биттері бар мәнге әкеледі.

Кейбір айнымалы 8 биты ғана қажет.

uint8_t volatile myTest = 0;
int32_t volatile totalCount = 0L;
int32_t volatile tickCount = 0L;
uint8_t volatile halftickCount = 0;
int8_t volatile addPulse = 0L; 

Келесі нәрсе - атомдық құндылықты оқу.

void loop()                                             
{                                               
//******************************COMMAND ACTIONS******************************  

if (myTest == 3)   //RE tick
{
    noInterrupts();
    int32_t tickCountCopy = tickCount;
    int32_t totalCountCopy = totalCount;
    interrupts();
    Serial << "Tick Count = " << tickCountCopy << "  totalCount = " << totalCountCopy << "\n"; 
    myTest = 0; 
}
}   

PS. бұл міндетті емес, бірақ бұл түсініктемелерге сәйкес келмейді.

1
қосылды
Мұнда нағыз нəрсе жоқ, бірақ сіз күткендегідей өткір емес сияқты. Менің болжауымша, шиптет триггері жұмыс істейтін болады. Менің жауабым сіздің проблемаңызды шешпесе де, сіздің кодыңызда есеп беруі мүмкін мәселені көрсетеді.
қосылды автор Al., көзі
Сәлем, және Gerben және Nick алғыс. Мен сіз ұсынған өзгерістерді жасадым, бірақ олар іс жүзінде нашарлайды, жақсы емес, өйткені тіпті қадамдық қозғалтқышсыз жұмыс істеп жүргенде, мен әрбір RE арналарында бірнеше рет іске қосылдым.
қосылды автор SeaDrive, көзі
Қап, жаңа сызық пен басымдылықты қайтаруды талап етті, бірақ ол аяқталғанша түсініктеме жіберді. Мәселен, қазірдің өзінде пішімдеудің жетіспеуін ақтаңыз. Мен Rotary Encoder-ты шағымдануым керек деген қорытындыға жеттім. Мен бұл оптикалық кодшық болғандықтан, оны бұзуды талап етпейтіндіктен, менің болжамым дұрыс емес деп ойладым. Мен RC уақытын пайдалану арқылы кішкене аппараттық дебитаторды жасап, Schmit триггерінің И.С. Деп үміттенемін шляпалар мәселені шешеді. Жақсы жаңалық - нақты қадамдық қозғалтқыш импульсінің ешқандай қиындықсыз есептелетіндігі. Рахмет, Хью.
қосылды автор SeaDrive, көзі
Сәлеметсіз бе, менің кодтаманың нәтижелерін көру үшін өзімнің кеңістігімді қолдануға тырыстым, бірақ мен оны қалай дұрыс пайдалану керектігін білмеймін және маңызды нәтижелерге қол жеткізе алмадым. Әрбір кодтаушы каналда 5 мс-тан кем емес кідіріс жасау арқылы дебютант тақтасын жасадым, ақыр соңында бәрі де жұмыс істейді. Мен бұл мәселені желтоқсан айының басында алдым, сондықтан оны шешу үшін барлық уақытты алды. Іс жүзінде бұл нақты мәселемен көмектесу үшін менің кеңістігімді сатып алды. Жауап берген және түсіндірген барлық адамдарға тағы да рахмет. Құрметпен Хью
қосылды автор SeaDrive, көзі
@HughGilhespie, егер мәселе қазір шешілсе, өзіңіздің сұрағыңызға жауап жазыңыз және оны шешілген деп белгілеңіз.
қосылды автор meepsh, көзі