Commit 5ce38a43 authored by Poseidon's avatar Poseidon
Browse files

Criando branch para testes

parent e06ef809
.build
sources/python/
PYBIN := python3
VENVDIR := $(shell pwd)/.venv
VENVPY := ${VENVDIR}/bin/python
BUILDDIR := .build
.PHONY: help setup firmware serial run
all: help
help:
@ echo "USAGE: make <target> where <target> can be:"
@ echo ""
@ echo " setup Execute once to prepare the required Python virtual environment"
@ echo " firmware Compile and upload the firmware to the Arduino board via serial"
@ echo " serial Starts a serial session with Python for board communication"
@ echo ""
@ echo " run Execute the logger on the foreground. Hit Ctrl+C to stop it."
install-debian-deps:
sudo apt-get install -y python3 supervisor curl dialog
install-pip3:
wget https://bootstrap.pypa.io/get-pip.py
sudo python3 get-pip.py
rm get-pip.py
install-python-deps: install-pip3
sudo pip3 install -U virtualenv
install-platformio:
sudo python -c "$$(curl -fsSL https://raw.githubusercontent.com/platformio/platformio/master/scripts/get-platformio.py)"
setup: install-debian-deps install-python-deps install-platformio venv
venv: clean-venv
@ echo "-------------------------------------------------------"
virtualenv -v --python='${PYBIN}' ${VENVDIR} --no-site-packages
${VENVDIR}/bin/pip install -r logger/requirements.pip
@ echo "-------------------------------------------------------"
@ echo "Required Python virtual environment sucessfully installed at "
@ du -sh ${VENVDIR}
clean-venv:
rm -rf ${VENVDIR}
check-venv:
@ command -v ${VENVPY} >/dev/null 2>&1 || \
{ printf "You need to prepare the required Python virtual environment";\
printf "\nfor running this software. Excecute, just once:";\
printf "\n\n $$ make setup\n\nor\n\n ";\
printf "$$ make setup PYBIN=<python_binary>\n\nfor specifying a ";\
printf "Python binary other than 'python3', like\n'python-3.x' ";\
printf "(where x is a number) for instance. \n\n"; exit 1; }
firmware:
python3 scripts/run_platformio.py
serial: check-venv
${VENVPY} scripts/init_serial.py --loop
pyserial: check-venv
${VENVPY} -i scripts/init_serial.py
syncrtc:
${VENVPY} scripts/init_serial.py --syncrtc
boardhash:
${VENVPY} scripts/getboardhash.py
run: check-venv
${VENVPY} logger/run.py
#include "binaryCommunication.h"
BinCommunication::BinCommunication(void *dataPtr, int dataLen){
this->dataPtr = (uint8_t*) dataPtr;
this->dataLen = dataLen;
}
void BinCommunication::begin(long int baudRate){
Serial.begin(baudRate);
}
bool BinCommunication::send(){
Serial.write(this->dataLen);
if(Serial.write(this->dataPtr, this->dataLen) == this->dataLen)
return true;
return false;
}
int BinCommunication::getDataLen(){
return this->dataLen;
}
void BinCommunication::setDataLen(int dataLen){
this->dataLen = dataLen;
}
void* BinCommunication::getDataPointer(){
return (void*)this->dataPtr;
}
void BinCommunication::setDataPointer(void* dataPtr){
this->dataPtr = (uint8_t*) dataPtr;
}
#ifndef BINARYCOMMUNICATION
#define BINARYCOMMUNICATION
#if (ARDUINO >= 100)
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
/*
Cria uma comunicação Serial enviando bytes 'crus' para obter melhor
desempenho.
Logo é necessário que onde os dados são recebidos que sejam decodificados,
já que não estão com caracteres ASCII
Protocolo para utilização:
É enviado um byte inicial, indicando quantos bytes vão ser enviados.
Esse byte é um unsigned int_8b logo é possível endereçar somente 255 bytes.
X.A.B.C.D
|-------| : Lenght = X
Melhor forma de usar é criar uma estrutura de dados
Ex.:
struct data{
int x1;
int x2;
...
char str[10];
..
float xn;
};
// Criando objeto para comunicação
comm = BinCommunication((void*)&data, sizeof(data));
// Nesse momento você alterar a sua estrutura e cada vez que usar o metodo
// send() será enviado todos os dados para o computador
comm.send();
*/
class BinCommunication{
private:
/* Tamanho em bytes da banda de dados*/
int dataLen;
/* Ponteiro do array de dados*/
uint8_t *dataPtr;
public:
/* Inicializando as variáveis necessárias*/
BinCommunication(void *dataPtr, int dataLen);
/* Incializando comunicação Serial do Arduino*/
void begin(long int baudRate);
/* Envia os dados que estão no array de dados*/
bool send();
/* */
int getDataLen();
void setDataLen(int dataLen);
void* getDataPointer();
void setDataPointer(void* dataPtr);
};
#endif
/*
**********************************************************
* RESPIRÔMETRO - CTA *
**********************************************************
AUTOR: Béuren F. Bechlin
+-------------------------------------------+
| Centro de Tecnologia Acadêmica - UFRGS |
| http://cta.if.ufrgs.br |
+-------------------------------------------+
Este arquivo fonte faz parte do Respirômetro e está
sobre a licença GPL v3, como também os arquivos:
* binaryCommunication(.h/.cpp): usado para criar uma
comunicação com dados binários entre o arduino e
o computador e não com CHARS como é o default.
* utils(.h/.cpp): usado para criar rotinas que devem
ser executadas com uma frequência fixa, funciona-
mento análogo com o delay() disponibilizado pela
plataforma, entretanto não para o processamento
e sim utiliza metodo de polling para verificar
se deve executar algo.
ENTRADAS ANALÓGICAS:
A0 :: RESPIRÔMETRO PRIMEIRA ENTRADA
A1 :: RESPIRÔMETRO SEGUNDA ENTRADA
A2 :: ELETROCARDIOGRAMA
*/
#include "binaryCommunication.h"
#include "utils.h"
/* Definindo a frequencia de operação do equipamento*/
#define FREQUENCY 250 // Hz
/* Criando estruturas de dados para definir como será enviado os
dados de comunicação*/
struct{
short int controlFlag = 0xAAAA;
short int frequency = FREQUENCY;;
}headerStruct;
struct{
short int reads[1];
}dataStruct;
/* Criando comunicação*/
BinCommunication commHeader(&headerStruct, sizeof(headerStruct));
BinCommunication commData(&dataStruct, sizeof(dataStruct));
/* Criando interface que se repetirá a cada '1.0/FREQUENCY'. Essa
interface irá chamar a função 'measures' a cada repetição*/
Interface interface(&measures, 1000.0/FREQUENCY);
void setup(){
/* Iniciando comunicação serial*/
Serial.begin(115200);
while(!Serial){
}
delay(50);
commHeader.send();
delay(50);
}
void loop(){
interface.run();
}
void measures(){
for(int i = 0; i < 1; i++)
dataStruct.reads[i] = analogRead(i);
/* Enviando dados*/
commData.send();
}
#include "utils.h"
Polling::Polling(){
this->period = 0;
}
Polling::Polling(int period){
this->period = period;
}
bool Polling::test(){
if(millis() - this->time_last >= this->period)
return true;
else
return false;
}
void Polling::executed(){
this->time_last = millis();
}
void Polling::setPeriod(int period){
this->period = period;
}
int Polling::getPeriod(){
return this->period;
}
Interface::Interface(void (*callback)(void), int period){
this->callback = callback;
this->state = true;
this->_interval.setPeriod(period);
this->_interval.executed();
}
bool Interface::running(){
return this->state;
}
void Interface::setState(){
this->state = !this->state;
}
void Interface::run(){
if(this->state == true){
if(this->_interval.test()){
this->callback();
this->_interval.executed();
}
}
}
void Interface::setPeriod(int period){
this->_interval.setPeriod(period);
}
int Interface::getPeriod(){
return this->_interval.getPeriod();
}
#ifndef UTILS
#define UTILS
#if (ARDUINO >= 100)
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
class Polling{
private:
unsigned long time_last;
int period;
public:
Polling();
Polling(int);
bool test();
void executed();
void setPeriod(int);
int getPeriod();
};
class Interface{
private:
bool state;
void (*callback)(void);
Polling _interval;
public:
Interface(void (*)(), int);
bool running();
void setState();
void setPeriod(int period);
void run();
int getPeriod();
};
#endif
#include "binaryCommunication.h"
BinCommunication::BinCommunication(void *dataPtr, int dataLen){
this->dataPtr = (char*)dataPtr;
this->dataLen = dataLen;
}
void BinCommunication::begin(long int baudRate){
Serial.begin(baudRate);
}
bool BinCommunication::send(){
Serial.write(this->dataLen);
if(Serial.write(this->dataPtr, this->dataLen) == this->dataLen)
return true;
return false;
}
int BinCommunication::getDataLen(){
return this->dataLen;
}
void BinCommunication::setDataLen(int dataLen){
this->dataLen = dataLen;
}
void* BinCommunication::getDataPtr(){
return this->dataLen;
}
void BinCommunication::setDataPtr(void* dataPtr){
this->dataPtr = (char*) dataPtr;
}
#ifndef BINARYCOMMUNICATION
#define BINARYCOMMUNICATION
#if (ARDUINO >= 100)
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
/*
Cria uma comunicação Serial enviando bytes 'crus' para obter melhor
desempenho.
Logo é necessário que onde os dados são recebidos que sejam decodificados,
já que não estão com caracteres ASCII
Protocolo para utilização:
É enviado um byte inicial, indicando quantos bytes vão ser enviados.
Esse byte é um unsigned int_8b logo é possível endereçar somente 255 bytes.
X.A.B.C.D
|-------| : Lenght = X
Melhor forma de usar é criar uma estrutura de dados
Ex.:
struct data{
int x1;
int x2;
...
char str[10];
..
float xn;
};
// Criando objeto para comunicação
comm = BinCommunication((void*)&data, sizeof(data));
// Nesse momento você alterar a sua estrutura e cada vez que usar o metodo
// send() será enviado todos os dados para o computador
comm.send();
*/
class BinCommunication{
private:
/* Tamanho em bytes da banda de dados*/
int dataLen;
/* Ponteiro do array de dados*/
char *dataPtr;
public:
/* Inicializando as variáveis necessárias*/
BinCommunication(void *dataPtr, int dataLen);
/* Incializando comunicação Serial do Arduino*/
void begin(long int baudRate);
/* Envia os dados que estão no array de dados*/
bool send();
/* */
int getDataLen();
void setDataLen(int dataLen);
int getDataPointer();
void setDataPointer(void *dataPtr);
}
#endif
# http://ascii-table.com/ansi-escape-sequences.php
def printAt(x, y, Str):
'''
Using ANSI escape sequence,
where ESC[y;xH moves curser to row y, col x:
'''
print("\033[{};{}H{}".format(x, y, Str))
def progressBar(percent, lenght):
'''
Cursor necessita estar na linha onde esta a barra de progresso.
DOC dos ANSII caracters:
http://ascii-table.com/ansi-escape-sequences.php
'''
highlight = " "*int((lenght-2)*percent/100)
notHighlight = " "*(lenght-2- len(highlight))
print("\033[{}D\t|\033[1;42m{}\033[0;0m{}| {}%".format(lenght+5, highlight,notHighlight, percent), end="")
if __name__ == '__main__':
#printAt(0, 0,"Hello Word")
start = "\033[1;31m"
end = "\033[0;0m"
progressBar(50, 25)
# print("\033[10B\033[10DFile is: " + start + "<placeholder>" + end)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Estação biométrica CTA
Programa para aquisição dos dados
Este programa é utilizado com o programa biometrica.ino no qual a taxa de amostragem é definida no microcontrolador
Protocolo usado está disponível no biométrica.ino
Centro de Tecnologia Acadêmica - UFRGS
http://cta.if.ufrgs.br
Licença: GPL v3
Ordem de argumentos : [porta],[taxa_transmissão],[arquivo_saída]
Onde:
[porta]: porta serial no qual o arduino está conectado
[taxa_transmissão]: velocidade de comunicação serial
[arquivo_saída]: nome do arquivo em que os dados serão salvos
[tempo_de_execução]: tempo total de execução, em segundos
PADRÃO NOME DO ARQUIVO DE SAÍDA: coleta_[Nome]_[Sobrenome]_[obs].log
[obs] são observações caso sejam necessárias
'''
STRUCT_DATA = 'hhf'
STRUCT_HEADER = 'h'
# Exemplo: python armazenamento_new.py /dev/ttyACM0 115200 coleta_Nome_Exemplo_1min.log 30
import sys, serial, datetime, os, time, struct
def validateInput():
argumento = sys.argv[1:] #renomeando os argumentos
baudRate = [300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 115200]
# Erros
if len(sys.argv) < 5:
sys.stderr.write('ERRO: Argumentos insuficientes.\nEm caso de dúvidas leia o READ_ME.md.\n' )
sys.exit(1)
if not os.path.exists(argumento[0]):
sys.stderr.write('ERRO: Arduino não está conectado na porta '+argumento[0]+'!\nEm caso de dúvidas leia o READ_ME.md.\n')
sys.exit(1)
if not os.access(argumento[0], os.R_OK):
sys.stderr.write('ERRO: A porta '+argumento[0]+' não pode ser lida por problemas de permissão!\nEm caso de dúvidas leia o READ_ME.md.\n')
sys.exit(1)
if not int(argumento[1]) in baudRate:
sys.stderr.write('ERRO: A taxa de transmissão '+argumento[1]+' não pode ser usada pelo microcontrolador!\nEm caso de dúvidas leia o READ_ME.md.\n')
sys.exit(1)
return {'SerialPort':argumento[0], 'BaudRate':int(argumento[1]), 'FileName':argumento[2], 'ExecTime':int(argumento[3])}
def initSerial(port, baud):
# Iniciando comunicação serial
ser = serial.Serial(port, baud)
# Limpando buffer para retirar as medidas feitas antes de iniciar o software
ser.setDTR(False) # Desliga DTR
time.sleep(0.05)
ser.flushInput() # Limpa buffer de dados
ser.setDTR(True) # Liga DTR novamente
return ser
def main():
args = validateInput()
serial = initSerial(args['SerialPort'], args['BaudRate'])
freq = int(struct.unpack('h', serial.read(2))[0])
scriptTime = int(freq*args['ExecTime'])
timeCounter = 0
while (timeCounter <= scriptTime or scriptTime == 0):
timeCounter += 1
try:
dataLen = int(struct.unpack('B',serial.read(1))[0])
rawData = serial.read(dataLen)
data = struct.unpack(STRUCT_DATA, rawData)
# Arquivo de log
dataFile = open(args['FileName'],'a')
dataFileBin = open(args['FileName']+'bin','ab')
dataFile.write(str(data[0])+"\t"+str(data[1])+"\t"+str(data[2])+"\n")
dataFileBin.write(rawData)
dataFile.close()
dataFileBin.close()
except KeyboardInterrupt:
break
serial.close()
if __name__== '__main__':
main()
1 2 0.10000000149011612
2 4 0.20000000298023224
3 6 0.30000001192092896
4 8 0.4000000059604645
5 10 0.5
6 12 0.6000000238418579
7 14 0.7000000476837158
8 16 0.8000000715255737
9 18 0.9000000953674316
10 20 1.0000001192092896
11 22 1.1000001430511475
12 24 1.2000001668930054
13 26 1.3000001907348633
14 28 1.4000002145767212
15 30 1.500000238418579
16 32 1.600000262260437
17 34 1.700000286102295
18 36 1.8000003099441528
19 38 1.9000003337860107
20 40 2.000000238418579
21 42 2.1000001430511475
22 44 2.200000047683716
23 46 2.299999952316284
24 48 2.3999998569488525
25 50 2.499999761581421
26 52 2.5999996662139893
27 54 2.6999995708465576
28 56 2.799999475479126
29 58 2.8999993801116943
30 60 2.9999992847442627
31 62 3.099999189376831
32 64 3.1999990940093994
33 66 3.2999989986419678
34 68 3.399998903274536
35 70 3.4999988079071045
36 72 3.599998712539673
37 74 3.699998617172241
38 76 3.7999985218048096