Manual Do Kit CanSat Júnior v1.2
Manual Do Kit CanSat Júnior v1.2
Manual Do Kit CanSat Júnior v1.2
v1.2 (2021-08-17)
Índice
Índice 1
Introdução 3
Componentes do Kit 3
Montagem do Kit 5
Paraquedas 6
Dimensionamento do Paraquedas 6
Antena Yagi-Uda 6
PCB “Arduino” 7
PCB Rádio 8
PCB Sensores 8
Programação do CanSat 10
Limitações do Scratch 10
Conselhos 11
Pré-requisitos 11
Procedimentos 14
Exemplos de Programas 16
Estação Base 17
Expressões e Tipos 18
Constantes 19
Aritmética 19
Lógica 20
Comparação 20
Negação 20
Variáveis 21
1
Estruturas de Controlo 21
Se-Faça-Senão (if-then-else) 21
Ciclos 22
Funções e Procedimentos 23
Rádio 26
digitalWrite 27
LED do Arduino 27
Tempo ativo 28
Receptor GPS 29
Glossário 32
2
Introdução
O Kit do CanSat Júnior contém todo o material necessário para construir um micro-satélite, um
paraquedas e uma estação base (fora o computador). Foi desenhado para poder ser usado sem qualquer
experiência prévia em informática e eletrónica, e deixar alunos e professores confortáveis com sensores,
microcontroladores e comunicação por rádio.
Este manual usa terminologia técnica que pode não ser familiar para todos. Aconselha-se a consulta
do Glossário.
Componentes do Kit
Para a construção do paraquedas, são fornecidos:
● 3m de paracord (4mm)
● 1x PCB Arduino
● 1x PCB Rádio (inclui transceiver RFM69HCW já soldado), com cabo terminado em ficha SMA fêmea
(1m)
● 2x Calha 0.5m
● 1x Fita métrica
● 1x PCB “Arduino”
● 1x PCB Rádio (inclui transceiver RFM69HCW já soldado), com antena fio monopolo
● 1x PCB Sensores
○ 1x Buzzer ativo
3
● 1x Conector de pilha 9V com master switch já soldado
● 2x Pilhas 9V
● 1x Placa de topo
● 1x Placa de fundo
● 4x Varões roscados M3
● 50x Porcas M3
● 50x Anilhas M3
● 1x Porca M6
● 2x Anilhas M6
4
Montagem do Kit
O CanSat é constituído pelas placas de Arduino, rádio e sensores, em conjunto com a sua estrutura (varões
roscados e placas de topo/base), paraquedas, e invólucro, que não é fornecido com o kit, mas pode ser uma
lata de coca cola ou outro refrigerante. É importante usar a placa rádio com a antena fio monopolo, não a que
tem um cabo comprido (1 m) com conector SMA.
A estação base é constituída pelas placas de Arduino e rádio. É importante usar a placa rádio com cabo
terminado em conector SMA fêmea (1m), não a que tem um pequeno fio soldado. A placa rádio deverá ser
ligada à antena pelas fichas SMA presentes nas extremidades dos cabos das duas, e a placa Arduino deverá
ser ligada a um computador com recurso a um cabo Micro USB-B para USB-A. Este cabo USB é usado
normalmente para ligar telemóveis ao carregador ou ao computador.
A ligação entre as PCBs “Arduino”, rádio e sensores não tem ordem. Basta alinhar os 3 conectores pretos da
que escolherem ficar em baixo com os 3 conjuntos de pinos metálicos da que escolherem ficar em cima e
juntar.
Sugestão: As placas precisam de alguma força para encaixar/desencaixar. Não as encaixe completamente
antes de testar que ficou tudo corretamente montado.
CUIDADO: A distância entre as várias PCBs será muito reduzida (na ordem de milímetros). Não deixem
que os contactos/soldas de placas diferentes se toquem. Recomenda-se o uso de um material isolante
entre elas para evitar curto-circuitos acidentais.
CUIDADO: Não esmagar o sensor de temperatura da placa de sensores. Podem dobrar com cuidado
os pinos do sensor para mudar a sua orientação, ou escolher ter a placa de sensores em cima
CUIDADO: Não encaixar duas PCBs do mesmo tipo. O circuito não foi desenhado para isso.
CUIDADO: A alimentação do CanSat deve ser feita através do cabo microUSB-USB que ligue o
Arduino a um computador/fonte ou de uma pilha de 9V (garantir que colocação correta do conector da
pilha).
CUIDADO: Alguns cabos microUSB-USB só transportam energia. Estes não funcionarão para
programar o Arduino nem para obter dados do Arduino da estação base. Teste o seu cabo verificando
que, usando-o para ligar o seu telemóvel ou o Arduino ao computador, o computador deteta o dispositivo.
5
Paraquedas
O material fornecido destina-se à criação de um paraquedas flat-shape, que deverá conferir uma velocidade
terminal ao CanSat entre 8 e 11 m/s.
O paraquedas é preso ao parafuso na parte superior do CanSat pelo gancho com destorcedor fornecido no
kit. A este destorcedor devem ser presos fios (de comprimento igual) que o prendem ao tecido do paraquedas
(pelas pontas).
Dimensionamento do Paraquedas
Para o dimensionar, deverá ser analisada a situação de equilíbrio quando o satélite adquire a velocidade
terminal. Aí, a força de atrito e da gravidade anulam-se: 𝐹𝑎𝑡𝑟𝑖𝑡𝑜 = 𝐹𝐺
1 2
𝐹𝑎𝑡𝑟𝑖𝑡𝑜 = 2
* ρ * 𝑘 * 𝐴 *𝑣
𝐹𝐺 = 𝑚 * 𝑔
onde:
ρ - densidade do ar
k - coeficiente de atrito
v - velocidade (terminal)
m - massa do satélite
Antena Yagi-Uda
Uma antena Yagi-Uda é constituída por n elementos perpendiculares a um eixo central. Os vários elementos
têm objetivos diferentes:
● O dipolo transmite o sinal. É constituído por dois condutores (isolados um do outro), ligados ao sinal e
massa (ground) do conector da antena. Existe sempre pelo menos um.
● O refletor, que se coloca atrás do dipolo, age como uma parede que reflete o sinal de volta para o
dipolo (e aumenta a sua intensidade). Está isolado dos restantes elementos.
6
● Os diretores, que se colocam depois do dipolo, funcionam como um funil para o sinal, também
contribuindo para o ganho da antena. Estão também isolados dos restantes elementos.
Os refletores e diretores são também chamados de elementos parasitas por não estarem ligados ao sinal.
A teoria por trás destas antenas permite muitas configurações diferentes. A que recomendamos usar tem 1
refletor, 1 dipolo e vários diretores (pelo menos 1, quantos mais melhor). Para saber as dimensões de cada
elemento e entre elementos recomenda-se o uso de uma calculadora como a disponível em:
https://www.changpuak.ch/electronics/yagi_uda_antenna_DL6WU.php
A antena pode ser construída com a calha, fita métrica, e o cabo com terminação SMA macho fornecidos.
Caso tenham oportunidade, podem fazer os elementos ligeiramente maiores do que o necessário e afinar a
vossa antena com a ajuda de alguém com equipamento especializado.
PCB “Arduino”
1. Caso esteja a montar a PCB Arduino do CanSat, garanta que usa a que tem o bloco de terminais para
ligar os conectores da bateria. Caso esteja a montar a da estação base, garanta que o bloco de
terminais não está presente.
2. Encaixar Arduino Nano Every na PCB “Arduino” orientando-a de modo a que o conector USB Micro-B
fique acessível do exterior.
3. Caso se trate da placa para o CanSat em si, o conector da bateria deverá ser ligado ao bloco de
terminais verdes. O fio vermelho corresponde ao pólo positivo (+), e o preto ao negativo (-). Os pólos
estão indicados à frente do conector em tinta branca.
7
PCB Rádio
O rádio (RFM69HCW) já vem soldado a esta placa.
1. Encaixar level shifter (TXB0104) na placa, alinhando o ponto dourado do componente com o marcado
na PCB.
PCB Sensores
1. Encaixar sensor de pressão (BMP180) na placa, seguindo a orientação da seta.
8
2. Encaixar sensor de temperatura (DS18B20+) na placa, seguindo a orientação da seta. Consideramos
a parte redonda do sensor como a sua frente.
3. Encaixar buzzer no pin header marcado com “BUZZER”. O pino mais curto (-) deverá ir para a ponta
do header marcada com “gnd”, o mais longo (+) pode ser encaixado em qualquer um dos restantes
buracos. Dependendo do modelo do buzzer o pino mais longo (+) poderá ser acompanhado por uma
marca no topo ou na lateral.
9
Programação do CanSat
O CanSat (e a estação base) usam um Arduino como microcontrolador, que é habitualmente programado em
C/C++. Para evitar lidar com a complexidade desta linguagem, recomenda-se a utilização de uma linguagem
baseada em Scratch com editor disponível em https://cj.breda.pt/scratch. Tem 3 “tabs”:
Este editor produz um ficheiro .ino (código C/C++) que pode ser aberto pelo programa “Arduino IDE”, que
programa o Arduino.
Caso nunca tenha programado ou usado uma linguagem Scratch, aconselha-se a leitura do Anexo A:
Introdução a Programação com Scratch.
Aconselha-se a leitura do Anexo B: Entrada/Saída do Kit no Scratch, que funciona como referência para todos
os blocos específicos ao kit, e alguns que consideramos úteis específicos ao Arduino.
Caso já tenha programado um Arduino com C/C++, aconselhamos a não usar o Scratch e aproveitar para
aplicar o seu conhecimento.Teste o seu cabo verificando que, usando-o para ligar o seu telemóvel ou o
Arduino ao computador, o computador deteta o dispositivo.
Limitações do Scratch
O Scratch está desenhado para ser usado com linguagens mais expressivas que C/C++ como Python ou
Javascript, que são mais relaxadas em vários aspetos (como tipos de dados e gestão de memória). Assim, há
algumas operações que não podem ser expressadas neste Scratch:
1. Em C/C++ números inteiros e com casas decimais são representados com tipos diferentes (int e
float). Em Scratch, não há essa distinção. A conversão entre inteiros e números com casas
decimais é implícita, e o arredondamento automático é sempre para baixo (p. ex. 14.9 é arredondado
para 14).
2. As variáveis só guardam inteiros (tipo long int em C) que têm de estar entre -231 e 231-1.
a. Se tentar guardar um valor com casas decimais numa variável ele será implicitamente
convertido para inteiro e arredondado para baixo.
b. Se tentar guardar um valor menor que -231 ou maior que 231-1, o número vai “dar a volta”. -231-1
será guardado como 231-1 e 231 será guardado como -231.
c. Todavia, valores lógicos (verdadeiro ou falso) e níveis de tensão (HIGH e LOW) podem ser
guardados em variáveis sem perda de informação (serão convertidos automaticamente para o
tipo certo).
d. Texto (strings) não pode ser guardado em variáveis.
e. Os argumentos e o valor de retorno de uma função estão sujeitos à mesma restrição.
10
f. O número dado pelo bloco “Tempo ativo” está entre 0 e 232 milissegundos. Isto significa que
após ~24.9 dias de uso, se tentar guardar este valor vai obter um tempo ativo negativo
(começando em -231, e vai subir até 0).
3. O Scratch permite usar o valor de uma variável como valor lógico (por exemplo na estrutura “se-faça”).
Caso tenha sido atribuído um valor numérico ou outro valor não-lógico à variável aplicam-se as
seguintes regras de conversão:
a. números diferentes de 0 são considerados “verdadeiros”;
b. número 0 é “falso”.
4. A comparação de ordem ( <, >, ≤, ≥) só é suportada para expressões numéricas. Outros valores
poderão ser implicitamente convertidos para um número inteiro.
5. O programa dado vai correr em ciclo infinito. Caso o seu programa inclua (termine) num ciclo infinito,
isto é inconsequente (se nunca sai do seu ciclo, nunca vai voltar ao início do seu programa).
Estas limitações não impedem a programação do CanSat (p. ex. não é expectável um CanSat estar 25 dias
ligado), nem obrigam a ter um programa mais complicado do que o necessário.
Conselhos
● Planeie o que quer que o CanSat faça, da forma mais específica possível (“primeiro A, depois B,
depois se C, então D, senão E”) antes de começar a usar o Scratch.
○ Pode ajudar fazer vários planos, cada vez mais específicos, sobre o que se pretende fazer.
○ À medida que ganha experiência, passa a ser só necessário um plano breve sobre o que se
pretende fazer.
● Faça pequenas experiências com o Scratch antes de tentar programar o CanSat inteiro. Corra os
exemplos, faça alterações, veja o que acontece.
● Comente o programa. Os comentários são pequenos bocados de texto que descrevem o que cada
parte do programa está a fazer. São ignorados pelo compilador (e consequentemente pelo Arduino),
por isso podem mesmo ter qualquer coisa.
○ Como sugerido no Anexo A, blocos de texto soltos funcionam bem como comentários.
Pré-requisitos
Para começar deve transferir e instalar a Arduino IDE, disponível em
https://www.arduino.cc/en/Main/Software.
11
Para adicionar suporte ao Arduino que estamos a usar (Arduino Nano Every), deverá abrir o Boards Manager
em Ferramentas > Placa > Boards Manager...
Qualquer engenheiro/programador é preguiçoso, e por isso não vai repetir o trabalho de escrever código para
interagir com um sensor/atuador. Ou usa uma biblioteca já feita, ou escreve a sua e depois usa-a sempre que
precisa. Para programar o CanSat, precisamos das seguintes bibliotecas:
12
Para instalar uma biblioteca, use o Library Manager em Ferramentas > Manage Libraries…
A sua operação é idêntica ao Boards Manager usado anteriormente. Como existem muitas bibliotecas
disponíveis, aconselha-se o uso da caixa de texto no topo da janela para filtrar os resultados:
13
Procedimentos
Será perguntado o nome que quer dar ao ficheiro, e depois ele será transferido para o seu computador.
14
Garanta que Ferramentas > Registers emulation está definido como “None”:
Garanta que o seu Arduino está selecionado em Ferramentas > Porta (a nomenclatura de nomes de porta
apresentada é a de macOS e Linux, em Windows aparece algo como COM1):
A definição de tipo de placa, emulação de registos e porta mostradas no canto inferior esquerdo da Arduino
IDE. O tipo de placa e emulação de registos são relembrados em execuções futuras.
Está agora pronto para fazer upload do programa para o Arduino. Clique na pequena seta redonda:
15
Quando o carregamento do programa terminar, aparecerá uma mensagem semelhante a “Envio completo” no
fundo da janela por cima da zona preta com mensagens do compilador/programador.
A UART funciona como um tubo, despejamos dados de um lado, e eles aparecem no outro pela mesma
ordem que foram enviados.
Garanta que a taxa de transmissão de dados no fundo da janela do monitor está definida para “115200 baud”:
Caso a taxa de transmissão seja diferente do Arduino poderá receber dados errados ou corrompidos.
Exemplos de Programas
Em conjunto com este manual são fornecidos vários ficheiros .xml, que podem ser abertos pelo editor scratch.
O exemplo do buzzer (buzzer.xml) é um pouco mais complexo (já usa uma variável e uma estrutura
se-então-senão): liga/desliga o buzzer a cada segundo, em ciclo infinito.
O exemplo do rádio, envia o tempo que passou desde que o Arduino foi ligado (uptime), reporta quanto tempo
passou durante o envio através da UART USB, e espera 1 segundo, em ciclo infinito.
16
Caso opte por usar C/C++ em vez de Scratch: Estes exemplos continuam a ser relevantes (depois de
exportados para C/C++)! O código gerado é inteligível o suficiente para ser reutilizado. Recomenda-se em
particular usar a classe StreamedRF do exemplo do rádio, de modo a garantir compatibilidade com o código
fornecido para a estação base. Esta classe oferece uma interface idêntica aos objetos Serial (funções write,
print, println e flush) tornando-a um método simples para interagir com o rádio.
Estação Base
O programa do Arduino da estação base e o programa de captura de dados estão disponíveis em
https://github.com/abread/groundstation/releases. Existem 3 ficheiros zip com a aplicação para Windows,
macOS e Linux, e um último ficheiro zip com o código do Arduino.
IMPORTANTE: A versão compilada para macOS não foi testada. Se abre e funciona, não há razão para
deixar de funcionar, mas também não podemos dar garantias de que vai funcionar.
IMPORTANTE: Garanta que o cabo microUSB-USB que usa consegue transmitir dados (um bom teste
é programar o Arduino com ele).
O Arduino da estação base deverá ser programado da mesma maneira que o do CanSat, mas com o
programa fornecido para a estação base. Devem antes de fazer “Upload”, alterar a frequência do rádio
(em Hz) para a desejada (na 2ª linha do ficheiro, que tem por defeito 433000000 Hz).
O rádio e Arduino da estação base são alimentados pelo cabo USB ligado ao Arduino (por isso a PCB não
tem um bloco de terminais para ligar a bateria).
1. Configuração, em que seleciona a porta de série do Arduino (tal como na Arduino IDE) e o ficheiro em
que os dados serão guardados (o nome pré-definido será guardado na pasta em que executam o
programa).
2. Operação, em que são mostrados os dados a chegar e o RSSI atual, que indica a intensidade do sinal
recebido
Os dados são gravados continuamente à medida que são recebidos. Quando a missão termina basta fechar o
programa.
17
Anexo A: Introdução a Programação com Scratch
O computador é uma máquina simples: dada uma lista de instruções (programa), executa-as uma a uma,
sequencialmente. Para conseguir dinamismo, existem estruturas de controlo que podem fazer o computador
saltar para sítios diferentes do programa (em vez de continuar para a instrução seguinte), e variáveis que
permitem guardar valores diferentes ao longo do tempo.
As categorias estão dispostas numa barra cinzenta do lado esquerdo do ecrã. Para ver os blocos disponíveis
numa categoria, clique no nome da mesma. Para usar um bloco, arraste-o para fora da lista de blocos da
categoria para o espaço de trabalho (zona branca com grelha de pontos).
Alguns blocos podem trazer outros agarrados para por conveniência (isto acontece quando um bloco é muito
usado com outro).
As saliências dos blocos indicam onde outros blocos podem ser encaixados: instruções podem ser
encaixadas umas nas outras na vertical, expressões encaixam noutros blocos na horizontal.
Todos os blocos no espaço de trabalho são parte do seu programa e aparecem no código exportado.
O programa é lido como um texto, da esquerda para a direita, de cima para baixo.
Nota: Este anexo foi escrito para ser útil na maioria das implementações do Scratch, e os conceitos
apresentados são relevantes para a maioria das linguagens de programação. Por esta razão, não serão aqui
abordados blocos de Entrada/Saída, que são diferentes para cada tipo de computador.
No Anexo B apresentaremos mais blocos de Entrada/Saída, que dizem respeito a um Arduino em geral, e aos
sensores/rádio do kit.
Expressões e Tipos
Uma expressão é um valor. Constantes, variáveis, aplicação de funções, operações são todas expressões
válidas (“1”, “f(x, 2)”. “2*(1+1)”). Expressões iguais têm o mesmo valor (1+1 e 2 são a mesma coisa).
Quando escrevo 1+1, eventualmente o computador vai ter de avaliar a expressão, isto é, calcular o seu valor
na forma mais simples (constante). Esta avaliação pode ser feita de muitas maneiras: assim que chegamos à
expressão, só quando a tentamos imprimir/usar, pelo compilador antes do programa sequer executar (caso o
18
valor possa ser determinado em tempo de compilação), etc. O que interessa é que a avaliação é sempre feita
a tempo - quando precisamos, o valor foi calculado.
Como nem todos os dados são representados da mesma maneira por um computador e nem todas as
operações fazem sentido (o que é “Olá” * “Adeus”?), todas as expressões têm um tipo.
Porquê falar de expressões? É útil saber que em todos os sítios que podemos dar um bloco com um valor
constante (expressão atómica), também podemos dar um bloco com uma expressão mais complexa, com um
número arbitrário de operações envolvidas.
● Numérico
● Textual (string)
● Lógico - verdadeiro ou falso
Muitas linguagens subdividem o tipo numérico em tipos inteiros (com vários limites de tamanho do número) e
que números com casas decimais (normalmente de vírgula flutuante, com vários limites de precisão).
Constantes
O tipo de expressões mais simples que existe são as constantes.
Exemplos de constantes:
Da esquerda para a direita: o número 42, o texto “A resposta” e o valor lógico verdadeiro.
Dica: O bloco de texto, quando não está ligado a nada, pode ser usado como comentário. Vai aparecer no
código exportado, mas será eliminado pelo compilador (porque não faz nada).
Aritmética
Os operadores aritméticos podem ser aplicados a qualquer par de expressões numéricas, e são uma
expressão numérica. O bloco de aritmética pode somar, subtrair, multiplicar, dividir e exponenciar (^); para
alterar a operação do bloco, clique na operação atual (que tem uma pequena seta ao lado a indicar que é um
menu).
Exemplo: 2 * (1 + 3)
equivalente ao número 8
19
Lógica
Temos dois três blocos diferentes a representar expressões lógicas: comparação, operadores lógicos binários
e negação.
Comparação
Um operador lógico de comparação compara dois valores e representa um valor lógico.
Se a linguagem subjacente converter tipos automaticamente, essa conversão será feita antes da comparação,
caso contrário valores de tipos diferentes ou não são comparáveis, ou são sempre diferentes.
Exemplo:
1+3=4, 2x2=4,
4 não é diferente de 4,
4 ≠ 4 é falso,
logo (1 + 3) ≠ (2 * 2) é falso,
logo a expressão ((1 + 3) ≠ (2 * 2)) = 𝑓𝑎𝑙𝑠𝑜 é verdadeira.
Este foi um exemplo mais complexo que pretendeu demonstrar a infinidade de operações possíveis com
expressões.
Permitem expressar a conjunção (“e”) e a disjunção (“ou”). São binários apenas porque aceitam dois
operandos.
Por exemplo, se eu disser “Gosto de carne e peixe”, mas só gostar de carne, estou a mentir; mas se disser
“Gosto de carne ou peixe” estou tecnicamente a dizer a verdade (embora de uma forma estranha).
Exemplo:
Esta expressão é
verdadeira.
falso ou 1=1 (que é verdadeiro) é verdadeiro,
logo (falso ou 1=1), que é verdadeiro, e verdadeiro é verdadeiro.
Negação
20
Outros tipos de expressões
São abordados nas secções seguintes, mas podemos saber desde já que variáveis e aplicação de funções
(“usar” uma função) também são expressões.
Curiosidade: Há linguagens de programação em que tudo (ou quase tudo) são expressões.
Variáveis
O computador tem memória que lhe permite guardar valores. Na verdade, tem vários tipos de memória, numa
hierarquia organizada pela velocidade de acesso (e quando o valor que quer aceder não está presente na 1ª,
tenta a seguinte que é mais lenta). Damos destaque à memória RAM, que é guarda todos os dados do
programa em execução (incluindo uma cópia do próprio programa, dependendo da arquitetura do
computador).
Podemos pensar nas variáveis como baldes com etiqueta (nome) que guardam um valor a dado momento.
Posso a qualquer momento ver o que está dentro do balde procurando-o pela nome na etiqueta, e posso
também substituir o conteúdo do balde (usando mais uma vez o nome).
Em Scratch, as variáveis são declaradas implicitamente, isto é, são criados automaticamente pelo Scratch à
medida que pedimos variáveis diferentes.
Embora as expressões abordadas na secção anterior sejam capazes de representar muitas computações,
não trazem nada de interessante ao programa sem variáveis. Aliás, como optimização, o compilador
pré-calcula expressões que só envolvem constantes e o programa compilado apenas contém o resultado. Isto
significa também que podem ter cálculos no vosso programa para não ter números “caídos do céu”, sem
ocupar mais espaço por isso.
Estruturas de Controlo
Se-Faça-Senão (if-then-else)
A estrutura se-faça-senão permite executar partes do programa condicionalmente.
21
Para executar outra ação quando a condição é falsa, podemos estender este bloco com o bocado “senão”.
Para isso clique na roda dentada azul à esquerda de “se” e arraste o bloco senão para o mini-bloco “se”.
Pode ainda acrescentar os bocados “senão-se” antes do “senão” final. Os blocos correspondentes à primeira
condição verdadeira serão executados (e mesmo que outras seguintes sejam verdadeiras, serão ignoradas).
Caso nenhuma seja verdadeira, os blocos associados ao bocado “senão” é executado.
Ciclos
Os ciclos permitem executar os mesmos blocos repetidamente.
Alternativamente, pode trocar o ciclo para um “repita até”, que executa os blocos associados em ciclo até que
a condição seja verdadeira, isto é, enquanto ela for falsa.
22
Ciclos “contar com” (for)
Um ciclo “contar com” é usado para repetir uma ação até uma variável contador atingir determinado valor.
Pode ser especificado também o valor inicial da variável e quanto é que é somado a ela após cada iteração
(incremento).
Podem ser usados em qualquer tipo de ciclo, e apenas dentro de um ciclo. O aviso (triângulo azul) indica
quando são usados fora de um ciclo - um erro.
Caso tenha vários ciclos uns dentro dos outros, este bloco atua sobre o ciclo interior:
No exemplo anterior, o bloco “sair do ciclo” atua sobre o ciclo “contar com”, não sobre o “repita 10 vezes”.
Funções e Procedimentos
A arte da programação passa por evitar repetição, por isso um bom programador não escreve o mesmo
código mais do que uma vez: agrupa-o numa função/procedimento e depois usa essa função/procedimento.
A diferença entre uma função e um procedimento, é que um procedimento apenas executa ações, e uma
função retorna um valor.
23
Como caso de estudo, vamos implementar a função “duplica ou triplica”, que aceita um número “x”, duplica-o
se for ímpar, triplica-o caso contrário.
Depois, vamos adicionar o parâmetro/entrada “x”, arrastando o bloco “nome de entrada” para dentro do
mini-bloco “entradas”. O nome do parâmetro pode ser mudado.
Temos um problema: como é que podemos retornar o dobro de x quando é ímpar? Não há nenhum bloco
“retorna” isolado! Podíamos calcular o resultado no corpo da função, guardá-lo numa variável e retornar o
valor dessa variável, mas vamos optar por usar o bloco especial “se-retorna”:
Note que o bloco “é ímpar” não existe no Scratch! É uma função criada previamente (a definição não é
apresentada aqui) que retorna verdadeiro se o número y fornecido é ímpar, falso caso contrário. Para cada
função definida, o Scratch mostra automaticamente o bloco para a chamar na secção “Funções”.
Note também que dentro da função “é ímpar” o parâmetro chama-se y, não x.
24
Quando uma função é executada, os valores passados aos seus argumentos são atribuídos aos nomes
usados internamente pela função. As variáveis correspondentes aos argumentos de uma função (no caso de
duplica ou triplica, a variável x) são temporárias: só existem durante a execução da função.
Por último, note que o bloco “se-retorna” não permite adicionar cláusulas “senão-se” ou “senão”. Não são
necessárias, porque quando uma função retorna um valor, volta para o sítio onde foi chamada. Ter vários
blocos “se-retorna” seguidos e o “retorna” final é equivalente a um bloco “se” com uma série de cláusulas
“senão se” e uma cláusula “senão” final.
Nota: Há uma distinção subtil entre parâmetro e argumento. Um parâmetro de uma função é aquilo que a
função aceita (o buraco onde temos de encaixar um valor), o argumento é o valor/expressão que efetivamente
lhe damos.
Curiosidade: Na maioria das linguagens de programação atuais todos os procedimentos são funções que
retornam um tipo “vazio” (void em C).
Um computador que não é capaz de atuar sobre o mundo real (seja mostrando informação, seja mexendo um
braço robótico) é um aquecedor caro. E um computador que não consegue percecionar o que se passa no
exterior, mas que atua sobre ele, é um temporizador de rega caro.
Para que os recursos do computador não sejam desperdiçados, tem mecanismos de entrada e saída de
informação. No caso do Arduino destacamos os seguintes:
Também suporta nativamente os protocolos de comunicação I2C e SPI, e o esquema de saída PWM, que não
serão aqui abordados diretamente.
Os sensores e rádio incluídos no kit usam estes protocolos de comunicação, mas estes pormenores de uso
foram abstraídos, tanto pelas bibliotecas usadas no código, como pelos blocos do Scratch.
25
Nota: Quando escrevemos numa UART do Arduino, ele não espera que todos os dados sejam transmitidos
antes de continuar o programa. Copia os dados para um buffer e um circuito independente do processador
trata da transmissão. Só espera por transmissão se o buffer não tiver espaço suficiente para todos os dados.
Isto significa que escrever no ecrã não demora quase tempo nenhum no nosso programa, fora casos em que
se escreva demais.
Olá mundo!
Olá.
Rádio
Para definir a frequência base de operação do rádio, existe o bloco “Rádio: definir frequência”. Use a
frequência atribuída à sua equipa (consulte o Anexo C)!
AVISO: Nem todas as frequências suportadas pelo rádio podem ser usadas, por questões legais. Consulte a
legislação local para saber que partes do espectro são de uso livre sem licença (frequências na faixa 430-435
MHz são de uso livre sem licença em Portugal à data de escrita, sujeitas a restrições de potência máxima de
transmissão).
Para enviar informação para a estação base (escrever no rádio), temos blocos muito semelhantes aos
“Escreve no ecrã”.
Olá mundo!
Olá.
Os blocos “Rádio: escreve” aceitam também qualquer expressão, e convertem o seu valor para texto antes de
enviar.
O rádio faz buffering, isto é, agrupa os dados em blocos (de 61 caracteres) antes de começar a tentar enviar
por questões de eficiência.
Cada vez que enviamos dados, é calculado e enviado um código de deteção de erros. Se em vez de enviar
10 caracteres no mesmo bloco enviarmos um de cada vez, acabamos por ter enviar o triplo dos dados (por
26
causa do código de deteção de erros, entre outros), o que corresponde a gastar ~3x mais tempo e ~3x mais
energia.
O rádio não tem maneira de distinguir entre dados “presos” no buffer à espera que chegue o ciclo seguinte e
comecemos a escrever novamente (como na frase “Olá.”) e dados que simplesmente vão ser escritos com
várias instruções (como na frase “Olá mundo!). Para evitar a situação de dados presos, temos o bloco “Rádio:
forçar envio”, que obriga o rádio a enviar os dados que tem à espera, mesmo que não sejam do tamanho de
um bloco inteiro. Caso não existam dados pendentes, o bloco “Forçar envio” não tem efeito.
É possível que a transmissão de dados falhe, pelo que se recomenda escolher um formato de envio de dados
resiliente a perdas. A perda de um bloco de 60 caracteres não deve tornar a informação irrecuperável.
Sugestão: usar apenas 59 caracteres para dados, e começar e terminar pacote com mudança de linha ou
outro carácter separador, e forçar o envio antes e depois da escrita do pacote. Caso exista muita informação
para transmitir, separá-la em vários pacotes de tipos diferentes que serão processados de forma
independente em terra
Nota: Ao contrário do que acontece com o “Escrever no ecrã”/UART, escrever no rádio vai parar o programa
até que os dados sejam todos enviados quando o buffer encher/chamarem “forçar envio”. Não há circuito
independente no Arduino para copiar dados para o rádio.
digitalWrite
Para ligar/desligar um pino digital, usamos o bloco digitalWrite(). O estado HIGH representa ligado, LOW
representa desligado.
Por exemplo, para fazer barulho com um buzzer ligado ao pino 1 durante 1 segundo:
Curiosidade: Este bloco chama-se digitalWrite porque é esse o nome da função em C/C++ para fazer esta
operação.
LED do Arduino
O Arduino tem um LED embutido que pode ser controlado pelo programa. Controlar o LED significa controlar
o pino que lhe dá energia. No caso do Scratch, não está na lista de pinos do bloco digitalWrite, mas temos um
bloco que o deixar desligar e ligar:
27
Tempo ativo
Um computador tem tipicamente um relógio sempre ligado (quando o computador está desligado é
alimentado ou pela bateria, caso exista, ou por uma pilha dedicada ao relógio), para quando o voltarem a ligar
ele saber a hora atual. O Arduino não tem um relógio assim, mas consegue saber quanto tempo passou
desde que foi ligado. O bloco “Tempo ativo” dá-nos o quantos milissegundos passaram desde que o Arduino
foi ligado (volta a 0 a cada 232 milissegundos).
Está na categoria “Controlo” porque no caso do Arduino não é tecnicamente um dispositivo de entrada/saída,
mas um contador no programa (a cada 1ms a execução é interrompida para aumentar o contador).
Curiosidade: Isto existe porque um processador funciona à base de um relógio. Cada vez que o relógio
avança (e o tempo entre cada avanço é na ordem dos 10-6s para o arduino e 10-9s para o computador), o
processador executa mais uma instrução. O tempo ativo funciona contando quantos ciclos de relógio
passaram e multiplicando pela duração de um ciclo.
A medição de temperatura decorre de forma assíncrona, isto é, o Arduino pode fazer outras tarefas enquanto
o sensor faz o seu trabalho. O tempo que o sensor demora a fazer a medição varia consoante a resolução
configurada. A resolução pode ser alterada com o bloco “DS18B20: Definir resolução para __ bits”, e é por
omissão definida para 9 bits (valor mais baixo). Consulte a data sheet do sensor para mais informação.
Quando quiser aceder aos resultados da última medição, o bloco “Obter temperatura” irá bloquear (esperar)
até que a última medição pedida acabe, caso ainda não tenha passado tempo suficiente, e retornar a última
temperatura observada pelo sensor pedido:
Caso tenha apenas um sensor, este será identificado pelo número 0 (zero), como mostrado na figura acima.
Para configurações com múltiplos sensores, serão todos detectados automaticamente e a ordem de deteção
é determinística (a ordem relativa entre números atribuídos aos sensores não muda).
É recomendado pedir a medição de temperatura no início do ciclo, e usar os dados apenas no fim do mesmo
para minimizar o tempo de espera.
28
Curiosidade: Este bloco abstrai toda a comunicação necessária para pedir uma leitura ao sensor e obtê-la.
Concretamente, abstrai a implementação do protocolo OneWire da Maxim (fabricante do DS18B20), e a sua
utilização para ler o sensor (que fala este protocolo).
Curiosidade: Este bloco abstrai toda a comunicação necessária para pedir uma leitura ao sensor e obtê-la.
Concretamente, abstrai o uso do protocolo I2C (já implementado no Arduino) para pedir leituras de
temperatura e pressão ao sensor. A leitura de temperatura é usada pelo sensor para compensar a variação
de pressão com a temperatura.
Receptor GPS
Para bom funcionamento do receptor GPS, o primeiro bloco presente no programa tem de ser o “GPS:
Processar dados pendentes”:
O receptor GPS funciona de forma independente do Arduino: comunica com vários satélites para determinar
latitude, longitude, altitude, direção, velocidade, etc. e reporta esta informação ao Arduino 1 vez por segundo.
O bloco “processar dados pendentes”, lê estes relatórios do GPS e interpreta-os, disponibilizando a
informação através dos blocos que se seguem:
29
Latitude e longitude expressas em graus.
Idade da posição corresponde a quantos milissegundos passaram
desde a última informação de latitude/longitude válida recebida do
GPS.
O bloco “Pause durante ___ ms” processa dados pendentes do GPS antes de pausar o Arduino quando o
GPS está em uso. Por esta razão, a pausa pode ser superior ao tempo pedido.
30
Anexo C: Alocação de Frequências a Equipas
Nome da equipa Escola Frequência (MHz)
31
Glossário
Arduino Microcontrolador desenhado para ser de baixo custo e de fácil uso/aprendizagem.
Atrito Força que se opõe ao movimento. É a força que nos trava quando paramos
subitamente de correr, impedindo-nos de deslizar infinitamente.
Level shifter Circuito que faz tradução entre dois níveis de lógica (p. ex. 5V e 3.3V).
Pin header Fichas onde pinos podem ser inseridos para contacto elétrico e encaixe.
ou barra de pinos
SMA (ficha) Conector/Ficha para cabos coaxiais, de uso comum em antenas WiFi.
32
UART Do inglês: Universal Asynchronous Receiver-Transmitter
Hardware com formato de transmissão e velocidade de transmissão configuráveis.
33