Running two applications at once

I have recently acquired a rep rap full graphics smart controller. I have gotten the lcd to work just fine without the ramps 1.4 controller. I however have not been able to work the rotary encoder on this board properly. After meeting with someone I got a new rotary encoder that works just fine, but when I combine the code for the rotary encoder and the lcd menu the rotary encoders actions are not recognized. I have figured out the solution to this problem but do not know how to apply it.

I need to have the two processes running at the same time but I have not yet learned how to do this yet.

Post the code that does not work. Read the forum guidelines to see how to properly post code and some information on how to get the most from this forum.
Use the IDE autoformat tool (ctrl-t or Tools, Auto format) before posting code in code tags.

Post a schematic. Hand drawn, photographed and posted is fine. Or how to make a schematic that you can post.

#define outputA 7
#define outputB 8
int counter =0;
int aState;
int aLastState;
#include <Arduino.h>
#include <U8g2lib.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
int battery = A1;
int readval;
int v1 = 0;
int j=8;
int y=0;
int p=4;
U8G2_ST7920_128X64_F_SW_SPI u8g2(U8G2_R0, /* clock=*/ 10, /* data=*/ 11, /* CS=*/ 9, /* reset=*/ 16);
void setup() {
  // put your setup code here, to run once:
 Serial.begin(9600);
 pinMode(battery, INPUT);
  Serial.begin(9600);
  u8g2.begin();
  pinMode(battery, INPUT);
  pinMode (outputA,INPUT);
pinMode (outputB,INPUT);
Serial.begin(9600);
aLastState = digitalRead(outputA);
}

void loop() {
  // put your main code here, to run repeatedly
 aState = digitalRead(outputA);

if (aState != aLastState){
  if (digitalRead(outputB) != aState){
   counter --; 
  }else{
   counter ++; 
  }
 Serial.print("Position: ");
 Serial.println(counter); 
}
aLastState = aState;
  u8g2.clearBuffer();          // clear the internal memory
  u8g2.setFont(u8g2_font_ncenB08_tr); // choose a suitable font
  u8g2.drawStr(2, 13, "Info Screen");
  u8g2.drawStr(2, 28, "Battery Settings"); // write something to the internal memory
  u8g2.drawStr(2, 43, "Temp Settings");
  u8g2.drawStr(2, 58, "Humidity Settings ");
  u8g2.drawHLine(0, 0, 128);
  u8g2.drawHLine(0, 16, 128);
  u8g2.drawHLine(0, 31, 128);
  u8g2.drawHLine(0, 46, 128);
  u8g2.drawHLine(0, 63, 128);
  u8g2.drawVLine(0, 0, 64);
  u8g2.drawVLine(111, 0, 63);
  u8g2.drawVLine(127, 0, 63);
  u8g2.drawVLine(127, 0, 63);
  u8g2.drawCircle(119, y, 5);
  u8g2.drawCircle(119, y, 4);
  u8g2.drawCircle(119, y, 3);
  u8g2.drawCircle(119, y, 2);  
  u8g2.sendBuffer();
  y=counter*7.5+8.;

}

the circuit is not the problem. The circuit for the rotary encoder works when it is using its own program. The same is true for the smart controller's own code

the problem is the Arduino runs the loop but there is a delay because it moves through the steps sequentially but due to the shear size of an uno it cant move fast enough for it to continually decode the info. So I need to have the two processes running side by side rather that behind one another.

Why set the same pin mode twice?

Why serial begin 3 times?

How often does the screen need to be updated? Currently screen updates are being done with each iteration of loop().

If you are using a ESP32 you can use the built in OS freeRTOS to run multiple tasks 'at the same time' or by using both cores run two different tasks at the same time. There is the State Machine, look it up, that can be used for task switching, and there is using millis() for timing that can be used for task switching, also can be searched for on this site.

What encoder do you have? Is it this kind? Do you have external pullup resistors installed or are they on the encoder board? I would not have to ask those questions if you had provided a decent schematic.

Agreed. The real problem is that the loop() is constantly engaged doing screen output; you have all the screen commands within loop() brackets {}.

You need to move making the screen pretty with lines and such into a separate function and call it once from within setup.

Within loop, you simply want to print your data. Over print on the next update, clearing the screen with each loop() iteration is wasteful.

If you print something like 12345678 and then on the next loop() you print 1234567 the screen will show 12345678. So, the trick is to either print a 8 spaces and then "1234567" or print "1234567" and " ". Anyway pad the characters or clear the variable length fields with blanks. Some displays allow you to quickly clear display areas by coordinates. There are other ways using Streaming - Arduino Reference.

I usually take the time to layout my screen on graph paper or in notepad:


**************************** ILI9341 320x240 DISPLAY LAYOUT ****************************
0,0
----------------------------------------------------------------------------> 319
| nnnT                                                                 DOW
|              lcd.fillRect( 0,  0, 319, 59, 0);     // blank top
|
|
|<- 059 
|
|              lcd.fillRect( 0, 60, 319, 114, 0);     // blank middle
|                              HH:MM:SS A
|
|
|
|<- 174
|              lcd.fillRect( 0, 175, 319, 64, 0);     // blank lower
|
| MON DD YYYY
|
|<- 239
*/

/*
 https://learn.adafruit.com/downloads/pdf/adafruit-gfx-graphics-library.pdf


You must program lean and minimize wasted cycles in loop().  Later on, you can explore interrupt-driven coding to handle your rotary encoder.

The reason for the repetition is an accident. Because I tried to compile 4 different codes. All I want to know is how to run two loops side by side.

your solution will not work because this screen has an internal memory so that even if data is not being sent the screen will keep displaying the data.

also this screen is not laid out like the traditional lcd with the HD44780 driver given in most starter kits. I have to use a different library called u8g2.h which works with most lcd screens.

There are no rectangles

Because it is absurdly slow!

Well, that is a misunderstanding. There is one loop() code. Two "processes" mean that you have two distinct sections of code, one following the other, inside loop(). Because you have arranged your code so that nothing unnecessarily delays the cycling through loop(), both (or several) processes get a frequent "bite of the cherry".

So there are two important things about writing to the display. One is - do not write anything that is no different than before. Only when data changes are you permitted to write it. As pointed out, drawing the whole screen will only be necessary in setup() or when you need the whole screen to be changed.

And the second is - if a number of steps will take any significant time to draw, do not do them all in one pass of the loop(). Use a counter that selects one such step on each pass of the loop() and the counter then steps for the subsequent pass. This is far neater in general, than attempting to intersperse a call to the alternate function after each step of the drawing routines - which would be an alternative but less manageable approach.

Not possible with a single core processor.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.