Página sobre o processo de instalação do MicroPython numa placa ESP32-PICO-KIT assim como o uso do Visual Studio Code para edição do código.
Continuar a lerArquivo da Categoria: Sem categoria
RPi setup
Serviço para arrancar meteo.py:
sudo nano -w /etc/systemd/system/meteo.service [Unit] Description=meteo After=network.target [Service] Type=simple User=%i ExecStart=/usr/bin/python /home/pi/python/meteo/meteo.py [Install] WantedBy=multi-user.target sudo systemctl --system daemon-reload sudo systemctl enable meteo sudo systemctl start meteo
Instalação do Grafana:
#!/bin/bash version="5.4.3" wget https://dl.grafana.com/oss/release/grafana_${version}_armhf.deb sudo dpkg -i grafana_${version}_armhf.deb sudo /bin/systemctl daemon-reload sudo /bin/systemctl enable grafana-server sudo /bin/systemctl start grafana-server
Montar uma partição ext4 para o InfluxDB:
lsblk sudo mkfs.ext4 /dev/sda1 sudo blkid /dev/sda1: UUID="acaa...4e9f" TYPE="ext4" PARTUUID="63...-01" sudo nano /etc/fstab PARTUUID=63...-01 /mnt/influxdb ext4 defaults 0 2 sudo chown influxdb:influxdb /mnt/influxdb sudo cp -a /var/lib/influxdb/. /mnt/influxdb/ sudo nano /etc/influxdb/influxdb.conf # under [meta] dir = "/mnt/influxdb/meta" # under [data] dir = "/mnt/influxdb/data" wal-dir = "/mnt/influxdb/wal" sudo service influxdb restart
Ativação da autenticação no InfluDB:
influx show users create user iot with password '...' with all privileges show users exit sudo nano /etc/influxdb/influxdb.conf # under [http] enabled = true bind-address = ":8086" auth-enabled = true log-enabled = true write-tracing = false pprof-enabled = false https-enabled = false https-certificate = "/etc/ssl/influxdb.pem" sudo service influxdb restart
Criação da base de dados:
influx auth username: iot password: ... show databases create database iotdb show databases sudo service influxdb restart
WinAVR no Eclipse
Página sobre o uso do WinAVR no Eclipse.
PlatformIO no Eclipse
Página que descreve o uso do PlatformIO no Eclipse.
Projetos 2016/2017
Objetivo
No intuito de obter a classificação da componente laboratorial nesta unidade curricular (até 6 valores), os estudantes deverão realizar um pequeno projeto baseado na placa ChipKIT UNO32 estudada. O Ambiente de desenvolvimento a usar pode ser qualquer um dos dois apresentados nas aulas (MPLAB X ou PlatformIO).
IMPORTANTE: De relembrar que esta componente não poderá exceder a componente dos mini testes em mais de 4 valores!
Lista de projetos
São vários os projetos passíveis de serem escolhidos por cada grupo de estudantes, não se pretendendo contudo que haja grupos com o mesmo projeto. As propostas de trabalhos são as seguintes:
- Reprodução de notas musicais usando a funcionalidade PWM
- Interface com um LED RGB e micro joystick
- Interface com o sensor de intensidade luminosa TSL230R
- Emissor e/ou recetor de sinais infravermelhos dum comando remoto duma TV
- Controlo dum motor passo-a-passo
- Interface com o módulo GPS LS20031
- Interface por I2C com o DAC MCP4728
- Interface por I2C com o DAC DAC8574
- Interface por I2C com o ADC MCP3424
- Interface por I2C com o ADC ADS1115
- Interface por SPI com o acelerómetro ADXL345
- Interface por I2C com um sensor de pressão BMP085 presente na IMU GY-80
- Interface por I2C com o magnetómetro MAG3110
- Interface por I2C com o magnetómetro HMC5883L
- Interface por I2C com o sensor de temperatura TMP75/175
- Interface por I2C com o sensor de temperatura ADT7410
- Interface 1-Wire com o sensor de temperatura DS18B20
- Interface por I2C com um display OLED 128×64 controlado pelo SSD1306
- Interface por SPI com um display OLED 128×64 controlado pelo SSD1306
- Interface por SPI com um display LCD 320×240 controlado pelo ILI9340
- Interface por SPI com um display LCD 84×48 Nokia 5110 (controlador PCD8544)
- Comunicação sem fios com os módulos NRF24L01
- Comunicação sem fios com módulos 433MHz
- Comunicação WiFi recorrendo ao módulo ESP8266
- Comunicação Bluetooth usando o módulo HC-05
- Interface com o leitor de RFID RC522
- Interface por I2C com um módulo ZS-042 (RTC DS3231 + EEPROM AT24C32)
- Interface com um cartão de memória (micro)SD
- Interface com o sensor de distâncias por IR GP2Y0A21YK0
- Interface por I2C com o sensor de distâncias por ultrassons SRF08 / SRF10
Uma procura na Internet pelo nome dos dispositivos permitirá aceder à sua datasheet!
Escolha do projeto
Os estudantes deverão comunicar ao docente a sua escolha de entre a lista acima indicada ou um projeto próprio caso ele cumpra os objetivos pretendidos. Esta escolha será realizada preenchendo um formulário até ao final do dia 4/dez. Uma vez conciliadas todas as escolhas será atribuído a cada grupo um projeto com o material necessário à sua realização.
Sessão de apresentação
A apresentação do projeto de cada grupo decorrerá numa sessão a realizar no dia 12 de Janeiro, tendo os respetivos estudantes que enviar por e-mail ([email protected]) até ao final do dia 15/jan um relatório sucinto sobre o trabalho em pdf, assim como um zip com o código fonte do projeto.
Horário
Hora | Grupo | Estudante | Estudante |
---|---|---|---|
14:00 | G01 | Pedro Pinto | Tiago Catalão |
14:10 | G02 | Tiago Pinto | Renato Ferreira |
14:20 | G03 | António Tomás Costa Nunes | Mafalda Pereira Varela |
14:30 | G04 | Guilherme José Esteves Pelayo | Hugo Miguel Malheiro de Passos Guia |
14:40 | G05 | Francisco Fonseca | Pedro Ricardo |
14:50 | G06 | Renato Cruz | Ricardo Esteves |
15:00 | G07 | Isa Vanessa Nunes de Almeida | António Pedro Rodrigues Pereira |
15:10 | G08 | Artur Jorge Coutinho Ribeiro | João Pedro Xavier Araújo |
15:20 | G09 | Isabel Cristina Rio-Torto de Oliveira | Nuno Francisco Monteiro de Barros Moreira |
15:30 | G10 | Patrícia Sá e Sousa da Costa | Ricardo de Paula Pinto Sousa Ribeiro |
15:40 | G11 | Daniel Miranda Silva Malafaia Granhão | Pedro Miguel Ramos Costa |
15:50 | G12 | Carlos Alberto Lopes Neto | Edgar dos Santos de Matos |
16:30 | G13 | André Duarte Correia de Oliveira | Nuno Miguel Rodrigues Gomes |
16:40 | G14 | Gabriel Pinheiro | Américo Duarte |
16:50 | G15 | João Neves | João Costa |
17:00 | G16 | Anabela Reigoto | Francisca Brito |
17:10 | G17 | Ana Beatriz Cruz | Marcia Sofia Alves |
17:20 | G18 | Baltasar Aroso | Pedro Costa |
17:30 | G19 | Filipa Gomes Raimundo | Nuno Fernandes Adrego |
17:40 | G20 | João Paulo Aires da Silva | Miguel André A. Tomás Ferreira de Barros |
17:50 | G21 | Joana Whiteman Catarino | Sara Serra Costa |
18:00 | G22 | António M. S. Marques Carreiro | Pedro José Ascenção Ramalho |
18:10 | G23 | Armando Nicolau Moreno | Vasco Rodrigues Arez |
18:20 | G24 | José Ribeiro | Pedro Cova |
PlatformIO 2016/17
Introdução
O PlatformIO é uma plataforma para o desenvolvimento de software destinado a várias arquiteturas e várias placas nomeadamente as ChipKIT UNO32 que usaremos nas aulas.
Uma das vantagens da utilização desta plataforma é a possibilidade de se usar as funções da biblioteca Arduino que começam a ser um autêntico standard no desenvolvimento de sistema baseados em microcontroladores.
Nesta página iremos descrever o processo de instalação e criação dum primeiro projeto para o caso particular do sistema operativo Windows embora esta plataforma possa ser usada noutros sistemas operativos como o OS X e Linux.
Instalação
Previamente à instalação do PlatformIO, e porque ele foi escrito em linguagem Python, será necessário ter previamente instalada uma versão 2.7 do Python (não a versão 3). Caso se pretenda usufruir da funcionalidade “code completion” no PlatformIO será também preciso instalar o pacote CLang.
O processo de instalação começa pela descarga do ficheiros de instalação do editor Atom disponível para o sistema operativo pretendido (platformio-atom-windows.exe no caso do Windows). Uma vez executado, é iniciada a etapa de instalação do IDE (ambiente integrado de desenvolvimento) PlatformIO:
Terminada esta etapa é apresentada a seguinte janela, onde deveremos escolher a opção de “Reload now”:
Surgindo então a seguinte janela inicial:
Criação dum projeto
Carregando no botão “New Project” da janela inicial, faz surgir um “wizard” para criação dum novo projeto:
Antes de concluir o processo (carregando no botão “Initialize“, é preciso escolher:
- a placa a usar (Selected board): no nosso caso a Digilent chipKIT UNO32
- a pasta que albergará o projeto (Choose the directory)
Neste último caso dever-se-á situar a pasta do projeto (neste exemplo chamada blink) dentro duma das 3 pastas que foram criadas para o efeito C:\usr\Alunos\COMP\3MIEEC_Tx (dependendo da turma em causa). É importante pois evitar o uso do “Ambiente de trabalho” sob pena destas serem periodicamente apagadas!
Caso a criação dum projeto para uma determinada arquitetura de placas ocorra pela primeira vez, são instaladas todas as ferramentas necessárias (a chamada toolchain) sendo durante o processo apresentada uma mensagem, neste caso: Installing platform: microchippic32. Em futuros projetos para uma mesma placa, tal já não irá repetir-se.
Criado o projeto, a sua estrutura será apresentada no lado esquerdo da janela do PlatformIO:
É preciso agora criar na pasta src um novo ficheiro (blink.cpp) com o código fonte do projeto:
O código fonte a introduzir neste exemplo, destina-se a fazer piscar um LED da placa, e é o seguinte:
#include "Arduino.h" #define LED 13 void setup() { pinMode(LED, OUTPUT); } void loop() { digitalWrite(LED, HIGH); delay(1000); digitalWrite(LED, LOW); delay(1000); }
Segue-se a fase de compilação (Build) do código, que é iniciada carregando no primeiro icon do lado esquerdo do PlatformIO:
Por fim, o ficheiro contendo o binário do programa é descarregado (Upload) para a memória Flash do PIC32 da placa através do segundo ícone do lado esquerdo do PlatformIO:
De notar que após carregar no botão de Upload, poderá ser necessário fazer Reset à placa. Desta forma o processo de descarga decorrerá sem percalços desde que o porto de ligação à placa esteja liberto. No final do processo, e face ao programa utilizado, o LED da placa ChipKIT irá piscar!
Projeto semaforo
Tendo em conta a dificuldade que houve na utilização dos botões (pois apresentam um funcionamento assíncrono) bem como da “variável” tempo, foi criado um módulo Python (gpio_utils.py) com classes que facilitam o uso destes elementos assim como dos LEDs:
import pigpio class timer: def __init__(self, pi): self._pi = pi self.reset() def reset(self): self._t = self._pi.get_current_tick() def time(self): return self._pi.get_current_tick() - self._t class button: def __init__(self, pi, pin): self._pi = pi self._pin = pin self._pi.set_mode(self._pin, pigpio.INPUT) self._pi.callback(self._pin, pigpio.FALLING_EDGE, self._cb) self._h = False def _cb(self, gpio, level, tick): self._h = True def hitted(self): tmp = self._h self._h = False return tmp def state(self): return not self._pi.read(self._pin) class led: def __init__(self, pi, pin): self._pi = pi self._pin = pin self._pi.set_mode(self._pin, pigpio.OUTPUT) self.off() def off(self): self._pi.write(self._pin, 0) def on(self): self._pi.write(self._pin, 1)
Desde logo é possível dar o primeiro passo no projeto semaforo:
import platform import pigpio import time from gpio_utils import timer, button, led if platform.uname()[4][0:3] == "arm": pi = pigpio.pi() else: pi = pigpio.pi("10.0.0.1xx") t = timer(pi) Bp = button(pi, 23) Bi = button(pi, 24) Lg = led(pi, 21) Ly = led(pi, 20) Lr = led(pi, 16) leave = False while not leave: if Bp.hitted(): Lg.on() t.reset() if Bi.hitted() or t.time() > 3000000: Lg.off() time.sleep(.05) leave = Bi.state() and Bp.state() Lg.off() Ly.off() Lr.off() pi.stop()
Para implementar o normal funcionamento pretendido para o semáforo, vamos usar uma abordagem já nossa conhecida de “Eletrónica Digital” que são as “máquinas de estados finitos” (FSM – Finite State Machines). Na sua versão mais simples teríamos o seguinte diagrama de transições de estados:
Optou-se por uma máquina de “Mealy” para minimizar as chamadas às funções da biblioteca pigpio que assim se fazem apenas quando das transições entre estados.
import platform import pigpio import time from gpio_utils import timer, button, led if platform.uname()[4][0:3] == "arm": pi = pigpio.pi() else: pi = pigpio.pi("10.0.0.1xx") t = timer(pi) Bp = button(pi, 23) Bi = button(pi, 24) Lg = led(pi, 21) Ly = led(pi, 20) Lr = led(pi, 16) # States INI = 0 SG = 1 SY = 2 SR = 3 s = INI leave = False while not leave: if s == INI: ns = SG Lg.on() t.reset() elif s == SG: if t.time() > 9000000: ns = SY Lg.off() Ly.on() t.reset() else: ns = SG elif s == SY: if t.time() > 1000000: ns = SR Ly.off() Lr.on() t.reset() else: ns = SY elif s == SR: if t.time() > 5000000: ns = SG Lr.off() Lg.on() t.reset() else: ns = SR s = ns time.sleep(.05) leave = Bi.state() and Bp.state() Lg.off() Ly.off() Lr.off() pi.stop()
Vamos agora adicionar a funcionalidade para antecipar o amarelo:
import platform import pigpio import time from gpio_utils import timer, button, led if platform.uname()[4][0:3] == "arm": pi = pigpio.pi() else: pi = pigpio.pi("10.0.0.1xx") t = timer(pi) Bp = button(pi, 23) Bi = button(pi, 24) Lg = led(pi, 21) Ly = led(pi, 20) Lr = led(pi, 16) # States INI = 0 SG = 1 SY = 2 SR = 3 s = INI leave = False while not leave: if s == INI: ns = SG Lg.on() flag = False t.reset() elif s == SG: if Bp.hitted(): flag = True if t.time() > 9000000 or flag and t.time() > 4000000: ns = SY Lg.off() Ly.on() t.reset() else: ns = SG elif s == SY: if t.time() > 1000000: ns = SR Ly.off() Lr.on() t.reset() else: ns = SY elif s == SR: if t.time() > 5000000: ns = SG Lr.off() Lg.on() flag = False t.reset() else: ns = SR s = ns time.sleep(.05) leave = Bi.state() and Bp.state() Lg.off() Ly.off() Lr.off() pi.stop()
Finalmente é adicionado o modo intermitente:
import platform import pigpio import time from gpio_utils import timer, button, led if platform.uname()[4][0:3] == "arm": pi = pigpio.pi() else: pi = pigpio.pi("10.0.0.1xx") t = timer(pi) Bp = button(pi, 23) Bi = button(pi, 24) Lg = led(pi, 21) Ly = led(pi, 20) Lr = led(pi, 16) # States INI = 0 SG = 1 SY = 2 SR = 3 INT = 4 SY1 = 5 SY0 = 6 s = INI leave = False while not leave: if s == INI: ns = SG Lg.on() flag = False t.reset() elif s == SG: if Bp.hitted(): flag = True if t.time() > 9000000 or flag and t.time() > 4000000: ns = SY Lg.off() Ly.on() t.reset() else: ns = SG elif s == SY: if t.time() > 1000000: ns = SR Ly.off() Lr.on() t.reset() else: ns = SY elif s == SR: if t.time() > 5000000: ns = SG Lr.off() Lg.on() flag = False t.reset() else: ns = SR if s == INT: ns = SY1 Ly.on() t.reset() elif s == SY1: if t.time() > 1000000: ns = SY0 Ly.off() t.reset() else: ns = SY1 elif s == SY0: if t.time() > 1000000: ns = SY1 Ly.on() t.reset() else: ns = SY0 if Bi.hitted(): Lg.off() Ly.off() Lr.off() if s == SG or s == SY or s == SR: ns = INT if s == SY1 or s == SY0: ns = INI s = ns time.sleep(.05) leave = Bi.state() and Bp.state() Lg.off() Ly.off() Lr.off() pi.stop()
Semáforo em Arduino
Esta é uma solução possível para o problema do Semáforo aqui proposto.
Para além da classe Button anteriormente já apresentada, nesta solução foram criadas 3 outras classes (Semaforo, Normal e Blink), todas definidas no ficheiro semaforo.h:
// Only modify this file to include // - function definitions (prototypes) // - include files // - extern variable definitions // In the appropriate section #ifndef _semaforo_H_ #define _semaforo_H_ #include "Arduino.h" //add your includes for the project semaforo here //end of add your includes here #ifdef __cplusplus extern "C" { #endif void loop(); void setup(); #ifdef __cplusplus } // extern "C" #endif //add your function definitions for the project semaforo here #define Bp 12 #define Bi 11 #define Lg 3 #define Ly 5 #define Lr 6 #define S_NORMAL 0 #define S_BLINK 1 #define S_ON 0 #define S_OFF 1 #define S_LG 0 #define S_LY 1 #define S_LR 2 class Normal { public: void begin(); void proc(); private: int state; long unsigned time; bool flag; }; class Blink { public: void begin(); void proc(); private: int state; long unsigned time; }; class Semaforo { public: Semaforo(); void proc(); private: int state; Normal normal; Blink blink; }; //Do not add code below this line #endif /* _semaforo_H_ */
O ficheiro semaforo.cpp será o seguinte:
// Do not remove the include below #include "semaforo.h" #include "button.h" Semaforo fsm; Button butBi(Bi); Button butBp(Bp); //The setup function is called once at startup of the sketch void setup() { // Add your initialization code here Serial.begin(115200); } // The loop function is called in an endless loop void loop() { butBi.proc(); butBp.proc(); fsm.proc(); } Semaforo::Semaforo() { pinMode(Lr, OUTPUT); pinMode(Ly, OUTPUT); pinMode(Lg, OUTPUT); digitalWrite(Lr, LOW); digitalWrite(Ly, LOW); digitalWrite(Lg, LOW); state = S_NORMAL; normal.begin(); } void Semaforo::proc() { switch (state) { case S_NORMAL: normal.proc(); if (butBi.clicked()) { state = S_BLINK; blink.begin(); } break; case S_BLINK: blink.proc(); if (butBi.clicked()) { state = S_NORMAL; normal.begin(); } break; } } void Normal::begin() { digitalWrite(Lg, HIGH); digitalWrite(Ly, LOW); digitalWrite(Lr, LOW); state = S_LG; flag = false; time = millis(); Serial.println("LG"); } void Normal::proc() { long unsigned t; switch (state) { case S_LG: if (butBp.clicked()) flag = true; t = millis() - time; if ((t > 9000) or (flag and (t > 4000))) { time = millis(); state = S_LY; digitalWrite(Lg, LOW); digitalWrite(Ly, HIGH); Serial.println("LY"); } break; case S_LY: if (millis() - time > 1000) { time += 1000; state = S_LR; digitalWrite(Ly, LOW); digitalWrite(Lr, HIGH); Serial.println("LR"); } break; case S_LR: if (millis() - time > 5000) { time += 5000; state = S_LG; digitalWrite(Lr, LOW); digitalWrite(Lg, HIGH); flag = false; Serial.println("LG"); } break; } } void Blink::begin() { digitalWrite(Lg, LOW); digitalWrite(Ly, HIGH); digitalWrite(Lr, LOW); state = S_ON; time = millis(); Serial.println("ON"); } void Blink::proc() { switch (state) { case S_ON: if (millis() - time > 1000) { time += 1000; state = S_OFF; digitalWrite(Ly, LOW); Serial.println("OFF"); } break; case S_OFF: if (millis() - time > 1000) { time += 1000; state = S_ON; digitalWrite(Ly, HIGH); Serial.println("ON"); } break; } }
Banggood
Compras à Banggood:
- OLEDs (eu)
- PCBs (eu)
- Cabo HDMI (eu)
- LEDs RGB (eu)
- Caixa RPi (eu)
- Header (eu) (single side)
- Breadboard (eu)
- Level adaptor (eu)
- Ethernet p/ Mac (eu)
- Header 2×20 p/ RPi (outro)
- Conetor 3p
Outras compras: