Commit 5ce38a43 authored by Poseidon's avatar Poseidon

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()
This diff is collapsed.
#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
#include"binaryCommunication.h"
/*
ReadAnalogVoltage
Reads an analog input on pin 0, converts it to voltage, and prints the result to the serial monitor.
Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.
This example code is in the public domain.
*/
struct Data{
short int x1;
short int x2;
float x3;
}data;
// BinCommunication comm = new BinCommunication();
BinCommunication comm(&data, sizeof(data));
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
comm.begin(9600);
data.x1 = 0;
data.x2 = 0;
data.x3 = 0;
byte b = 10;
Serial.write(b);
Serial.write(0);
}
// the loop routine runs over and over again forever:
void loop() {
data.x1 ++;
data.x2 += 2;
data.x3 += 0.1;
comm.send();
delay(100);
}
......@@ -36,14 +36,4 @@ class Interface{
};
// * Classe para gerenciar o cartão SD e os arquivos nele
// class SDmanager: public SD{
// private: