Vėjo greitis: nuo matavimo iki reikšmės parodymo

Vėjo greičio reikšmė paprastai ir pakankamai tiksliai pamatuojama, tačiau duomenų išvedimas yra sudėtingas. Šiame straipsnyje aprašysiu visą procesą nuo daviklio iki reikšmės parodymo ekrane.
Vėjo greičiui matuoti skirtas prietaisas vadinamas anemometru. Naudosime Three Cup Anemometer Aluminium Alloyed DC12-24V su skaitmeniniu duomenų perdavimu per RS485 portą. Taip pat išduodamas meandro formos impulsinis signalas, kurio dažnis tiesiogiai priklausomas nuo vėjo greičio. Chakteristikose nurodoma: 1m/sek. greitį atitinka 12 impulsų.

Šio prietaiso išduodamas signalas yra meandro formos impulsai:


…Daugeliui pažįstamas senovinis graikų ornamentas yra vadinamas Meandru. Šį pavadinimą ornamentas gavo nuo Meandro (gr. Μαίανδρος)
žr daugiau: kas-yra-meandras.
Vėjo greitis yra tiesiogiai priklausomas nuo meandro dažnio, arba vieno periodo trukmės. Trukmė matuojama Arduino procesoriuje milisekundėmis. Signalas nuo daviklio per LM358 komparatorių, kuris atlieka buferavimo funkciją
paduodamas į D7 procesoriais išvadą.

Laiko matavimas atliekamas standartine Arduino C funkcija pulseIn. Programos dalis.

unsigned long A, B, C;
A=pulseIn(VGROUT, HIGH, 100000); 
B=pulseIn(VGROUT, LOW, 100000); 
C=(A+B)/2;
dat[15]=lowByte(C); dat[16]=highByte(C);

PulseIn() funkcijos aprašymas:

Reads a pulse (either HIGH or LOW) on a pin. For example, if value is HIGH, pulseIn() waits for the pin to go HIGH, starts timing, then waits for the pin to go LOW and stops timing. Returns the length of the pulse in microseconds or 0 if no complete pulse was received within the timeout.
The timing of this function has been determined empirically and will probably show errors in shorter pulses. Works on pulses from 10 microseconds to 3 minutes in length. Please also note that if the pin is already high when the function is called, it will wait for the pin to go LOW and then HIGH before it starts counting. This routine can be used only if interrupts are activated. Furthermore the highest resolution is obtained with short intervals.
Syntax
pulseIn(pin, value)
pulseIn(pin, value, timeout)
Parameters
pin: the number of the pin on which you want to read the pulse. (int)
value: type of pulse to read: either HIGH or LOW. (int)
timeout (optional): the number of microseconds to wait for the pulse to be completed: the function returns 0 if no complete pulse was received within the timeout. Default is one second (unsigned long). 
Returns
the length of the pulse (in microseconds) or 0 if no pulse is completed before the timeout (unsigned long) 

Unsigned long formatas: Unsigned long variables are extended size variables for number storage, and store 32 bits (4 bytes).

Būtų gerai naudoti pertraukim1 vėjo greičio matavimui, tačiau ne visi Arduino išvadai tam tinka. pvz Arduino UNO, kurį dabar naudojame galima naudoti tik 2 ir 3 skaitmeninius išvadus. Daugiau informacijos: https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/
Atliksiu koregavimą Arduino programoje. Pakeitimas – naudojama pertraukimo procedūra – efektyvesnis programos veikimas. Gaunasi kur kas stabiliau, tiksliau matuojamos mažų vėjų reikšmės.
Taigi/ Į RPI perduodama Arduino kintamasis VejoGreitis_us. Jis matuojamas kaip laiko skirtumas tarp dviejų kylančių 2 skaitmeninio įvado frontų. Pertraukimų inicializavimas vyksta eilute:

attachInterrupt(digitalPinToInterrupt(VGROUT), rising1, RISING);

Čia VGROUT vėjo daviklio paduodamas signalas į Arduino. Visas programinis kodas dalyvaujantis šiame procese:

...
signed long VejoGreitis_us;
signed long prev_time_us;
...
const int VGROUT=2;//sukeiciau 2 ir 7 vietomis, kad turėčiau pertraukimą, kurie galimi 2 ir 3 pin'uose UNO versijai
...
void setup (void){
...
	pinMode(VGROUT, INPUT);
	attachInterrupt(digitalPinToInterrupt(VGROUT), rising1, RISING);
...
void rising1() {
  attachInterrupt(digitalPinToInterrupt(VGROUT), falling1, FALLING);
  VejoGreitis_us=micros()-prev_time_us;
  prev_time_us = micros();
}
void falling1() {
  attachInterrupt(digitalPinToInterrupt(VGROUT), rising1, RISING);
}

Sekantis žingsnis surišti pamatuotą vėjo greitį su apkrovos koeficientu.
Betz’o kreivės numatytosios (teorinės) reikšmės surašytos Arduino programinio kodo kitamąjame Betz:

byte BETZ[256]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x03,0x03,0x03,0x03,0x03,0x03,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x06,0x06,0x06,0x06,0x07,0x07,0x07,0x08,0x08,0x08,0x08,0x09,0x09,0x09,0x0A,0x0A,0x0A,0x0A,0x0B,0x0B,0x0B,0x0C,0x0C,0x0C,0x0D,0x0D,0x0D,0x0E,0x0E,0x0E,0x0F,0x10,0x11,0x11,0x12,0x12,0x13,0x14,0x14,0x15,0x15,0x16,0x17,0x17,0x18,0x18,0x19,0x1A,0x1A,0x1B,0x1B,0x1C,0x1C,0x1D,0x1E,0x1F,0x1F,0x20,0x20,0x21,0x22,0x23,0x24,0x25,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3E,0x3F,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x48,0x49,0x4B,0x4D,0x4E,0x4F,0x52,0x53,0x55,0x57,0x58,0x5A,0x5C,0x5D,0x5F,0x60,0x62,0x64,0x65,0x66,0x67,0x69,0x6A,0x6C,0x6E,0x6F,0x71,0x72,0x73,0x74,0x76,0x78,0x7B,0x7D,0x80,0x83,0x85,0x88,0x8A,0x8D,0x8F,0x92,0x94,0x97,0x9A,0x9C,0x9D,0x9F,0xA1,0xA4,0xA6,0xA9,0xAC,0xAE,0xB1,0xB4,0xB6,0xB9,0xBB,0xBF,0xC1,0xC2,0xC3,0xC5,0xC6,0xC8,0xCA,0xCC,0xCE,0xD0,0xD2,0xD4,0xD6,0xD8,0xDA,0xDC,0xDE,0xE0,0xE1,0xE3,0xE5,0xE7,0xE9,0xEB,0xED,0xEF,0xF1,0xF3,0xF4,0xF7,0xF9,0xFB,0xFD,0xFF};

Priimame, kad 0 indeksas atitinka 0m/s vėjo greitį, o 255 indeksas atitinka 16m/s (tarkim tai maksimalus galimas vėjo greitis Lietuvoje) vėjo greitį. Užduotis gautą parametrą VejoGreitis_us, kas reiškia meandro trukmę mikrosekundėmis paversti į vėjo greitį metrais per sekundę. Vėjo greičio daviklio duomenys sako, kad 1m/s greitį atitinka 12 impulsų, arba 67 milisekundės. Didesnio greičio priklausomybė yra priešingai proporcinga impulso periodo trukmei.

Deklaruojame VGRmpers kaip integer – vieno baito 256 reiksmių kintamąjį, kuris bus Betz kintamojo indeksas.
unsigned int VGRmpers;//unsigned int – 0…256, signed int, -127…+127 reiksmes
//paruosiame apkrovai vejo greitį padaugintą iš 16 (užpildysime 0-16m/s kiekvieną iš 16 vėjo greicio 16 tarpinių reiksmiu – viso 256 reiksmes)
VGRmpers=1000000*16/12/VejoGreitis_us;//VGRmpers reiškia vėjo greitį padaugintą is 16
analogWrite(Power1, BETZ[VGRmpers]);
analogWrite(Power2, BETZ[VGRmpers]);

p.s. pataisyti schemą ir aprašymus pakeičiant VGROUT įvedimo į Arduino įšvadą. Būtų gerai pakeisti ir pačio signalo pavadinimą. Žodis OUT – glumina, tarsi tai procesoriaus išvadas.
p.p.s. perduoti gen dažnio reikšmę – padidinti perduodamų baitų skaičių ir pakeisti spi lentelės struktūrą.

Parašykite komentarą