STE29008-2019-2

De MediaWiki do Campus São José
Ir para: navegação, pesquisa

Índice

Sistemas Embarcados: Diário de Aula 2019-2

29/07/2019 – Apresentação

31/07/2019 – Introdução

05/08/2019 – GPIO


  • Definição das Duplas:
    • Daniel e Anderson
    • Ameliza e Natalia
    • Guilherme e Marcone
    • Allex e Douglas
    • Fabiano e Filipe Kuhnen
    • Felipe Cardoso e Luiza
    • Gustavo e Gabriel

07/08/2019 – Experimento UART

12/08/2019 – Projeto 1: Sensor de Temperatura - Arduino

Atividade

O objetivo deste experimento é apresentar um exemplo básico de programação de sistema embarcado com microcontrolador. Para isto, será desenvolvido um sensor de temperatura com comunicação serial utilizando a plataforma Arduino.

  • Material necessário:
    • Arduino Uno;
    • Termistor NTC 10KOhm;
    • Resistor 10KOhm;
    • Matriz de contato;
    • Computador com IDE do Arduino instalada.
  • Para completar o desafio, utilize o site arduino.cc como referência, e construa um sketch (programa na IDE do Arduino) que, a cada 1 segundo, pisque um LED (veja o LED já na placa do Arduino no pino 13), e leia um valor do sensor de temperatura e escreva, em graus celcius, na tela. Um pseudo-código da sua aplicação seria:
loop() {
    ligaLED();
    AdquireTemperatura(); // lê do ADC e converte para Celcius
    desligaLED();
    ImprimeResultado(); // pela serial
    dorme1segundo();
}
  • Para completar esta atividade, você precisará:
    • Montar um circuito com divisor de tensão utilizando o NTC e o resistor para aquisição do sinal através de uma porta analógica do Arduino
    • Especificar um modelo (equação) para obter o valor da resistência do NTC a partir do valor de tensão lido no canal analógico do Arduino;
    • Utilizar o modelo de Steinhart-Hart para obter a temperatura a partir da resistência;
    • Calibrar o seu sistema para temperaturas entre 0 e 50 graus celcius (utilize esta calculadora e a tabela de resistência-temperatura do seu NTC abaixo);
    • No programa arduino, implemente duas versões do software: uma utilizando apenas "float" e outra utilizando apenas "int 32-bits" (compare as versões).
  • Entregue um relatório curto (1 página), comparando os resultados obtidos em termos de:
    • Uso de memória de programa (flash - código-fonte);
    • Uso de memória de dados (RAM);
    • Tempo necessário para o cálculo (conecte o pino do LED a um osciloscópio - o tempo que o LED fica acesso é o tempo que leva para fazer o cálculo).
  • Observações:
    • O trabalho deve ser executado em dupla.
    • Entrega até 18/08 via Sigaa


NTC-10Kohm-tabela.jpg

14/08/2019 – Projeto 1: Sensor de Temperatura - Arduino (cont.)

19/08/2019 – Correção Projeto 1

  • Implementado em conjunto a versão long e float.


21/08/2019 – Usando C++

Mudança de nível de abstração


Portas arduino MEGA.png


Fonte: https://www.arduino.cc/en/Hacking/PinMapping2560


Megapdf.jpg

ATmega2560: I/O Ports


  • Tabela verdade de configuração das portas:

Port Pin Configurations.png


  • Endereços registradores de I/O:

Io registers address 2560.png

GCC, avr-libc

Fluxo Ferramentas:

Avr-gcc.png


AVR-LIBC:

Desenvolvimento:

  • É obrigatório a instalação das ferramentas (Toolchain e AVR-Libc).
  • O aluno pode escolher usar o MPLAB X ou montar seu próprio Makefile.
  • Gravação:
    • avrdude
    • MPLAB X: avrdude -c avrispmkII -P /dev/ttyUSB0 -D -p ${Device} -U flash:w:${ImagePath}:i
    • Terminal: avrdude -c avrispmkII -P<PORTA> -D -p ATmega2560 -U flash:w:<HEX>:i

Prática

26/08/2019 – Usando C++ (cont.)

Prática

  • Configuração da ferramenta:
    • Tools -> Options -> Embedded -> Build Tools-> Add
    • Base Directory: /opt/microchip/avr8-gnu-toolchain/bin
  • Implemente um programa usando GCC e avr-libc para ligar um led (D13) quando um botão (A0) for pressionado (exemplo)

Notas


28/08/2019 – Usando C++ Serial

Objetivos

  • Entender o periférico Serial e implementar métodos de configuração, envio e recepção.
  • Datasheet ATmega2560

Experimento

  • Implementar comunicação serial 9600bps 8N1


02/09/2019 – Usando C++ ADC

Objetivos

  • Entender o periférico ADC e implementar métodos de configuração e leitura do ADC.
  • Datasheet ATmega2560

Experimento

  • Implementar leitura do ADC

Exercício

  • Implementar o "sensor de temperatura" com C++ e AVR-LIBC
  • Comparar o tamanho do código gerado
  • Entrega: 08/09


04/09/2019 – Interrupção

  • Desafio:
    • Usando Round Robin sem interrupções implementar um sistema com um LED e um botão. O sistema deve piscar o LED (D13) a cada 1 segundos e ao botão (D2) ser pressionado envia uma mensagem pela serial.


09/09/2019 – Classe GPIO

  • Classe GPIO_v1 discutida em sala de aula.
  • Exercício:
    • Implementar classe GPIO com ponteiros para as portas.
    • Verificar tamanho do "set" e da ocupação da memória de dados
    • Comparar com a primeira versão.


#include <avr/io.h>
#include <util/delay.h>
#include "GPIO.h"


//LEDS PLACA (acende com '0')
GPIO led0(0, GPIO::OUTPUT);		//PE0
GPIO led1(1, GPIO::OUTPUT);		//PE1

//LEDS PLACA (acende com '1')
GPIO led13(13, GPIO::OUTPUT);	//PB7

//Adicionar LED
GPIO led4(4, GPIO::OUTPUT);		//PG5
GPIO led6(6, GPIO::OUTPUT);		//PH0

int main(void){

	UCSR0B = 0;

	led0.set(1);
	led1.set(1);
	led6.clear();
	led4.clear();
	led13.clear();
	_delay_ms(1000);
	led0.clear();
	led1.clear();
	led6.set(1);
	led4.set(1);
	led13.set(1);
	_delay_ms(1000);

	while (1){
		led0.toggle();
		led1.toggle();
		led6.toggle();
		led4.toggle();
		led13.toggle();
		_delay_ms(1000);
	}

}

Megapdf.jpg

10/09/2019 – Classe GPIO (cont.)

  • Experimento:
    • Implementar a classe GPIO_v1.3 com o GPIO_Port.
    • Verificar o consumo da memória de dados e programa? Por que o consumo da memória de dados foi 23 bytes?
  • Exercício (fora da sala de aula):
    • Implementar todas as versões compreendendo os conceitos de modelagem (v1.2 e v1.3).
    • Implementar a v2.0 com o construtor indexado (informações abaixo) entendendo o conceito da indexação dos pinos a partir do id.
    • Implementar a v3.0 com todos os pinos do Arduino Mega. Apoio: Mapeamento de Pinos Arduino Mega


  • Modificação GPIO.cpp (uso)
GPIO::GPIO(uint8_t id, PortDirection_t dir)
{
	_bit = GPIO_PORT::id_to_bit[id];
	_port = GPIO_PORT::AllPorts[GPIO_PORT::id_to_port[id]];
	_port->dir(_bit, dir);
}
  • Modificação GPIO_Port.h (dentro do namespace GPIO_PORT)
extern GPIO_Port * AllPorts[4];
extern const uint8_t id_to_port[14];
extern const uint8_t id_to_bit[14];


  • Modificação GPIO_Port.cpp (dentro do namespace GPIO_PORT)
GPIO_Port * AllPorts[4] = {
		reinterpret_cast<GPIO_Port*>(AVR_PB),
		reinterpret_cast<GPIO_Port*>(AVR_PE),
		reinterpret_cast<GPIO_Port*>(AVR_PG),
		reinterpret_cast<GPIO_Port*>(AVR_PH)
};


enum Ports_index {
	PB_i = 0,
	PE_i = 1,
	PG_i = 2,
	PH_i = 3
};

const uint8_t id_to_port[14] = {
	PE_i	,
	PE_i	,
	PE_i	,
	PE_i	,
	PG_i	,
	PE_i	,
	PH_i	,
	PH_i	,
	PH_i	,
	PH_i	,
	PB_i	,
	PB_i	,
	PB_i	,
	PB_i
};

const uint8_t id_to_bit[14] = {
	(1 << (0))  ,
	(1 << (1))  ,
	_BV( 4 )	,
	_BV( 5 )	,
	_BV( 5 )	,
	_BV( 3 )	,
	_BV( 3 )	,
	_BV( 4 )	,
	_BV( 5 )	,
	_BV( 6 )	,
	_BV( 4 )	,
	_BV( 5 )	,
	_BV( 6 )	,
	_BV( 7 )
};

(16/09/2019) – Classe UART Bloqueante

Proposta e implementação da UART Bloqueante

  • Usar a implementação feita em sala de aula e encapsular na classe abaixo.
  • Dúvidas: Ler o capítulo 22 do datasheet (USART). Atenção especial as seguintes seções
    • "Clock Generation"
    • "USART Initialization"
    • "Sending Frames with 5 to 8 Data Bit"
    • "Receiving Frames with 5 to 8 Data Bits"
    • "Register Description"
  • Diagrama de Classe:

UART_bloqueante.png


#include <avr/io.h>
#include <util/delay.h>
#include "UART.h"

UART uart(115200, UART::DATABITS_8, UART::NONE, UART::STOPBIT_1);

int main(){
	uint8_t echo;
	char msg[] = "Byte Received: ";

	while(1){
		echo = uart.get();
		uart.puts(msg);
		uart.put(echo);
		uart.put('\n');
	}

	return 1;
}


(18/09/2019) – Classe UART com interrupção

UART_interrupt.png


Exercício

  • Implementar Fila e adicionar na Classe UART com interrupção.

UART_interrupt_queue.png

(23/09/2018) – Análise do Andamento dos Exercícios

  • Verificação dos alunos com relação as dúvidas
  • Análise das implementações executadas até o momento


(24/09/2018) – Timer e Timeouts

  • Leitura capítulo 16 ("8-bit Timer/Counter0 with PWM").
  • Adaptar e testar a classe timer fornecida para o Atmega2560:
  • Implementar a classe Timeout e e inserir os métodos "TimeoutManager" e "addTimeout" na classe Timer:

timeouts.png

#include <avr/io.h>
#include <avr/interrupt.h>
#include "GPIO.h"
#include "Timer.h"


GPIO p2(2, GPIO::OUTPUT);
GPIO p3(3, GPIO::OUTPUT);
GPIO p4(4, GPIO::OUTPUT);
GPIO p5(5, GPIO::OUTPUT);

void timeout2_handler(void){
	p2.toggle();
}

void timeout3_handler(void){
	p3.toggle();
}

void timeout4_handler(void){
	p4.toggle();
}

void timeout5_handler(void){
	p5.toggle();
}


Timer t = Timer(1000);

int main(){

	sei();
	t.addTimeout(1000, &timeout2_handler);
	t.addTimeout(2000, &timeout3_handler);
	t.addTimeout(3000, &timeout4_handler);
	t.addTimeout(4000, &timeout5_handler);
	while(true){
		t.timeoutManager();
	}
}

(30/09/2018) – Timer e Timeouts (cont.)

  • Finalizar a implementação da classe Timeouts.
  • Desenvolvimento C++
    • 21/08 e 26/08: Botão LED
    • 28/08: Transmissão Serial Bloqueante
  • ISR com a AVR-LIBC
    • 04/09: Desafio e Interrupção Externa
  • Consumo Memória (Dados e Programa), LSS
    • 09/09: GPIO_v1 ("case")
    • 10/09: GPIO_v1.2 (ponteiros DDR, PORT, PIN)
  • Refatoração Classe
    • 10/09: GPIO_v1.3 (GPIO_Port)
  • Indexação do Construtor
    • 16/09: GPIO_v2 (wiki) e GPIO_v3 (todos os pinos do Mega)
  • Modelando Classes:
    • 16/09: Classe UART Bloqueante
    • 18/09: Classe UART com interrupção (tarefa: adicionar FIFO)
    • 24/09: Classe Timer/Timeout


(02/10/2018) – A3

  • Avaliação individual prática em sala de aula.


(07/10/2018) – Correção A3

  • Correção da A3


(09/10/2018) – Interrupção Externa

Classe de Interrupção Externa:

  • A Classe extint funciona para as 8 interrupções externas (INTn). Não confundir com a PCINTn.
  • Ler o capítulo 14 do datasheet (Interrupts).
  • Ler Seção "7.8 Reset and Interrupt Handling"
  • Ler o capítulo 15 do datasheet (External Interrupts). Atenção especial as seguintes seções:
    • "Register Description" (EICRA, EICRB, EIMSK e EIFR)
  • Diagrama de Classe:

ExtInt.png

  • Atividade
    • Fazer proposta de integração com a GPIO
    • Codificar e fazer teste

(14/10/2018) – Interrupção Externa (cont.)

  • Não houve Aula
  • Terminar a Atividade da aula anterior

(16/10/2018) – Atividade A4

  • Temas (sorteado com a turma):
  1. PWM (8-bit TC0): G3 (Anderson, Daniel e Lucas)
  2. SPI (master and slave): G1 (Allex e Douglas)
  3. 2-wire (master and slave): G5 (Guilherme e Marcone)
  4. ADC: G4 (Felipe e Luiza)
  5. 16-bits TCx (Input, Output e Compare Units): G2 (Ameliza e Natália)
  • G1: Allex e Douglas
  • G2: Ameliza e Natalia
  • G3: Anderson, Daniel e Lucas
  • G4: Felipe e Luiza
  • G5: Guilherme e Marcone
  • Cronograma:
    • 23/10: Estudo do periférico, implementação de código de exploração e apresentação para turma.
    • 30/10: Modelagem, táticas de testes e defesa para turma
    • 06/11: Apresentação final

(21/10/2018) – Atividade A4: Apoio

  • Apoio na atividade A4

(23/10/2018) – Atividade A4: Checkpoint

  • Checkpoint:
    • Estudo do periférico, implementação de código de exploração e apresentação para turma.
  • Ordem da Apresentação:
    • G4 – G5 – G1 – G2 – G3

Observações

  • G4: Felipe e Luiza (ADC)
    • Não apresentaram
    • Felipe faltou
    • Luiza poderia ter apresentado algo?
  • G5: Guilherme e Marcone (TWI)
    • Boa a apresentação (Link)
    • O código exploratório foi feito no Arduino, o que impossibilita uma maior intimidade com os registradores de configuração.
  • G1: Allex e Douglas (SPI)
    • Boa a apresentação (Link)
    • O código não está funcional, mas cumpriu os requisitos de “exploração”.
  • G2: Ameliza e Natalia (16-bits TCx – Input, Output e Compare Units)
    • Link Apresentação
    • Boa apresentação. Faltou alguns conceitos como comparador no modo output
    • Não teve código exploratório
  • G3: Anderson, Daniel e Lucas (PWM)
    • Apresentação regular. Um pouco confusa
    • Não teve código exploratório

(28/10/2018) – Atividade A4: Apoio

  • Apoio na atividade A4

(30/10/2018) – Atividade A4: Checkpoint

  • Checkpoint:
    • Modelagem, táticas de testes e defesa para turma
  • Ordem da Apresentação:
    • G5 – G1 – G4 – G2 – G3

Observações

  • G5: Guilherme e Marcone (TWI)
    • Guilherme faltou
    • Implementações exploratórias com memória, muito bom! É o que eu esperava na semana passada.
    • Classe rudimentar
    • Sugestão: Pensar melhor no projeto da classe e reapresentar na segunda para alinhar a implementação. Incluir interrupção.
  • G1: Allex e Douglas (SPI)
    • Link Apresentação
    • Classe na direção correta
    • Retirar lista dinâmica e adicionar array de ponteiros de GPIO passando no construtor
    • Muito bom!
    • Douglas precisa se mostrar mais ativo nas apresentações, mostrando o que fez.
  • G4: Felipe e Luiza (ADC)
    • Apresentarão todas as etapas na segunda-feira (04/11)
    • Luiza poderia ter preparado algo?
  • G2: Ameliza e Natalia (16-bits TCx – Input, Output e Compare Units)
    • Link Apresentação
    • Não foi apresentado a classe
    • Código exploratório está na direção certa. É o que eu esperava na semana passada.
    • Sugestão: Finalizar o código exploratório e já modelar uma versão da classe para discutir na segunda-feira.
  • G3: Anderson, Daniel e Lucas (PWM)
    • Link Apresentação
    • Apresentaram a classe, mas pareceu preparada às pressas.
    • Precisa avaliar melhor a questão do duty_cycle e da freqüência
    • Anderson precisa se mostrar mais ativo nas apresentações, mostrando o que fez.
    • Sugestão: Pensar melhor no projeto da classe e reapresentar na segunda para alinhar a implementação.

(04/11/2018) – Atividade A4: Apoio

  • Apoio na atividade A4

(06/11/2018) – Atividade A4: Checkpoint Final

  • Checkpoint:
    • Apresentação final
  • Ordem da Apresentação:
    • G2 – G4 – G1 – G5 – G3

(11/11/2018) – Atividade A5: Apresentação

  • Interface de comunicação (Wifi, LoRa ou Serial)
    • Upload dos dados
    • Sincronização da hora para data logger (flash spi) rudimentar.
    • Definir protocolo para configuração
  • Display LCD
  • Cronograma:
    • 20/11: Apresentação dos diagramas
    • 04/12: Último dia para dúvidas
    • 09/12: Prazo final para entrega dos códigos/diagramas finais (pelo SIGAA)
    • 11/12: Apresentação/teste do projeto presencial em sala de aula.
  • Diagrama (fornecido pela Natália):

DiagramaInicialProjetoFinal-STEv2.png

(13/11/2018) – Aula liberada para trabalhar na modelagem

(18/11/2018) – Aula de apoio para modelagem

(20/11/2018) – Apresentação da modelagem

  • Ordem de Apresentação:
    • G1 – G3 – G2 – G5 – G4
  • G1: Allex, Douglas
    • Diagrama de Classes

Diagrama ste.png

  • Máquina de estados

Maneger Fsm g1.png

Sincronização Fsm sync g1.png

  • G3: Anderson, Daniel e Lucas
    • Diagrama ste G3.png


(09/12/2018) – Exemplo Interface

#include <avr/interrupt.h>
#include <util/delay.h>

#include "UART.h"

#define __DHT11_

UART uart(9600, UART::EIGHT_DB, UART::NONE_PAR, UART::ONE_SB, UART::DS_DISABLE);

/*
 Classe Abstrata de Sensor de Temperatura 
 */
class SensorTemp
{
public:
    SensorTemp(){}
    virtual void read() = 0;    // "= 0" part makes this method pure virtual, and
                                // also makes this class abstract.
    virtual void config() = 0;
};

class DHT11 : public SensorTemp
{
private:
    int _id;

public:
    DHT11(int id):_id(id){}
    ~DHT11();
    void read();
    void config();
    void outro_metodo_dht11(){}
};

void DHT11::read()
{
    uart.puts("DHT11::read\n");
}

void DHT11::config()
{
    uart.puts("DHT11::config\n");
}


class BMP280 : public SensorTemp
{
private:
    int _id;

public:
    BMP280(int id):_id(id){}
    ~BMP280();
    void read();
    void config();
    void outro_metodo_bmp280(){}
};

void BMP280::read()
{
    uart.puts("BMP280::read\n");
}

void BMP280::config()
{
    uart.puts("BMP280::config\n");
}


int main(void)
{
#ifdef __DHT11_
    DHT11 s(1);
#else
    BMP280 s(2);
#endif
     
   
    SensorTemp *SensorTemp = &s;
    

    sei();
    for(;;){
        SensorTemp->read();
        SensorTemp->config();
        
        _delay_ms(2000);

	}
    
}