We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hello, This is my first time using Processing on the Raspberry PI. So I made the traditional 'Blink the LED' test in Processing and it works fine. I connected a Red and Yellow LED on the breadboard to create a "ping-pong" type display.
But I noticed something when I started adding Shapes into the code. I added 2 shapes to represent the LED's, one is a red box and the other is a yellow box. And I have the code written to 'turn' on the shapes by changing the color whenever the LED on the breadboard is turned ON. Then when the LED is turned OFF, I change the color of the box to black.
But there seems to be some lag in the graphics. Basically the LED on the breadboard will turn on and the box in the window will change color about 1 second later. At first I thought maybe the "GPIO.digitalWrite" instruction is taking too long. But I swapped the code so the "fill" and "rect" instruction is done first and then after the "GPIO.digitalWrite" instruction is executed. But there was no difference or improvment.
Then I decided to add a mouse event so I can control when to start and end the blinking. There I noticed the lag in the graphics. If I clicked the mouse for a split second, where the LED's would change state just once. I would see the LED's change first, then about 1 sec later the graphics in the window would be updated. And this is a consistent anomaly.
I can't verify this on my desktop to see if I can reproduce the problem as I don't have any GPIO's available at the moment.
Has anyone noticed this before ?
Would I have something out of sequence in the code ?
below is my test code
//================================================== // Import hardware IO library. import processing.io.*; // Pin #'s for LEDs and Button: int redLEDPin = 22; int yelLEDPin = 27; int count = 0; int count2 = 0; int i = 1; // LED state, on or off (true or false). boolean redLED = true; boolean yelLED = false; boolean mouseclk = false; //---------------------------------------------------- void setup() { size(300, 200); textSize(10); //textFont(mono); // Initialize LEDs as outputs. GPIO.pinMode(redLEDPin, GPIO.OUTPUT); GPIO.pinMode(yelLEDPin, GPIO.OUTPUT); // Default to drawing black lines around buttons. stroke(0, 0, 0); // Turn the LEDs off. GPIO.digitalWrite(redLEDPin, false); GPIO.digitalWrite(yelLEDPin, false); } //------------------------------------------------------- void draw() { if (mouseclk) //check flag, only do this once { background(0, 0, 255); fill(255,255,255); text("BEGIN TEST:",5,10); text("WAIT FOR MOUSE CLICK",150, 10); text("TEST LOOP# " + i + " ",150,100); //blink redLEDiconON(); redLEDiconOFF(); yelLEDiconON(); yelLEDiconOFF(); redLED = !redLED; yelLED = !yelLED; i++; delay(1000); //count = 1; } if (!mouseclk) //check flag, only do this once { fill(255,255,255); text("END TEST:", 150,150); } //noLoop(); } //------------------------------------------------------ void mousePressed() { count2 = 1; i = 1; redLED = true; yelLED = false; mouseclk = true; } //------------------------------------------------------ void mouseReleased() { mouseclk = false; } //---------------------------------------------------- void redLEDiconON() { if (redLED) { fill(255, 0, 0); text("Red=ON",50, 80); rect(50, 20, 30, 30, 7); GPIO.digitalWrite(redLEDPin, true); //delay(200); } } //---------------------------------------------------- void redLEDiconOFF() { if (!redLED) { fill(255, 0, 0); text("Red=OFF",50, 80); fill(0, 0, 0); rect(50, 20, 30, 30, 7); GPIO.digitalWrite(redLEDPin, false); //delay(200); } } //---------------------------------------------------- void yelLEDiconON() { if (yelLED) { fill(255, 255, 0); text("Yel=ON",200, 80); rect(200, 20, 30, 30, 7); GPIO.digitalWrite(yelLEDPin, true); //delay(200); } } //---------------------------------------------------- void yelLEDiconOFF() { if (!yelLED) { fill(255, 255, 0); text("Yel=OFF",200, 80); fill(0, 0, 0); rect(200, 20, 30, 30, 7); GPIO.digitalWrite(yelLEDPin, false); //delay(200); } } //=====================================================
Answers
mouseclk is changing from true to false each time round the loop. it's only turned off when you release the mouse, so it's random whether it ends up true or false. Maybe try setting mouseclk to false during the
if (mouseclk) {
bit so it only runs once, and you could take thedelay()
out.the updated code is below
yes, this was my intention. I only wanted to the blink code so it runs while I press 'n hold the mouse button. So it runs continuously. And this would stop blinking when I released the mouse button. I did this to get control over when the blink code starts 'n stops.
About the delay, I thought I would need it because the code itself runs fast enough by itself and I couldn't see if the LEDs and shapes were actually in sync because they blink so fast.
I tried your suggestion to see what happens. And it won't run continuously, it only loops once.
I went ahead and changed the code a little and optimized the if/then statements. So now the mouse click is a toggle function. I click the mouse once to start the LEDs blinking. I click the mouse button again, and the LEDs stop blinking.
But I still see the lag in the graphics. The LED will always turn on before the graphics in the screen is updated.
Then I removed the delay again as you suggested. And the LEDs were blinking wildly fast. If I stop the blinking with the mouse click, the LED and it's corresponding box on the screen is always perfectly in sync. I don't see any lag any more. But this should hold true if I run it slower. Instead I see the lag appear again.
The moment I click the mouse button to stop the blinking, the LEDs stop blinking immediately. Then there's a 1 second lag and then finally the box on the screen is updated. As you can see in the code, I placed the delay at the end of the draw function which is the most obvious place
So with the current state of the code [below] If I toggle the mouse button, once to start the blinking and then quickly click the mouse button again to stop the blinking when I see the LEDs change. So it only loops once. I will see the LED change first before the boxes on the screen is updated. And this lag can be as long as 1 second.
It's almost as if there was some mysterious delay function between these two lines of code
Would the delay need to go somewhere else ?
Do you think my Raspberry PI is too slow. I'm using one of the older boards, the 700mhz B+. BTW, the Processing IDE is terribly slow on this. I suppose it would run better on a RPi2 or 3.
So what I do is write and build the code on my desktop using the Raspberry PI libraries, export the files to LinuxArmv6 platform, and then FTP those files to the PI and run it on there directly.
Would somebody be able to try this little Blinking LED test on their RPi and compare their results.
If it helps, here's some code that blinks an LED and doesn't use delay(). Delay does cause problems so it's better avoided if you can. Sorry, aware I'm not answering your question about drawing time for rect(), but let's remove the delays first!
To make it easier to have more than one pin blinking, this is the same sketch as an object. This lets you call blink for any pin, and set different blink rates.
forgive me , but this forum doesn't seem to let me reply to individual posts.
Your post at 5:59am looks to be very helpful. I'll have to try that after work tonight. I like how you used the internal timer, "milli()" to keep track of time. I wasn't familiar with this function in Processing. I do this too on some retro projects when programming on the C64 with assembly code.
Your last post at 7:53 also looks very helpful too. Again I have to wait til after work tonight and give it a try. I really like how you used the "Class" object. That's something I'm still practicing with as I was mostly a C coder on many projects - beside assembly. My background is hardware, but I still like to program since I was a kid - but back then it was only Basic, Fortran or Pascal.
Hope it works! If it's still slow I can test it for you on a pi zero, but hopefully optimising the code will speed it up.
ok, thanks again for the tips. I'll try this tonight and let you know
Could I trouble you to look at my other post and get some suggestions[link below]. It's about the Servo-PWM Hat from Adafruit, made for the Raspberry PI. They only have libraries in python. I really would like to move everything over to Processing. As I read about the speed gains with Processing over python [interpeter] when using a lot of math in a project. I wish they had it already in C code. But I gained an interest in Processing several years ago and now that the news it's been ported to RPi was great to hear. https://forum.processing.org/two/discussion/17319/servo-pwm-pi-hat-how-to-convert-the-python-code-into-processing-code#latest
Sorry not to be able to help with that one. In the past I've managed by looking at the data sheet & bitbanging it, rather than using a library, meaning you can stay within processing, but it's complicated & needs a bit of tweaking.
ok, no prob. I'll keep looking for more info about that one. I'm getting ready to try those examples you posted tonight.
I tried your first example. It works great !!
I merged your code with the millis() function together with mine[without the delay()]. So I can keep using the mouse toggle feature. And wouldn't you know it. The lag problem is gone. This really was a strange problem.
Plus I changed the blinkTime to 500msec. I didn't want to push it so hard right now. I'll tinker with that value and see how fast both the graphics and the LEDs can really change.
I'm going to try your 2nd example later too. below is the code
glad it's working. just for interest there are a few more optimisations you could make - for instance in yelLEDicon(), you have
fill(255,255,0)
andrect()
on both sides of the if statement - this could go at the start of the function, which is easier to read & less code.I think the code in the
if (count == 0) {}
section will work in setup which means you don't need the count integer - but anyway a boolean would be more suitable here.None of these things have to be done, if it's working, but it's good practice to keep the code tight.
ok, I see what you mean. This little test was some practice to get acquainted with building some tools with Processing. Basically a kind of a gui instrument panel to receive telemetry data and transmit any commands for my next robot project. Next test was to add some sensors to check the response time of the software.
Eventually I like to make this wireless via wifi. I see some more info about more libraries on the other website Openprocessing.org . I thought about using the udp networking libraries to transfer the telemetry data and run the instrument panel locally on a laptop to stay mobile.
I tried this before with C coding on some old embedded projects with ethernet - it was a good experience. But a future problem exists when I'm somewhere that has no wifi. I didn't know how to get around this yet - maybe use a direct wireless connection instead of wifi.