import processing.serial.*; import java.util.Arrays; Serial p; //////////////////////////////////////////////// /*--------------------SETUP-------------------*/ //uncomment the line where your arduino/STM32 is connected //String LA_port = "/dev/ttyACM0"; //linux DFU //String LA_port = "/dev/ttyUSB0"; //linux Serial String LA_port = "COM3"; //windows final int baudrate = 115200; //check if it is the same in arduino /*------------------END SETUP-----------------*/ //////////////////////////////////////////////// //colors: int white = 255; int black = 0; int green = #00FF00; int red = #FF0000; int grey = 150; // shift, reducer and millisecond view float reducer = 1.0; boolean milliseconds = true; float xShift; // start point in the processing window float xEdge = 60; float yEdge = 10; float xEnd; float oldxEnd; float[] xPos = new float[16]; float yBottom; float yDiff; float yPos = yEdge; float ySave = yEdge; boolean textCovered; boolean drawTimes = true; //Serial from mcu //initial data int samples; int event; int initialState[]= new int[3]; boolean first = false; boolean dataComplete = false; //following data boolean [][][] state; boolean [][] isLow = new boolean[8][3]; boolean [][] isLowinit = new boolean[8][3]; float[] usTime; float[] xTime; int[][] pinChanged; int[] PinAssignment = new int[16]; int[] PinArduinoNames = new int[16]; int index1; int index2; int index3; boolean refresh= true; int []cursora= new int[2]; float cursoraf= 0; boolean cursorplay=false; /* ENGLISH How the assign of the pins works?. The entries will be depleted in the order they appear in the whole PinAssignment that goes from 0 to 15 for a total of 16, the value of the integer in each position will reference the pin to be used. Then the value that must be entered in the integer will be shown to observe the desired pin. In case you do not want to show anything on that channel, just assign 00 so that the channel will not be written. The pins that do not appear in the table can not be used because they were not considered in the arduino programming, to avoid overloading the arduino and obtain more satisfactory response times. SPANISH Funcionamiento de la asignacion de pines. Las entradas se deplegaran en el orden que aparezcan en el entero PinAssignment que va del 0 al 15 para un total de 16, el valor del entero en cada posicion referenciara el pin a utilizar. A continuacion se mostrara el valor que se debe introducir en el entero para observar el pin deseado. En caso de no querer mostrar nada en ese canal basta con asignar 00 para que el canal no sea escrito. Los pines que no aparecen en la tabla no podrán ser utilizados por que no fueron considerados en la programacion de arduino, esto para evitar sobrecargar al arduino y obtener tiempos de respuesta más satisfactorios. EN Number of Pin in the Arduino UNO Number to enter in the PinAssignment ES Numero de Pin en el Arduino UNO Numero a introducir en el PinAssignment Digital PIN 8 -------------------------------------------------------> 10 Digital PIN 9 -------------------------------------------------------> 11 Digital PIN 10 -------------------------------------------------------> 12 Digital PIN 11 -------------------------------------------------------> 13 Digital PIN 12 -------------------------------------------------------> 14 Digital PIN 13 -------------------------------------------------------> 15 */ //buttons and others int button1X = 8; int button2X = 8; int button3X = 80; int button4X = 200; int button5X = 270; int buttonY; int buttonH = 20; int smallButtonW = 50; int bigButtonW = 100; int graphBoxH; int textBoxH; int immage = 1; int corner = 10; String s; boolean initial=true; // bar scroll int handleFill = grey; float handleX; float handleY; float handleW = 20; float handleH = 15; boolean isDraggable = false; void setup () { //p = new Serial(this, Serial.list()[0], 115200); p = new Serial(this, LA_port, baudrate); p.bufferUntil('\n'); size(1300, 700); background(black); smooth(4); xShift=(width-handleW)/2; //Here you chose the pins that yuo want to show in the Logic Analizer. Put 00 to OFF the channel. //Aquí escoges los pines que quieres desplegar. PinAssignment[0] = 10; PinAssignment[1] = 11; PinAssignment[2] = 12; PinAssignment[3] = 13; PinAssignment[4] = 14; PinAssignment[5] = 15; PinAssignment[6] = 00; PinAssignment[7] = 00; PinAssignment[8] = 00; PinAssignment[9] = 00; PinAssignment[10]= 00; PinAssignment[11]= 00; PinAssignment[12]= 00; PinAssignment[13]= 00; PinAssignment[14]= 00; PinAssignment[15]= 00; for (int i=0; i<16; i++) { switch (PinAssignment[i]) { case (10): PinArduinoNames[i]=08; break; case (11): PinArduinoNames[i]=09; break; case (12): PinArduinoNames[i]=10; break; case (13): PinArduinoNames[i]=11; break; case (14): PinArduinoNames[i]=12; break; case (15): PinArduinoNames[i]=13; break; default: PinArduinoNames[i]=00; break; } } graphBoxH = height -50; textBoxH = height - 35; yBottom = graphBoxH-20; buttonY = textBoxH +8; handleX = xEdge; handleY = graphBoxH; } void cleanGraph() { noStroke(); //no borders fill(black); rect(xEdge, 0, width, graphBoxH); //cancel the graph stroke(green); //green lines Arrays.fill(xPos, 0); //reset start point of the graph textCovered = false; } void draw() { if (dataComplete==true) { cleanGraph(); pushMatrix(); //move the coordinate reference translate(xEdge, 0); float firstchange; boolean cares; if (cursorplay){ fill(50); stroke(75); if(cursora[1]==16){ //Esta variable la utilizamos para definir el canal sobre el cual estamos trabajando, en esta parte marcamos el rectangulo en el que trabajamos. rect(0, yBottom-12, width-xEdge, 34); } else{ rect(0, yEdge+36*cursora[1]-2, width-xEdge, 34); } stroke(green); } updatepos(); //Se encarga de decir que segmento de tiempos se va a escribir for (int i=0; i// yDiff=yPos; yPos+=30; } else { yDiff=yPos+30; } isLow[index1][index2]=isLowinit[index1][index2]; //println(isLowinit[index1][index2]); } else { if (isLow[index1][index2]) { //pin high else low yDiff=yPos; yPos+=30; isLow[index1][index2]=false; } else { yDiff=yPos+30; isLow[index1][index2]=true; } } // Graph lines line(xPos[n]+xShift, yPos, xTime[i]+xShift, yPos); // straight line line(xTime[i]+xShift, yPos, xTime[i]+xShift, yDiff); // vertical line xPos[n]=xTime[i]; //save last position of the line for the pin yPos = ySave; //load the initial value of the y } } yPos+=36; //go to the next pin } // Text times if ((drawTimes && cares)||i==0) { if (cursora[0]==i){ stroke(red); fill(red); }else{ stroke(grey); fill(grey); } textSize(10); textCovered=!textCovered; dashline(xTime[i]+xShift, firstchange, xTime[i]+xShift, yBottom, spacing); text(round(usTime[i]), xTime[i]+xShift+2, (textCovered==true) ? yBottom : yBottom+10); //write on different height stroke(green); } } yPos = yEdge; for (int n = 0; n < 16; n++) { if (PinAssignment[n]!=0){ s= str(PinAssignment[n]); index1 = s.charAt(1)-'0'; index2 = s.charAt(0)-'1'; if (xPos[n]==0) { if (isLowinit[index1][index2]==true) line(xPos[n]+xShift, yPos+30, xEnd+xShift, yPos+30); else line(xPos[n]+xShift, yPos, xEnd+xShift, yPos); } } yPos+=36; } dataComplete = false; popMatrix(); } drawText(); } void drawText() { stroke(white); //white borders fill(black); rect(0, 0, xEdge, graphBoxH); //clean left side rect(xEdge, graphBoxH, width, handleH); //clean bar scroll rect(0, textBoxH, width, height); //clean bottom side // write name of the pins fill(white); textSize(14); int x=5; int y=30; /* if (STM32) { for (byte i = 12; i<=15; i++) { line(x, y-20, xEdge, y-20); line(x, y+10, xEdge, y+10); text ("PB"+i, x, y); y+=60; } } else { */ for (byte i = 0; i<16; i++) { line(x, y-20, xEdge, y-20); line(x, y+10, xEdge, y+10); stroke(#EF7F1A); dashline(xEdge, y-23 , width, y-23, spacingnew); dashline(xEdge, y+13 , width, y+13, spacingnew); stroke(white); if (PinArduinoNames[i]==0){ text ("Pin "+ "OFF", x, y);} else{ text ("Pin "+ str(PinArduinoNames[i]), x, y); } y+=36; } // draw buttons fill(grey); rect(button1X, yBottom-15, smallButtonW, buttonH, corner); rect(button2X, buttonY, smallButtonW, buttonH, corner); rect(button3X, buttonY, bigButtonW, buttonH, corner); rect(button4X, buttonY, smallButtonW, buttonH, corner); rect(button5X, buttonY, smallButtonW, buttonH, corner); fill(white); text("Start", button2X+3, buttonY+14); text(reducer, button4X, buttonY+14); text("Save", button5X+3, buttonY+14); text(milliseconds == true ? "milliseconds" : "microseconds", button3X+3, buttonY+14); text("T:"+ str (drawTimes), button1X+3, yBottom); //bar scroll fill(handleFill); rect(handleX, handleY, handleW, handleH); if (isDraggable) { handleX = mouseX-handleW/2; if (handleXwidth-handleW) handleX = width-handleW; updatepos(); dataComplete = true; } } void mousePressed() { if (mouseX>xEdge && mouseXhandleY && mouseYxTime[samples-1]){ if (cursoraf<=0){ cursora[0]=0; } if (cursoraf>=xTime[samples-1]){ cursora[0]=samples-1; } }else{ for (int i=1; iabs(xTime[i+1]-cursoraf)&&state[i][index1][index2]){ if (abs(xTime[i]-cursoraf)>abs(xTime[i+1]-cursoraf)){ if(state[i][index1][index2]){ cursora[0]=i; } }else { break; } //println (abs(xTime[i]+xShift)); //println ("wut"); } } } println( cursora[0]); dataComplete=true; } void updatepos(){ if (samples!=0) { xEnd = (xTime[samples-1]); // xEnd = xEnd } else { xEnd = 0; } xShift = -map(handleX, xEdge, width-handleW, 0, xEnd); xShift = xShift + (width-handleW)/2; } void movepos(){ xShift = xTime[cursora[0]]; handleX = map(xShift, 0, xEnd, xEdge, width-handleW); xShift = -xShift - (width-handleW)/2; dataComplete=true; } void keyPressed() { int number; if (key == CODED) { if (keyCode == UP && cursorplay) { number=cursora[1]; cursora[1]= cursora[1]-1; for (int i=cursora[1]; i>=0; i--){ if (PinAssignment[cursora[1]]==0){ cursora[1]= cursora[1]-1; }else { break; } } if (cursora[1]==-1){ cursora[1]= number; } cursora[1]=constrain(cursora[1], 0, 16); //println("cur1 "+cursora[1]+"cur0 "+cursora[0]); dataComplete=true; } else if (keyCode == DOWN && cursorplay) { if(cursora[1]<16){ cursora[1]= cursora[1]+1; for (int i=cursora[1]; i<16; i++){ if (PinAssignment[cursora[1]]==0){ cursora[1]= cursora[1]+1; }else { break; } cursora[1]=constrain(cursora[1], 0, 16); } } //println("cur1 "+cursora[1]+"cur0 "+cursora[0]); dataComplete=true; } else if (keyCode == RIGHT && cursorplay) { if (cursora[1]==16){ if (cursora[0]!=samples-1){ cursora[0]+=1; } } else{ s = str(PinAssignment[cursora[1]]); index1 = s.charAt(1)-'0'; index2 = s.charAt(0)-'1'; //println(cursora[0]); for (int i=cursora[0]+1; i-1; i--){ cursora[0]=i; if (state[i][index1][index2]){ break; }else { } } } //println("cur1 "+cursora[1]+"cur0 "+cursora[0]); //updatepos(); movepos(); }else if (keyCode == LEFT && !cursorplay) { handleX-=1; if (handleXwidth-handleW) handleX = width-handleW; dataComplete=true; }else if (keyCode == RIGHT && !cursorplay) { handleX+=1; if (handleXwidth-handleW) handleX = width-handleW; dataComplete=true; } } } void mouseClicked() { // bootons over signals if(mouseX>xEdge && mouseX yBottom-15 && mouseY xEdge && mouseX yEdge && mouseY xEdge && mouseX yEdge+36 && mouseY xEdge && mouseX yEdge+36*2 && mouseY xEdge && mouseX yEdge+36*3 && mouseY xEdge && mouseX yEdge+36*4 && mouseY xEdge && mouseX yEdge+36*5 && mouseY xEdge && mouseX yEdge+36*6 && mouseY xEdge && mouseX yEdge+36*7 && mouseY xEdge && mouseX yEdge+36*8 && mouseY xEdge && mouseX yEdge+36*9 && mouseY xEdge && mouseX yEdge+36*10 && mouseY xEdge && mouseX yEdge+36*11 && mouseY xEdge && mouseX yEdge+36*12 && mouseY xEdge && mouseX yEdge+36*13 && mouseY xEdge && mouseX yEdge+36*14 && mouseY xEdge && mouseX yEdge+36*15 && mouseY yBottom-15 && mouseY button1X && mouseX buttonY && mouseY button2X && mouseX buttonY && mouseY button5X && mouseX buttonY && mouseY button4X && mouseX 90 && !milliseconds){ reducer=0.1; milliseconds = !milliseconds; } reducer = constrain(reducer, 0.1, 100); } else { //move the graph if (reducer<=1){ reducer-= 0.1; }else if (reducer<=10){ reducer-=1; }else { reducer-=10; } if (reducer<0.1 && milliseconds){ reducer=100; milliseconds = !milliseconds; } reducer = constrain(reducer, 0.1, 90); } scaletime(); updatepos(); dataComplete=true; } else // micro or millis if (mouseY>buttonY && mouseY button3X && mouseX width-handleW) handleX = width-handleW; dataComplete=true; } void mouseMoved() { if (mouseY>buttonY && mouseY button2X && mouseX buttonY && mouseY button3X && mouseX buttonY && mouseY button5X && mouseX buttonY && mouseY button4X && mouseX yBottom-15 && mouseY button1X && mouseX handleX && mouseXhandleY && mouseYxEdge && mouseX yBottom-15 && mouseY xEdge && mouseX yEdge && mouseY xEdge && mouseX yEdge+36 && mouseY xEdge && mouseX yEdge+36*2 && mouseY xEdge && mouseX yEdge+36*3 && mouseY xEdge && mouseX yEdge+36*4 && mouseY xEdge && mouseX yEdge+36*5 && mouseY xEdge && mouseX yEdge+36*6 && mouseY xEdge && mouseX yEdge+36*7 && mouseY xEdge && mouseX yEdge+36*8 && mouseY xEdge && mouseX yEdge+36*9 && mouseY xEdge && mouseX yEdge+36*10 && mouseY xEdge && mouseX yEdge+36*11 && mouseY xEdge && mouseX yEdge+36*12 && mouseY xEdge && mouseX yEdge+36*13 && mouseY xEdge && mouseX yEdge+36*14 && mouseY xEdge && mouseX yEdge+36*15 && mouseY 0) { int i; boolean drawLine = true; // alternate between dashes and gaps /* Figure out x and y distances for each of the spacing values I decided to trade memory for time; I'd rather allocate a few dozen bytes than have to do a calculation every time I draw. */ for (i = 0; i < spacing.length; i++) { xSpacing[i] = lerp(0, (x1 - x0), spacing[i] / distance); ySpacing[i] = lerp(0, (y1 - y0), spacing[i] / distance); } i = 0; while (drawn < distance) { if (drawLine) { line(x0, y0, x0 + xSpacing[i], y0 + ySpacing[i]); } x0 += xSpacing[i]; y0 += ySpacing[i]; /* Add distance "drawn" by this line or gap */ drawn = drawn + mag(xSpacing[i], ySpacing[i]); i = (i + 1) % spacing.length; // cycle through array drawLine = !drawLine; // switch between dash and gap } } }