Arduinoscope para os mais íntimos, com função de análise lógica. Mas o que é um osciloscópio? :B
Tio wikipédia responde:
O osciloscópio é um instrumento de medida eletrônico que cria um gráfico bi-dimensional visível de uma ou mais diferenças de potencial. O eixo horizontal do ecrã (monitor) normalmente representa o tempo, tornando o instrumento útil para mostrar sinais periódicos. O eixo vertical comumente mostra a tensão. O monitor é constituído por um “ponto” que periodicamente “varre” a tela da esquerda para a direita.
E Processing?
Processing é uma linguagem de programação de código aberto e ambiente de desenvolvimento integrado (IDE), construído para as artes eletrônicas e comunidades de design visual com o objetivo de ensinar noções básicas de programação de computador em um contexto visual e para servir como base para cadernos eletrônicos.
Para essa breve explicação usarei OS linux 32bits
Para outros OS, seus respectivos downloads podem ser encontrados aqui: downloads
Requisitos:
- Processing interpreter
- Libs para processing
- controlP5
- arduinoscope
- processing.serial
Que podem ser todas encontradas aqui: download
- Para usuarios linux, é necessarios a libs gcc-avr e avr-libc
Como eu sou um ser humano que foi criado em ambientes windows(não tive culpa!), eu também o testei no mesmo, sem problemas.
Mas como fui rebelado e voltado para OS unix, essa explicação será nesse ambiente:
Preparação:
Primeiramente, extraia todas as libs para o path(PATH_ROOT/processing-1.5/lib) do Processing
No board do arduino vamos fazer o upload da seguinte sketch:
/* this goes on your arduino for use with Processing example SimpleSerialArduinoscope */ // holds temp vals int val; void setup() { // set 2-12 digital pins to read mode for (int i=2;i<14;i++){ pinMode(i, INPUT); } Serial.begin(115200); } void loop() { // read all analog ports, split by " " for (int i=0;i<6;i++){ Serial.print(analogRead(i)); Serial.print(" "); } // read all digital ports, split by " " for (int i=2;i<14;i++){ Serial.print(digitalRead(i)); Serial.print(" "); } // frame is marked by LF Serial.println(); }
Feche o IDE do Arduino porque se não dará um bug com a porta serial (Só Deus sabe o porquê).
Agora abra a IDE do Processing e compile o seguinte sketch:
/* This is a basic serial arduinoscope. (c) 2009 David Konsumer <david.konsumer@gmail.com> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Serial data comes in, in the format 1 23 34 4 5 76 1 23 34 4 5 76 1 23 34 4 5 76 1 23 34 4 5 76 (space seperates pin=data, LF-seperated frame data) */ import arduinoscope.*; import processing.serial.*; // this example requires controlP5 // http://www.sojamo.de/libraries/controlP5/ import controlP5.*; // how many scopes, you decide. Oscilloscope[] scopes = new Oscilloscope[6]; Serial port; ControlP5 controlP5; PFont fontLarge; PFont fontSmall; int LINE_FEED=10; int[] vals; void setup() { size(800, 800, P2D); background(0); controlP5 = new ControlP5(this); // set these up under tools/create font, if they are not setup. fontLarge = loadFont("TrebuchetMS-20.vlw"); fontSmall = loadFont("Uni0554-8.vlw"); int[] dimv = new int[2]; dimv[0] = width-130; // 130 margin for text dimv[1] = height/scopes.length; // setup vals from serial vals = new int[scopes.length]; for (int i=0;i<scopes.length;i++){ int[] posv = new int[2]; posv[0]=0; posv[1]=dimv[1]*i; // random color, that will look nice and be visible scopes[i] = new Oscilloscope(this, posv, dimv); scopes[i].setLine_color(color((int)random(255), (int)random(127)+127, 255)); controlP5.addButton("pause",1,dimv[0]+10,posv[1]+10,32,20).setId(i); controlP5.addButton("logic",1,dimv[0]+52,posv[1]+10,29,20).setId(i+50); controlP5.addButton("save",1,dimv[0]+92,posv[1]+10,29,20).setId(i+100); } port = new Serial(this, Serial.list()[0], 115200); // clear and wait for linefeed port.clear(); port.bufferUntil(LINE_FEED); } void draw() { background(0); // int[] vals = getTestValuesSquare(); // int[] vals = getTestValuesSin(); for (int i=0;i<scopes.length;i++){ // update and draw scopes scopes[i].addData(vals[i]); scopes[i].draw(); // conversion multiplier for voltage float multiplier = scopes[i].getMultiplier()/scopes[i].getResolution(); // convert arduino vals to voltage float minval = scopes[i].getMinval() * multiplier; float maxval = scopes[i].getMaxval() * multiplier; int[] values = scopes[i].getValues(); float pinval = values[values.length-1] * multiplier; // add lines scopes[i].drawBounds(); stroke(255); int[] pos = scopes[i].getPos(); int[] dim = scopes[i].getDim(); line(0, pos[1], width, pos[1]); // add labels fill(255); textFont(fontLarge); text(pinval, width-60, pos[1] + dim[1] - 10); textFont(fontSmall); text("min: " + minval, dim[0] + 10, pos[1] + 40); text("max: " + maxval, dim[0] + 10, pos[1] + 48); fill(scopes[i].getLine_color()); text("pin: " + i, dim[0] + 10,pos[1] + dim[1] - 10); } // draw text seperator, based on first scope int[] dim = scopes[0].getDim(); stroke(255); line(dim[0], 0, dim[0], height); // update buttons controlP5.draw(); } // handles button clicks void controlEvent(ControlEvent theEvent) { int id = theEvent.controller().id(); // button families are in chunks of 50 to avoid collisions if (id < 50){ scopes[id].setPause(!scopes[id].isPause()); }else if (id < 100){ scopes[id-50].setLogicMode(!scopes[id-50].isLogicMode()); }else if(id < 150){ String fname = "data"+(id-100)+".csv"; scopes[id-100].saveData(fname); println("Saved as "+fname); } } // handle serial data void serialEvent(Serial p) { String data = p.readStringUntil(LINE_FEED); if (data != null) { // println(data); vals = int(split(data, ' ')); } } // for test data, you can comment, if not using int d=0; ControlTimer ct = new ControlTimer(); int[] getTestValuesSin(){ int[] vals = new int[scopes.length]; // this is test data if (d==45){ d=0; } int sval = (int) abs(sin(d*2)*1023.0f); for (int i=0;i<scopes.length;i++){ vals[i]=sval; } d++; return vals; } int oldtime; int time; boolean up=false; int[] getTestValuesSquare(){ int[] vals = new int[scopes.length]; ct.setSpeedOfTime(25); oldtime=time; time = ct.second(); if (oldtime==time){ up = !up; } for (int i=0;i<scopes.length;i++){ if (up){ vals[i]=1023; }else{ vals[i]=0; } } return vals; }
Se você desejar apenas um canal, modifique a seguinte linha:
Oscilloscope[] scopes = new Oscilloscope[6];
Como testar?
Cabo com pino 5v ou 3,3v em pino de 0-5 analógico ou você pode fazer modificações para usar com os pinos digitais.
Com esse script você terá 6 canais de análise. Um possível esquema para tal:
Finalidade?
Inúmeras, mas agora estou usando pra testar picos de sinais com minha antenas wireless com uma gambiarra.
Futuramente, estudarei um modo de criar um eletroencefalograma(EEG) vagabundo caseiro que não deixarei de apresentar a vós, caros leitores 🙂
Referências:
http://pt.wikipedia.org/wiki/Oscilosc%C3%B3pio
http://code.google.com/p/arduinoscope/
http://accrochages.drone.ws/en/node/90
http://www.practicalarduino.com/projects/scope-logic-analyzer
Gostei do post. Este Processing me lembra muito o Java , aliás o RxTx é em Java + JNI. Faltou a identação dos códigos para facilitar a leitura.
Pelo jeito não é so o Android que copiou o Java, e isso é muito bom, pois Java é uma linguagem muito limpa e de fácil leitura.
Ficarei feliz em ver o post do negocio de ler ondas celebrais.
O Processing é baseado em Java, tanto é que a sua IDE agora está se voltando também a programação para Android(Coisa que eu também pretendo mexer=]). Desculpe-me pela identação, a clareza é tudo em um algoritmo. Dá próxima colocarei tudo tabulado. O negocio do EEG, ainda vai demorar um pouco, falto adquirir materiais e também um pouco de conhecido. Mas quando estiver concluído o projeto, postarei em primeira mão.
Obrigado pelos comentários,
Abraço!
Não consegui fazer rodar aqui, pode me explicar certinho como configurar o processing?
Extrai as libs, mas acho que não funcionou.
Qual o sistema operacional que você está usando, cara?
======================================================
Pode ser um bug do processing, extrai-o para o diretório “C:/” (caso for win) ou “opt” (caso for linux) quando tem espaço no nome do diretório o processing não consegue identificar as pastas das libs( tipo “/opt/coisas aqui/processing” tem que ser um diretório sem espaços, ficando “opt/coisas_aqui/processing”)
Abraço!
Opa, muito bom esse post!
Amigo, gostaria de saber se a versão das IDEs influenciam na obtensão dos dados.
Baixei o processing 1.5.1, e o IDE do arduino 1.0.
O programa do arduino rodou normalmente, porém o programa do processing executa mas não obtem as leituras.
Segui o exemplo dito, contudo não obtive resultados.
Teria alguima idéia ?
Obs: Estou usando o Windows 7 x64 e Arduino UNO
boa noite , cara estou usando o processing e riodando os programas no simulador do android, mais percebi que o android não aceita a biblioteca controlP5. sabe o que pode estar acontecendo ? ou ele não aceita mesmo ?
abraço
A biblioteca controlP5 não foi projetada para OS android. Mas existe uma similar (muito limitada) que talvez te ajude > http://code.google.com/p/apwidgets/
Goste muito dessas iformações. Obrigado