Vėjo daviklio emuliatorius

Kad nereikėtų laikyti prijungto vėjo greičio daviklio, sukursime jo emuliatorių. Idėja atrodo sekančiai: Raspberry (toliau Rpi) parašysime programą, kuri generuos meandro formos impulsą ir jį paduosime į Arduino vieną iš skaitmeninių įėjimų.

Dar kartą peržiūrėkime Rpi GPIO išvadus ir jų paskirtį. Žemiau informacija iš: http://raspi.tv/2013/rpi-gpio-basics-4-setting-up-rpi-gpio-numbering-systems-and-inputs

rev2-gpio-bold-173x300

  • raudonai pažymėti yra +3V3 bei +5V maitinimo kontaktai
  • juodai pažymėti yra „Žemės” kontaktai
  • geltonai pažymėti yra bendro naudojimo  I/O portai (beje, 18 yra PWM-inis).

Likusieji taip pat gali būti naudojami kaip  GPIO portai, tačiau jie yra priskirti funkcijoms. Jei užtenka 8 portų rekomenduotina naudoti pažymėtus geltonai išvengiant galimų konfliktavimų su kitomis sąsajomis. Trumpai kitų sąsajų išvadai…

  • žaliai/pilkas – i2c sąsaja
  • šviesiai pilki – UART (nuosekli sąsaja)
  • oranžiniai– SPI (Serial Peripheral Interface) sąsaja.

Tarkime, pasirinkome GPIO4 7 išvadą kaip impulsų generatoriaus išėjimą. Jį reikia sujungti su Arduino skaitmeniniu įėjimu, kuris, tarkim bus ~3 (čia tildė nurodo, kad tai bus PVM ‘inis išvadas, matuosime impulso ilgį dažnio nustatymui: Hz=1/sek). Čia tinkama bendra Rpi-Arduino sujungimų nuotrauka.

Meandro generavimo programos pagrindu naudosime (TY joan) http://raspberrypi.stackexchange.com/questions/19765/rpi-gpio-as-a-high-speed-square-wave-generator parašytą C kalba. Pavadinsime meandras.c:

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <pigpio.h>
#define GPIO 4
#define ON   10
#define OFF  10
static int gpio = GPIO;
static int on   = ON;
static int off  = OFF;
gpioPulse_t pulse[2];
void fatal(char *fmt, ...){
   char buf[256];
   va_list ap;
   va_start(ap, fmt);
   vsnprintf(buf, sizeof(buf), fmt, ap);
   va_end(ap);
   fprintf(stderr, "%s\n", buf);
   exit(EXIT_FAILURE);
}
void usage(){
   fprintf(stderr, "\n" \
      "Usage: sudo ./square [OPTION] ...\n" \
      "   -f value, off micros, 1- (%d)\n" \
      "   -g value, gpio, 0-31     (%d)\n" \
      "   -n value, on micros, 1-  (%d)\n" \
      "EXAMPLE\n" \
      "sudo ./square -g 23\n" \
      "  Generate square wave on gpio 23.\n" \
   "\n", OFF, GPIO, ON);
}
static void initOpts(int argc, char *argv[]) {
   int i, opt;
   while ((opt = getopt(argc, argv, "f:g:n:")) != -1) {
      i = -1;
      switch (opt) {
         case 'f':
            i = atoi(optarg);
            if (i >= 1) off = i;
            else fatal("invalid -f option (%d)", i);
            break;
         case 'g':
            i = atoi(optarg);
            if ((i >= 1) && (i <= 31)) gpio = i;
            else fatal("invalid -g option (%d)", i);
            break;
         case 'n':
            i = atoi(optarg);
            if (i >= 1) on = i;
            else fatal("invalid -n option (%d)", i);
            break;
         default: /* '?' */
            usage();
            exit(EXIT_FAILURE);
        }
    }
}
int main(int argc, char *argv[]) {
   int wid;
   initOpts(argc, argv);
   printf("gpio #%d, on %dus, off %dus\n", gpio, on, off);
   if (gpioInitialise()<0) return -1;
   gpioSetMode(gpio, PI_OUTPUT);
   pulse[0].gpioOn = (1<<gpio);
   pulse[0].gpioOff = 0;
   pulse[0].usDelay = on;
   pulse[1].gpioOn = 0;
   pulse[1].gpioOff = (1<<gpio);
   pulse[1].usDelay = off;
   gpioWaveClear();
   gpioWaveAddGeneric(2, pulse);
   wid = gpioWaveCreate();
   if (wid >= 0) {
      gpioWaveTxSend(wid, PI_WAVE_MODE_REPEAT);
      while (1) sleep(1);
   }
   gpioTerminate();
}

Kompiliavimui papildomai naudojame pigpio biblioteką, taigi kompiliavimo eilutė pailgėja:

gcc -o meandras.o -L/usr/lib -lmysqlclient -lpigpio -I/usr/local/include -L/usr/local/lib -lwiringPi meandras.c

Paduodame iš Rpi 7 kontakto GPIO4 signalą į Arduino plokštės D3 kontaktą. Signalo apdorojimui pasirinkime iš http://www.benripley.com/diy/arduino/three-ways-to-read-a-pwm-signal-with-arduino/

straipsnyje aprašytų trijų būdų antrą, šiek tiek pakeičiame programos tekstą. Rezultatą saugome [17] ir [18] dat masyvo elementuose.

const int VejoPin=3;

volatile int pwm_value = 0;
volatile int prev_time = 0;

Setup{

attachInterrupt(digitalPinToInterrupt(VejoPin), rising, RISING);

}

void rising() {
attachInterrupt(digitalPinToInterrupt(VejoPin), falling, FALLING);
VejoGreitisx10=micros()-prev_time;
VejoGreitisx10=10000000/VejoGreitisx10;
dat[17]=lowByte(VejoGreitisx10); dat[18]=highByte(VejoGreitisx10);
prev_time = micros();
}
void falling() {
attachInterrupt(digitalPinToInterrupt(VejoPin), rising, RISING);
}

 

Liko dažnio keitimas nuo potenciometro, kuris bus pajungtas į Arduino A0 įėjimą, padėties. A0 reikšmės bus perduodamos per SPI sąsają. meandras programą integruosiu į pagrindinę programą. Bet tai jau rytoj.

Viena mintis apie “Vėjo daviklio emuliatorius

Parašykite komentarą