text:
OLED display hectic behavior - interference with other parts of the code?
Disclaimer: I'm a total novice to Arduino so please forgive me if the question may seem trivial, I'm trying my best to learn :)
I'm working on a small project where I have a fingerprint sensor, a servo and an OLED display. The goal is to be able to register a fingerprint and then use the fingerprint to move the servo, whilst the OLED display gives instruction / messages to the user.
I noticed a few days ago an issue whereby my OLED wouldn't simply stop working if I had some Serial.println in my code. Without understanding the root cause, by trial and error I got to the conclusion that the issue was with that specific function, so I proceeded to remove it and everything went ok.
Then I noticed that the display stopped working also by adding extremely simple pieces of code that should not be related in ANY way to how the OLED works (at least to the best of my very limited knowledge).
The code below works as expected, each and every call to the oledPrint function yields the expected result on the OLED itself.
#include <EEPROM.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET -1
Adafruit_SSD1306 display(OLED_RESET);

#include <Adafruit_Fingerprint.h>
#include <SoftwareSerial.h>

#define ISPRESSED LOW
#define BASE_MAX 200
#define MASTER_MAX 200

SoftwareSerial mySerial(2, 3);

Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);

uint8_t id;

const int buttonRegisterPin = 8; // the number of the pushbutton pin - NOTE: RED BUTTON
const int buttonRegisterMasterPin = 7; // the number of the pushbutton pin - NOTE: GREEN BUTTON
const int buttonClearPin = 6; // the number of the pushbutton pin - NOTE: BLACK BUTTON
const int buttonClearMasterPin = 12; // the number of the pushbutton pin - NOTE: YELLOW BUTTON

const int baseState = HIGH;
int ledStatus = HIGH;

int baseCount;
int masterCount;

void setup() {
  //Serial.begin (9600);
  Serial.begin (115200);

  //initialize counters
  initializeCounters();

  //initialize buttons
  initializeButton(buttonRegisterPin);
  initializeButton(buttonRegisterMasterPin);
  initializeButton(buttonClearPin);
  initializeButton(buttonClearMasterPin);

  //initialize the fingerprint sensor
  initializeFingerPrintSensor();

  //initialize the OLED display
  initializeOledDisplay();

}

void loop() {

  bool skip = false;
  oledPrint("Welcome to your fingerprint locker");
  //base registration case
  if(digitalRead(buttonRegisterPin) == ISPRESSED && skip == false){

    while(!baseRegistration());
    skip = true;
  }

  //master registration case
  if(digitalRead(buttonRegisterMasterPin) == ISPRESSED && skip == false){

    while(!masterRegistration());
    skip = true;
  }

  //base clear case
  if(digitalRead(buttonClearPin) == ISPRESSED && skip == false){
    clearRegistrations(false);
    //do stuff for base clear
    skip = true;
  }

  //master clear case
  if(digitalRead(buttonClearMasterPin) == ISPRESSED && skip == false){

    //do stuff for master clear
    skip = true;
  }
}

/**
 * Initializes a button
 * @Param: buttonPin = number of the pin used by the button
 */
void initializeButton(int buttonPin){
  pinMode(buttonPin, INPUT_PULLUP);
}

/**
 * Initializes the OLED display
 */
void initializeOledDisplay(){
  Wire.begin();
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  delay(2000);
  display.clearDisplay();

  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0, 10);
}

/**
 * initializes the fingerprint sensor
 */
void initializeFingerPrintSensor(){
  finger.begin(57600);

  if (finger.verifyPassword()) {
    Serial.println("Found fingerprint sensor!");
  }
  else {
    Serial.println("Did not find fingerprint sensor :(");
    while (1) { delay(1); }
  }
}

boolean baseRegistration(){
  boolean check = false;
  int tempBaseCount = baseCount + 1;
/*
  if(tempBaseCount > BASE_MAX){
    oledPrint("Too many users already registered");
    return true;
  }*/
  oledPrint("Starting registration");
  while(check == false){

    oledPrint("Please put your finger on the reader");

    id = tempBaseCount;
    if (id == 0) {// ID #0 not allowed, try again!
       return;
    }

    if(getFingerprintEnroll(tempBaseCount, false)){
      check = true;
    }
  }
  return check;
}

boolean masterRegistration(){
  boolean check = false;
  int tempMasterCount = baseCount + 1;
/*
  if(tempMasterCount > MASTER_MAX){
    oledPrint("Too many master keys already registered");
    return true;
  }
  */
  oledPrint("Starting master key registration");

  while(check == false){

    oledPrint("Please put your finger on the reader");

    id = tempMasterCount;
    if (id == 0) {// ID #0 not allowed, try again!
       return;
    }

    if(getFingerprintEnroll(tempMasterCount, true)){
      check = true;
    }
  }
  return check;
}

boolean clearRegistrations(bool master){
  if(master){
    //to do
  }
  else{
    //increaseBaseCounter(0);
    id = 900;
    int p = finger.deleteModel(id);
    if(p == FINGERPRINT_OK){
     // Serial.println("success");
     // Serial.println(p);
      return true;
    }
   // Serial.println("FAIL");
   // Serial.println(p);
    return false;
  }
}

// returns -1 if failed, otherwise returns ID #
int getFingerprintIDez() {
  uint8_t p = finger.getImage();
  if (p != FINGERPRINT_OK)  return -1;

  p = finger.image2Tz();
  if (p != FINGERPRINT_OK)  return -1;

  p = finger.fingerFastSearch();
  if (p != FINGERPRINT_OK)  return -1;

  // found a match!
  oledPrint2Lines("Match found, ID #", finger.fingerID);
 /* Serial.print("Found ID #");
  Serial.print(finger.fingerID);
  Serial.print(" with confidence of ");
  Serial.println(finger.confidence);*/
  return finger.fingerID;
}

uint8_t getFingerprintEnroll(int count, bool master) {
  int p = -1;
  while (p != FINGERPRINT_OK) {
    p = finger.getImage();
    switch (p) {
    case FINGERPRINT_OK:
      //oledPrint("Image taken");
      break;
    case FINGERPRINT_NOFINGER:
      break;
    case FINGERPRINT_PACKETRECIEVEERR:
      oledPrint("Communication error");
      break;
    case FINGERPRINT_IMAGEFAIL:
      oledPrint("Imaging error");
      break;
    default:
      oledPrint("Unknown error");
      break;
    }
  }

  // OK success!

  p = finger.image2Tz(1);
  switch (p) {
    case FINGERPRINT_OK:
      //oledPrint("Image converted");
      break;
    case FINGERPRINT_IMAGEMESS:
      oledPrint("Image too messy");
      return p;
    case FINGERPRINT_PACKETRECIEVEERR:
      oledPrint("Communication error");
      return p;
    case FINGERPRINT_FEATUREFAIL:
      oledPrint("Could not find fingerprint features");
      return p;
    case FINGERPRINT_INVALIDIMAGE:
      oledPrint("Could not find fingerprint features");
      return p;
    default:
      oledPrint("Unknown error");
      return p;
  }

  oledPrint("Remove finger");
  delay(2000);
  p = 0;
  while (p != FINGERPRINT_NOFINGER) {
    p = finger.getImage();
  }
  p = -1;
  oledPrint("Place the same finger again");
  while (p != FINGERPRINT_OK) {
    p = finger.getImage();
    switch (p) {
    case FINGERPRINT_OK:
      //oledPrint("Image taken");
      break;
    case FINGERPRINT_NOFINGER:
      break;
    case FINGERPRINT_PACKETRECIEVEERR:
      oledPrint("Comunication error");
      break;
    case FINGERPRINT_IMAGEFAIL:
      oledPrint("Imaging error");
      break;
    default:
      oledPrint("Unknown error");
      break;
    }
  }

  // OK success!

  p = finger.image2Tz(2);
  switch (p) {
    case FINGERPRINT_OK:
      //oledPrint("Image converted");
      break;
    case FINGERPRINT_IMAGEMESS:
      oledPrint("Image too messy");
      return p;
    case FINGERPRINT_PACKETRECIEVEERR:
      oledPrint("Communication error");
      return p;
    case FINGERPRINT_FEATUREFAIL:
      oledPrint("Could not find fingerprint features");
      return p;
    case FINGERPRINT_INVALIDIMAGE:
      oledPrint("Could not find fingerprint features");
      return p;
    default:
      oledPrint("Unknown error");
      return p;
  }

  // OK converted!

  //oledPrint2Lines("Creating model number:", count);

  p = finger.createModel();
  if (p == FINGERPRINT_OK) {
    //oledPrint("Prints matched!");
  } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
    oledPrint("Communication error");
    return p;
  } else if (p == FINGERPRINT_ENROLLMISMATCH) {
    oledPrint("Fingerprints did not match");
    return p;
  } else {
    oledPrint("Unknown errro");
    return p;
  }

  p = finger.storeModel(id);
  if (p == FINGERPRINT_OK) {
    if(master == false){
      oledPrint2Lines("Registered with id number:", count);
      increaseBaseCounter(count);
    }
    else{
      oledPrint2Lines("Registered master key number:", count - 50);
      increaseMasterCounter(count);
    }
    return 1;
  } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
    oledPrint("Communication error");
    return p;
  } else if (p == FINGERPRINT_BADLOCATION) {
    oledPrint("Could not store in that location");
    return p;
  } else if (p == FINGERPRINT_FLASHERR) {
    oledPrint("Error writing to flash");
    return p;
  } else {
    oledPrint("Unknown error");
    return p;
  }
}

uint8_t readnumber(void) {
  uint8_t num = 0;

  while (num == 0) {
    while (! Serial.available());
    num = Serial.parseInt();
  }
  return num;
}

void oledPrint(char* text){

  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.println(text);
  display.display();
  delay(2000);
}

void oledPrint2Lines(char* text, int val){

  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.print(text);
  display.print(val);
  display.display();
  delay(2000);
}

void initializeCounters(){
  //address 0 is BASE
  baseCount = EEPROM.read(0);
  Serial.println(baseCount);
  //address 1 is MASTER
  masterCount = EEPROM.read(1);
  if(masterCount < 50)
    masterCount = 50; //will get to 51 once first registered - 51 = master key #1
  Serial.println(masterCount);
}

void increaseBaseCounter(int count){
  baseCount = count;
  EEPROM.write(0, baseCount);
}

void increaseMasterCounter(int count){
  masterCount = count;
  EEPROM.write(1, masterCount);
}

However, if I uncomment the code in the baseRegistration and/or masterRegistration functions (see code snippet below), the display starts to act up: some text is displayed, some other isn't, some other again is displayed partially. I just can't find a sensible explanation anywhere, and being used to work on much higher abstraction levels this is to me completely absurd :D
boolean baseRegistration(){
  boolean check = false;
  int tempBaseCount = baseCount + 1;
//PART THAT CAUSES ISSUES - STARRT
  if(tempBaseCount > BASE_MAX){
    oledPrint("Too many users already registered");
    return true;
  }
//PART THAT CAUSES ISSUES - END
  oledPrint("Starting registration");
  while(check == false){

    oledPrint("Please put your finger on the reader");

    id = tempBaseCount;
    if (id == 0) {// ID #0 not allowed, try again!
       return;
    }

    if(getFingerprintEnroll(tempBaseCount, false)){
      check = true;
    }
  }
  return check;
}

Even more oddly, if I remove the part above from those two functions and I had one more simple call to the fingerprint sensor in the loop function, the OLED just stops working altogether (and again, absolutely crazy for me :P).
See below the loop function with the addition of the line that breaks the OLED altogether:
void loop() {

  bool skip = false;
  oledPrint("Welcome to your fingerprint locker");
  //base registration case
  if(digitalRead(buttonRegisterPin) == ISPRESSED && skip == false){

    while(!baseRegistration());
    skip = true;
  }

  //master registration case
  if(digitalRead(buttonRegisterMasterPin) == ISPRESSED && skip == false){

    while(!masterRegistration());
    skip = true;
  }

  //base clear case
  if(digitalRead(buttonClearPin) == ISPRESSED && skip == false){
    clearRegistrations(false);
    //do stuff for base clear
    skip = true;
  }

  //master clear case
  if(digitalRead(buttonClearMasterPin) == ISPRESSED && skip == false){

    //do stuff for master clear
    skip = true;
  }

  int fingerprintID = getFingerprintIDez(); //THIS IS THE LINE
  delay(50);

}

I just don't know how to proceed, if any of you would be so kind to help a novice out I'd be extremely grateful!
Thanks in advance to anyone who could point me in the right direction!!
For the sake of completeness, I'm using the adafruit libraries for the fingerprint sensor as well as the oled.

The SSD1306 library uses a lot of RAM. You may be having problems because of that. You may be better using the "text only" library: https://github.com/greiman/SSD1306Ascii

Your program seems to fit well inside the Arduino Uno memory. If your output is displaying correctly through the serial monitor, there also seems nothing wrong with your data sent to the display.
Have you tried connecting pull-up resistors to the SDA and SCL lines? Resistors around 3.9k work fine for me when using OLED displays.


text:
Arduino recognize specific sound?
I'm wondering if Arduino is able to not just measure sound and work based on hearing a sound that is "loud enough", but if it is able to identify a specific sound (say the first few seconds of a song). Is this possible, and how would one go about doing so?
If identifying the first few seconds of a song isn't really feasible, is it at least possible to do so with a consistent (but particular) pitch (rather than a general loudness threshold)?

google is your friend ... https://1sheeld.com/top-5-arduino-voice-control-modules/ ... some of these may do the job

No, you cannot recognize a song with an Arduino. It doesn't have enough computing power. I think most solutions, that recognize a song, are based on some kind of machine learning or similar, which is totally out of scope for an Arduino. For this you need a real processor like on a Raspberry Pi or similar Single Board Computers.
Identifying a specific pitch/frequency in a sound signal is possible, but you shouldn't expect great accuracy. As Duncan already wrote in his answer, you need a Fourier transformation for this. It transforms the audio signal (voltage level dependent on time) into the frequency domain (amplitude dependent on frequency). So, if you do a fourier transformation on a short audio signal, you get data about, what frequencies are in that signal with which amplitudes. You can then wait for a peak in a specific frequency range.
Doing a FFT (Fast Fourier Transformation) on an Arduino is slow and not accurate. You also only have very limited memory. So your analysed audio signals will be rather short.

There is another way to detect a specific pitch/frequency, which is more a hardware task. You can feed the audio signal into an RC resonator circuit, which is tuned to the frequency, that you are interested in. The circuit will amplify the frequency, that it is tuned to, and dampen all other frequencies (of course it is not really one specific frequency, but a small range of frequencies). The resulting signal can then be checked for threshold values, since it only contains frequencies around the tuning frequency.

What you're describing is a passive hardware notch filter. That will only respond to a specific frequency range. I guess you could build several notch filters and monitor them to detect a number of notes...

Yes, but I doubt, that you would really be able to recognize real songs. Simple "songs" with only a few notes at a time might work, but normal songs have multiple instruments plus the voice line in them. I think, this makes it really hard (since most instruments also emit many higher harmonics of the played note). Though I haven't tried that ever, so I cannot be sure here.

Agreed. We're saying the same thing: An AVR-based Arduino is not up to the job.

Thanks for your guy's input. I've been wanting to take on a machine learning project, so the idea of achieving actual song recognition with Raspberry Pi is intriguing...

As stated in other answers, sound recognition is completely out of the
realm of what an Arduino can do, but recognizing a specific pitch is
possible.
However, contrary to previous answers, I would recommend against using
an FFT. The FFT is the right tool when you need to get all the
frequency components. It is, however, overkill when you want to look at
a single frequency. Given the low processing power at your disposal, I
suggest you try instead an homodyne detection scheme. An Arduino
Uno, or similar board, has enough resources to sample an input at
9.6 kHz, and extract in real time a specific frequency component.
See for example this homodyne detection program.

The OP's stated goal is to recognize a specific sound, like the first few seconds of a song. I don't think identifying single frequency components is going to work for that application.

@DuncanC: C.f. the OP's second paragraph.

Right. Thank you though as a single pitch is acceptable and this gives me a start.

It sounds like you need to do Fourier analysis on the sound. (Breaking up the sound into its component frequencies.) Most Arduinos are based on AVR chips, which do not have hardware support for floating point math. They use software to do floating point, which makes them a poor choice for this sort of thing.
There are FFT libraries for Arduino, but they will be slow and fairly crude. You'd probably be better off using a board like a Raspberry Pi that has an ARM processor for signal processing like this.

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Can you use an Arduino UNO as an EEPROM programmer
Hi I have an Arduino UNO and a AT28c64B and a single shift register, is it possible to make an EEPROM programmer with it? I’m not too good with the Arduino to do a lot of trial and error... I would just like to know if it’s possible or not, not how to...

what is shift register? ... there is more than one type being manufactured

You need 24 GPIO pins to control that EEPROM chip. The Arduino has 19, and a typical shift register has 8 outputs. It takes 3 or 4 (depending on the shift register) to drive the shift register.
That's 19 + 8 - 4 = 23 for a shift register that needs 4 pins, or 19 + 8 - 3 = 24 for one that needs 3 pins.
However I would assume that you want to communicate with your computer as well, and that means that pins 0 and 1 of the Arduino are out of bounds, since they are used for the PC communication.
That means, at best, you have 22 pins when you need 24.
So, no, with that combination you can't, due to a lack of pins.
However an IO expander, such as the MCP23017, would give you enough pins and need fewer pins to drive. They also work in both directions, so can be used for pins that want to be read as well as written (data pins).
Alternatively an SPI or I2C connected EEPROM would be the better option, since those are designed to be driven by a small microcontroller like an Arduino uses.

Could I alternately not use all the address lines since I’m not going to use that much space, only a couple of commands, and the EEPROM is going to be used for a 6502 computer, so it can’t initially run from a serial EEPROM..

Sure, you can tie the upper address lines to GND to set those bits to always 0.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Arduino Mega's auxiliary serial ports
If I am correct, the first two pins (RX/TX) are connected to the USB, and I cannot use the serial monitor and the first RX/TX serial ports at the same time.
But, what about the other 3 auxiliary serial ports? Are they separated? Do each one of them has it's own buffer?
For example: Is it possible to add, let's say, four Bluetooth modules(Let's say HC-05) and use each of them for a different purpose?

Just to complement JRobert's answer: yes, the four serial ports are
independent. They can be activated independently, they can be set to
different baud rates if needed, and they do have separate buffers.

You can indeed use a serial monitor on your PC on the Mega's first serial port, in fact you will have to if you are connecting to one on the PC via USB port.. And just as with the Uno, you can connect a TTL serial device (like RS-232 serial, but using logic levels of 0 and +5v instead of [-3v - -25v] and [+3v - +25v] (which most PCs implemented as -12v and +12v).
If you need to connect to a true RS-232 device, you'll need to convert the TTL logic levels to something within the RS-232 spec; -5v and +5v would probably be the easiest.

Serial1, Serial2 and Serial3 are all independent, at 0/5V levels.
You can each one to a bluetooth module, or whatever HC-05 is.
Or FTDI Basic modules if you want more USB ports.
Etc.


text:
About boot-loader ic used in DEV boards
I have problem with Arduino MEGA, Arduino Deu etc...  Those Development board are having separate MCU except main MCU... Why? For what purpose are they used for?
as FTDI or bootloader chip or protection for main MCU or  what other purpose?
I don't have an idea about that?
what are they called?
Please any one clarify me this?

question 1, question 2.

There are two different reasons for a second MCU on a development board.
1) If the main MCU has a bootloader for serial upload, but doesn't include USB peripheral and the dev board should have for convenient development an USB port, then the board must include a USB-to-TTL-Serial adapter ('FTDI'). The adapter can be an FTDI USB chip, some other manufacturers USB chip (most common is CH340) or an MCU (with a USB peripheral) programed as USB-to-TTL-Serial with a firmware. Original Arduinos use ATmega 8u2 or 16u2 for this.
2) Some dev boards include a programmer for upload without bootloader. The programmer is a second MCU running a programmer firmware and is wired to programming pins of the main MCU. For example Arduino Zero, M0 Pro or Uno WiFi Rev 2, Nano Every have this concept.


text:
Read status on SCART output
I'm trying to get the status of my set top box (on/off).
It does have USB but it's always powered on.
It has optical out that is also always on.
It has an IP address that always responds to ping.
So my next idea is to read the signal in the SCART.
If I read the voltage across pin 8 and 14 I get 0-ish when off and 12 when on.
But when it powers on it spikes at 18 volt (at least what my multimeter can see).
https://youtu.be/D2eVFe33MeM
What do I need to do to read this?
If I add a voltage divider with 1 and 4.7 Kohm I get a safe voltage if it does not go above 18 volt at any time.
But what can I do to be sure I don't burn a ESP chip?
Is there any way to make sure it's safe to read even if it spikes at say 25 volts?

This is really a question best asked in https://electronics.stackexchange.com/.  But you could add a series limiting resistor then back to back zener diodes to ground to control any voltage spikes.  Suppose you could get away w/only one zener.  But most suppression circuits use two.

An optical isolator with appropriate resistors would be my recommendation.

I would use something like below. The optical isolator (PC817 or similar) protects your ESP.

Use a 1.0-1.5K resistor from the incoming SCART switch signal (SCART pin 8) to the anode of the Opto isolator (pin 1 in case of the PC817). This will limit the current through the PC817 internal LED to about 10mA with a 12V signal but the PC817 can survive up to 50mA, i.e. up to 60V on the SCART plug and even then will not damage your ESP processor.

Connect SCART ground (pin 14) to the cathode of the Opto isolator
(pin 2).

Connect a 3.3K - 4.7K resistor to the collector of the phototransistor of the PC817 (pin 4 of the PC817) and connect the other side of this resistor to Vcc of your ESP (+3.3V) as a pullup.

Connect pin 3 (emitter) of the PC817 to the Ground of your ESP.

Connect a digital input pin of your ESP to pin 4 (phototransistor collector) of your PC817 to create an active-low signal indicating your set top box is active.

This is the schematic you could use:

simulate this circuit – Schematic created using CircuitLab

I can't find a opto isolator locally. I can order one, but the shipping is about 40 times higher than the unit price. So I did some testing and with a simple LED and a resistor. The LED turns on and off as it should. Sadly the phototransistor I have can't see that light. But I just need to find the correct combination and it will work. Thank you for the idea and schematic. But sadly due to shipping cost I can't build it like that, I will be DIY-ing one.


text:
What can cause an Arduino to "disconnect" from Windows?
I bought a DFrobot Beetle and it worked fine for probably an hour, then it just stopped working with Windows.
When I connect it to the computer I hear the "connect" sound, then within 5-7 seconds I hear the disconnect sound again.
I didn't do anything special with it. I connected a RDM6300 rfid reader and used an example code from a library.
I think the last thing I did was to change a string output message in the console.
From then on it just disconnects.
I tried to email DFrobot but didn't get a reply.
What could have caused this?
What can I do to make it work again?
The reset pin didn't work.
There is not enough time to replace the code on the board before it disconnects.

What's the USB chip? is it CH340 or CP2102? if it's CH340 try installing the windows driver for it. Link.

I don't know. How can I see that? On the chip it says "MEGA32U4"  \n "-MJ" \n "1812E PH" \n "1812E81"

Can you please post a link to the actual product?

This is the place I bought it from https://www.tme.eu/en/details/df-dfr0282/programmable-controllers/dfrobot/dfr0282/ . DFrobot product page https://wiki.dfrobot.com/Beetle_SKU_DFR0282

Seems it don't a have USB chip on it but read the Introduction section. Link. Did you select Arduino Leonardo in Arduino IDE before programing it? Also read This. and the AtMega32u4 Driver.

Yes I had Leonard selected, and it worked fine for an hour with probably 10 different codes. I will try the driver, but not today. Going to bed soon. Thanks!

do a double reset and the upload some working sketch. the USB is handled by the sketch


text:
Arduino input to Visual Studio
I am completely new to programming, and I need some pointers where to look for a possible solution.
Currently I have been trying to get input from my Arduino buttons to Visual Studio to then do something with the input specifically.
There are three buttons setup and I want to use the input of these to control the answering for a quiz game in Visual Studio. Only one button can be pressed, then it will show a messagebox and advances to the next question. At the moment im having a hard time figuring out how to do this. Any pointers where to look is greatly appreciated.

Can you read a serial port from Visual Studio?

Yes, I have tried the excercise to control a LED using the form in Visual studio before. When I want to control physical buttons from Arduino to Visual Studio, then im not sure how to send the data over. I know that you can use portname.Readline(); so I can send strings over, but it takes everything thats printed in Serial Monitor?

When you connect an Arduino to a Windows computer it adds a COM port to the devices. You still use this COM-port from your serial terminal. If you detach it from the serial terminal and write a program that opens the COM-port for reading, then you can send e.g. text messages from the Arduino to the PC (your program). I don't know what programming language you use (C#?). So I can not give you a hint how to open the port and read from it.

If you are able to send texts to the PC, you can read this text in your program and interpret them. Of cause you must define a protocol, i.e. specify which text you send when a button is pressed and which text you send when the button is released and of cause which of the three button are pressed or released. e.g. "pA" if button 1 is pressed and "rB" if button 2 is released.

Thanks for taking the time to help me! I am using C#. I already have setup the com port / baud / and put the portname.Open() in. I dont know if its possible or how you can make it see the difference between strings that are going through Serial Monitor. It just react to everything when using Readline in Visual Studio.
Was thinking maybe assigning a "char" or "byte" to use for this, but I am not sure about it.

I managed to get button input into Visual Studio. It sends "A", "B" or "C" over the serial communication, that the C# program then picks up. However I want it to print only once, because with one press it prints multiple characters into serial monitor, so the messagebox that I want to show comes up multiple times.

Can you show us the sketch you're using?


text:
L298N regulated output is greated than 5V
A few months ago I used a L298N module (actually the Velleman VMA409) and I managed to make my motors working fine.
However now that I want to reuse it for another project something seems off: The regulated 5V output is always equal to the 16V VMS input.
To give more details:

I'm powering the board with 4x 3.7V 18650 batteries in series for an input of about 16V. This should be OK since according to the specs the range for VMS is 5V-35V
I'm reading the output value on the two pins I marked with an arrow in the following picture (using both of the GND pins) and in all cases I get about the same value as what I have on VMS.
This is when I have the 5V_EN jumper in place, if I remove it I get no output at all (Which I think is normal, since that disable the internal regulator)
For now I haven't connected my arduino because I want to understand what's going on before, so the Inx and EnX pins are connected to nothing.

So my questions are:

Is it indicating that I somehow fried my driver board?
Can I get back this 5V regulated output?

Does the LED go on with only VMS connected and the 5V_EN jumper in place?

your question is not about an arduino, so it is off topic here

It's more of an EE question, yes. If you ask it there, here is a link to the schematic: https://www.velleman.eu/downloads/29/infosheets/vma409-schematic.pdf

Sounds like the regulator has "failed short"

@ocrdu The LEDs do go on with only VMS connected and the jumper in place. But I'm not sure what that would mean? @ Majenko: What would be the consequences of the failing regulator: Is it still safe to use the module if I don't rely on the 5V output? Also how can I have fried this regulator?

The LED is fed by the 5V regulator in that configuration, if it were getting 16V it would probably fry, so the regulator could still be working. Just a check. Don't get why you are seeing 16V on the 5V out though. Can you measure the voltage on the 7805 output pin?

You are making an incorrect assumption, the L298N is an "H" bridge driver for small motors, not a 5V power supply. The 5 volt output is provided by a separate 78L05 regulator on the module.  This regulator cannot supply much power. Take a look at the schematic link given to you by ocrdu. Be sure all the grounds are connected.


text:
(Firebase and NodeMCU) How to reduce the delay time when control led?
My project consists of NodeMCU controlling led from Firebase's RealTime Database (Using Esp8266Firebase library)
The problem is that the delayed time is too long ( about 6 seconds from when I change the value on the server until the led is turn ON or OFF)
My code on NodeMCU 1.0
#include "FirebaseESP8266.h"
#include <ESP8266WiFi.h>

#define FIREBASE_HOST "-6c5d7.firebaseio.com"
#define FIREBASE_AUTH "hYIBAaJYb8nGPuo8Q9EfZuAIfV"

//define ledPin
int ledPin = 2; //D4

void setup(){
    //setup pinLed
    pinMode(ledPin, OUTPUT);

    //setup general
    Serial.begin(115200);
    delay(1000);
    WifiConnect();
    Serial.begin(115200);
}

void getConfirmDataForLed() {

    int controlValue;
    Firebase.getInt(firebaseData,"/Control/ControlValue",controlValue);

    switch(controlValue) {

        case 1:
            digitalWrite(ledPin, HIGH);
            break;
        default:
            digitalWrite(ledPin, LOW);
            break;
    }

}

void WifiConnect(){
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.println("Connecting to WiFi..");
    }

    Serial.println("Connected to the WiFi network");
    Serial.println(WiFi.localIP());
    Serial.println(WiFi.macAddress());

    Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
    Firebase.reconnectWiFi(true);
    //Set database read timeout to 1 minute (max 15 minutes)
    Firebase.setReadTimeout(firebaseData, 1000 * 60);
    //tiny, small, medium, large and unlimited.
    //Size and its write timeout e.g. tiny (1s), small (10s), medium (30s) and large (60s).
    Firebase.setwriteSizeLimit(firebaseData, "tiny");
    delay(1000);
}

void loop(){
    getConfirmDataForLed();
    delay(500);
}

Firebase's Structure
Control
    |
    |--ControlValue : 0

what is the average response time of firebase in your area?

When I use my android phone to send data to firebase, It changes very quickly, but it only slows on the Node

@Thang Do not reveal your Firebase auth details publicly like this. It may be misused.


text:
String generator not working as expected
I'm trying to build a random string, save it to EEPROM as int, then read it back and output it.
If I give it a predefined string then it works fine. But Something is wrong with the random string generator.
  String output;
  char letter;

  String mystr=""; //"ABCabc123..";
  String characters = "ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz";
  String numbers = "0123456789";
  String other = "<>!.,()?|=&%¤#";

  // add random characters to empty string
  for(int i=0 ; i < 12 ; i++){
    mystr += characters[random(0, characters.length())];
  }
  // add two numbers, one other and two more characters
  mystr += numbers[random(0, numbers.length())];
  mystr += numbers[random(0, numbers.length())];
  mystr += other[random(0, other.length())];
  mystr += characters[random(0, characters.length())];
  mystr += characters[random(0, characters.length())];

  // loop the string and place one character in each EEPROM address
  for(int i=0 ; i < mystr.length() ; i++)
  {
    EEPROM.writeInt( i,mystr[i] );
  }

  // read the string back from EEPROM
  for(int i=0 ; i < 17 ; i++){
    letter = EEPROM.readInt(i);
    output += letter;
  }

If I run the code output will be "H". Every time.
If I use the predefined string "ABCabc123.." then it works correct.
What am I doing wrong with building the mystr?

EEPROM.writeInt() and EEPROM.readInt() don't look like standard Arduino functions. Where did you get them? Also note that “¤” is not an ASCII character. It takes two bytes if you write it in UTF-8.

@EdgarBonet I can't include EEPROM.h . It's missing from Digispark boards I guess. I found EEPROM.h and downloaded it, but when I included it, I got an error that Debug.h was missing. So I just gave up on that and found anothter library.

Your first mistake is to use String. Don't. Instead use a char array.
char mystr[18]; // Room for 17 characters plus the NULL terminating character

Your string constants should also be char arrays, not String variables. And better to put them in PROGMEM:
const char characters[] PROGMEM = "ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz";
const char numbers[] PROGMEM = "0123456789";
const char other[] PROGMEM = "<>!.,()?|=&%¤#";

Now filling your target array becomes:
for(int i=0 ; i < 12 ; i++){
  mystr[i] = pgm_read_byte_near(characters + random(0, 50));
}

mystr[12] = pgm_read_byte_near(numbers + random(0, 10));
mystr[13] = pgm_read_byte_near(numbers + random(0, 10));
mystr[14] = pgm_read_byte_near(other + random(0, 14));
mystr[15] = pgm_read_byte_near(characters + random(0, 50));
mystr[16] = pgm_read_byte_near(characters + random(0, 50));
mystr[17] = 0; // Don't forget the NULL...

Your second problem is the use of EEPROM.writeInt and EEPROM.readInt.  Those are for writing integer values, not characters.  Instead just use EEPROM.read and EEPROM.write:
for (int i = 0; i < 17; i++) {
    EEPROM.write(i, mystr[i]);
}

Then to read back:
for (int i = 0; i < 17; i++) {
    mystr[i] = EEPROM.read(i);
}
// And don't forget to terminate the string...
mystr[17] = 0;

I can't get this working. First off all, the random does not seem to change between runs. I get the exact same string each time, only if I change something do I get a different result. When I output the array, character by character I get a shorter string than it should be. 7 characters Åo-Åyäv And two of those is not included in the character char.

Random isn't random, no. It's pseudo random. You have to set the "seed" to change the "random" sequence.

I see. I will try and use a different approach then.


text:
Can a pin be Neutral, not high or low?
I'm trying to figure out a way to controll a DFplayer mini mp3 player with ADkeys.
Because I only have two or three files to play at a fixed volume I find it easier to just use the ADkeys. https://wiki.dfrobot.com/DFPlayer_Mini_SKU_DFR0299#target_4

Lets say I want to use Segment 1 - Segment 3 (MP3 file 1 - MP3 file 3). I would then connect a resistor (or none in Segment 1) in between and to three pins on the Arduino.
But how can I make the pin neutral, so that it does not trigger everything at once?
As far as I can read the pins are grounded in Arduino if not "high".

You mean “high impedance”?

@EdgarBonet I was thinking as high as there is 5 volt, and low as grounded. Sorry for the confusion.

What you are talking about in this instance is "Open Drain".  Normally, as you rightly note, with outputs you have either HIGH or LOW, which effectively connects the output pin to +5V or GND respectively.
Instead you are asking for Open Drain.  In this arrangement a pin is either "active", in which case it connects it to GND, or "inactive", in which case it is disconnected from (almost) anything.
Most 8-bit Arduino boards don't have Open Drain capability on their IO pins (some more advanced 32-bit boards do, though), but it is easy enough to emulate it in software.
You can emulate it using "Tri-State" logic.  That is logic where, as well as HIGH and LOW you have "High Impedance", or "HI-Z".  HI-Z is pretty much the same as "inactive" Open Drain. On the Arduino HI-Z is the same as INPUT.
So you can emulate it by:

To activate a pin set it to OUTPUT and LOW
To deactivate a pin set it to INPUT

For example, to "press" one of your buttons for 100ms you could:
pinMode(4, OUTPUT);
digitalWrite(4, LOW);
delay(100);
pinMode(4, INPUT);

I see! So setting the pin to input means it's waiting for input thus is neither. That's clever!

@Andreas Actually technically the pin is always "waiting" for input. Setting it to INPUT mode just turns off the output driver circuitry and allows it to "see" the outside world.

Your drawing appears to be attempting to provide analog levels to the DF miniplayer.
What you can do in that case is use two PWM outputs from the Arduino, with a RC lowpass filter to smooth the PWM into a DC level. (Arduino pin to 10K resistor, 4.7uF cap to gnd after that, the cap/resistor junction going to the DF Miniplayer).
Then
analogWrite(pin, 128); // with pin being 3,5,6,9,10,11 on a Uno for example

to output 2.5V to the DF Miniplayer.
Similarly, 64 would be about 1.25V, while 192 would be about 3.75V.
Other levels are easily obtained.

Thank you for your answer but I believe you missed something. It's ground that the circuit is connected to, not a positive end. Or did I misunderstand you?

The DF Miniplayer has some internal pullup resistor, yes? So connecting different value resistors from the pin to Gnd via switch creates a voltage divider and results in different voltages at the pin. How is that different  than driving the pin with a voltage directly? Setup a few resistors, measure the voltage when pressed.  See 3.5 of the Manual to see what buttons do  https://github.com/Arduinolibrary/DFPlayer_Mini_mp3/raw/master/DFPlayer%20Mini%20Manual.pdf

To be honest I dont know. I don't have a clue what the internals are and how that is different. I don't have the knowledge. I can see a benefit of your answer if it works, but since I only need two or three then I'm fine with just using separate pins.


text:
Can I read from a memory card with three pins?
I have a project where I have three pins to use and I just realized it would be better to use a memory card than replacing the code each time.
I'm building a Arduino with a push button. Press the button and it sends keystrokes to the connected computer with login details.
The login details need to change every three months so having that on a memory card will be easier.
So since I use a digispark Attiny 85 with a total of 6 pins (where two is used to send the keystrokes).
I have one to the push button, and three pins left.
Is there any card reader that can work with three pins? I only need to read if that makes a difference.
The ones I find use four pins (+ vcc and gnd).
Pretty much any memory card type is ok.

Not with an ATTiny85, and not with so few pins, no.
However, all is not lost.
The ATTint85 has 512 bytes of EEPROM inside it where you can store your login details. All you need is some way of telling setting that data in your sketch from the PC - and the simplest way is probably through a USB serial connection.
If you don't have a serial connection available (I think Digispark has a custom interface they use) then you can use whatever interface you have available to do the job.

512 bytes is enough! Interesting! Is this fool proof? It's supposed to be normal people that does this. Not programmers or in any way tech savvy people.

Yes, it's foolproof. Not sur ewhat libraries are available for the attiny85, but the Arduino has the EEPROM library bundled with it...

I found this https://youtu.be/U9HEov6dDB8 not sure if it will work with digispark boards, but I will try it when I get them.

SD cards work with SPI. This needs only one pin per device (SlaveSelect) but 3 pins for the other common signals ( MISO / MOSI / SCK )
Card reader modules simply do some voltage level shifting (if at all).
But, you need a lot of RAM to work with SD cards, as data transfer always happens in 512 byte "sectors". With a file system, you need at least two such blocks in parallel. An attiny85 is simply too small.


text:
Reset Arduino by connecting vcc and gnd?
A follow up question on my previous question, if a memory card reader can be used with three pins (digispark Attiny 85):
Can I read from a memory card with three pins?
Now I came up with another idea.
Since the USB connector or the VCC pin can power an Arduino my guess is that they are in parallel and the actual Arduino is connected to both.
Kind of like this very bad schematic made on my phone: (sorry for that)

Where the blue stuff is the Arduino chip.
If that is true then adding the push button between VCC and GND with a resistor between should remove the power of the Arduino?
In that case I can have my code in setup() and use the pus button to reset the Arduino, and still have four pins to the memory card reader.
Or is this wrong? What kind of resistor value do I need to make sure I don't short the USB connector but still have less resistance than the Arduino chip?

What's the problem with pulling the RST line down to GND? Shorting a supply is likely to kill it dead (or in the worst case blow it up and cause a fire).

@Dougie as far as I can see it doesn't have a reset pin

Then it ain't an Arduino. They even have a button on the board to ground the RST pin

@Dougie as i wrote in the question, it's a digispark Attiny 85. It doesn't have a reset button, and not even a dedicated reset pin. It's a pin that I need to use to the SD card reader

Yes it does pin#1 on the chip is the RST line. So can you change the description as it is NOT an Arduino.

It's quite common to use the name Arduino as board platform name, just like these does https://www.sparkfun.com/categories/242 . What is your point really? The question clearly state what device it is. Just as if I would ask a question about a pro mini vs mega, the pin layout and the count of pins is clearly different. No I can't use pin 1, as I wrote I need all the pins for a SD card reader.

That is wrong. That is very, very wrong. That is one of the worst things you can do to a USB connection short of plugging it into the mains.
Do not even consider doing this.  Short circuits are never a good idea.

Not even with a resistor?

Not even with a resistor. To make it "reset" you'd be having to cause the voltage to drop below the brownout threshold of the MCU. The only way that will happen is if you draw more current than the supply can give you. A good USB host will shut off the power to a port where that happens and alert you that it has a malfunctioning device. A bad one will just melt.

It's a good thing I asked then.. :-)


text:
qMenuSystem using DigoleSerial library doesn’t work on my I2C Monochrome OLED
Just like the title says I’m trying to make qMenuSystem to work with my oled display.
Here is what I know so far about my display :
- It's a Monochrome OLED 128x64 (Blue) Display
- It's connecting using I2C using the 0x3C address allocated
- It's working well with Adafruit SSD1306 and Adafruit GFX Libraries
- It's looking like this : https://cdn3.volusion.com/btfzd.umflq/v/vspfiles/photos/AD304-2T.jpg?1526038845

The library DigoleSerial has the following files :
//DigoleSerial.cpp

//Digole Digital Solutions: www.digole.com
#include "DigoleSerial.h"
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "Arduino.h"

/*
// Communication set up command
 * "SB":Baud (ascII bytes end with 0x00/0x0A/0x0D) -- set UART Baud Rate
 * "SI2CA":Address(1 byte <127) -- Set I2C address, default address is:0x27
 * "DC":1/0(1byte) -- set config display on/off, if set to 1, displayer will display current commucation setting when power on
// Text Function command
 * "CL": -- Clear screen--OK
 * "CS":1/0 (1 byte)-- Cursor on/off
 * "TP":x(1 byte) y(1 byte) -- set text position
 * "TT":string(bytes) end with 0x00/0x0A/0x0D -- display string under regular mode
// Graphic function command
 * "GP":x(1byte) y(1byte) -- set current graphic position
 * "DM":"C/!/~/&/|/^"(ASCII 1byte) -- set drawing mode--C="Copy",! and ~ = "Not", & = "And", | = "Or", ^ = "Xor"
 * "SC":1/0 (1byte) -- set draw color--only 1 and 0
 * "LN":x0(1byte) y0(1byte) x1(1byte) y2(1byte)--draw line from x0,y0 to x1,y1,set new pot to x1,y1
 * "LT":x(1byte) y(1byte) -- draw line from current pos to x,y
 * "CC":x(1byte) y(1byte) ratio(byte) -- draw circle at x,y with ratio
 * "DP":x(1byte) y(1byte) Color(1byte) -- draw a pixel--OK
 * "DR":x0(1byte) y0(1byte) x1(1byte) y2(1byte)--draw rectangle, top-left:x0,y0; right-bottom:x1,y1
 * "FR":x0(1byte) y0(1byte) x1(1byte) y2(1byte)--draw filled rectangle, top-left:x0,y0; right-bottom:x1,y1
 */

// that resetting the Arduino doesn't reset the LCD, so we
// can't assume that its in that state when a sketch starts (and the
// LiquidCrystal constructor is called).

//UART function

void DigoleSerialDisp::preprint(void) {
    //write((uint8_t)0);
    Print::print("TT");
}

/*----------Functions for Graphic LCD/OLED adapters only---------*/
void DigoleSerialDisp::drawBitmap(unsigned int x, unsigned int y, unsigned int w, unsigned int h, const uint8_t *bitmap) {
    uint8_t i = 0;
    if ((w & 7) != 0)
        i = 1;
    Print::print("DIM");
    writePosition(x); //x;
    writePosition(y);
    writePosition(w);
    writePosition(h);
    for (int j = 0; j < h * ((w >> 3) + i); j++) {
        write(pgm_read_byte_near(bitmap + j));
//        delay(5);
    }
}

void DigoleSerialDisp::setRot90(void) {
    Print::print("SD1");
}

void DigoleSerialDisp::setRot180(void) {
    Print::print("SD2");
}

void DigoleSerialDisp::setRot270(void) {
    Print::print("SD3");
}

void DigoleSerialDisp::undoRotation(void) {
    Print::print("SD0");
}

void DigoleSerialDisp::setRotation(uint8_t d) {
    Print::print("SD");
    write(d);
}

void DigoleSerialDisp::setContrast(uint8_t c) {
    Print::print("CT");
    write(c);
}

void DigoleSerialDisp::drawBox(unsigned int x, unsigned int y, unsigned int w, unsigned int h) {
    Print::print("FR");
    writePosition(x);
    writePosition(y);
    writePosition(x + w);
    writePosition(y + h);
}

void DigoleSerialDisp::drawCircle(unsigned int x, unsigned int y, unsigned int r, uint8_t f) {
    Print::print("CC");
    writePosition(x);
    writePosition(y);
    writePosition(r);
    write(f);
}

void DigoleSerialDisp::drawDisc(unsigned int x, unsigned int y, unsigned int r) {
    drawCircle(x, y, r, 1);
}

void DigoleSerialDisp::drawFrame(unsigned int x, unsigned int y, unsigned int w, unsigned int h) {
    Print::print("DR");
    writePosition(x);
    writePosition(y);
    writePosition(x + w);
    writePosition(y + h);
}

void DigoleSerialDisp::drawPixel(unsigned int x, unsigned int y, uint8_t color) {
    Print::print("DP");
    writePosition(x);
    writePosition(y);
    write(color);
}

void DigoleSerialDisp::drawLine(unsigned int x, unsigned int y, unsigned int x1, unsigned int y1) {
    Print::print("LN");
    writePosition(x);
    writePosition(y);
    writePosition(x1);
    writePosition(y1);
}

void DigoleSerialDisp::drawLineTo(unsigned int x, unsigned int y) {
    Print::print("LT");
    writePosition(x);
    writePosition(y);
}

void DigoleSerialDisp::drawHLine(unsigned int x, unsigned int y, unsigned int w) {
    drawLine(x, y, x + w, y);
}

void DigoleSerialDisp::drawVLine(unsigned int x, unsigned int y, unsigned int h) {
    drawLine(x, y, x, y + h);
}

void DigoleSerialDisp::nextTextLine(void) {
    write((uint8_t) 0);
    Print::print("TRT");
}

void DigoleSerialDisp::setFont(uint8_t font) {
    Print::print("SF");
    write(font);
}

void DigoleSerialDisp::setColor(uint8_t color) {
    Print::print("SC");
    write(color);
}

void DigoleSerialDisp::backLightOn(void) {
    Print::print("BL");
    write((uint8_t) 1);
}

void DigoleSerialDisp::backLightOff(void) {
    Print::print("BL");
    write((uint8_t) 0);
}

void DigoleSerialDisp::directCommand(uint8_t d) {
    Print::print("MCD");
    write(d);
}

void DigoleSerialDisp::directData(uint8_t d) {
    Print::print("MDT");
    write(d);
}

void DigoleSerialDisp::moveArea(unsigned int x0, unsigned int y0, unsigned int w, unsigned int h, char xoffset, char yoffset) {
    Print::print("MA");
    writePosition(x0);
    writePosition(y0);
    writePosition(w);
    writePosition(h);
    write(xoffset);
    write(yoffset);
}

void DigoleSerialDisp::uploadStartScreen(int lon, const unsigned char *data) {
     int j;
     uint8_t c;
    Print::print("SSS");
    write((uint8_t) (lon % 256));
    write((uint8_t) (lon / 256));
    delay(300);
    for (j = 0; j < lon;j++) {
        if((j%32)==0)
         delay(50);
         delay(_Comdelay);
        c=pgm_read_byte_near(data+j);
        write(c);
    }
}

void DigoleSerialDisp::uploadUserFont(int lon, const unsigned char *data, uint8_t sect) {
     uint8_t c;
    Print::print("SUF");
    write(sect);
    write((uint8_t) (lon % 256));
    write((uint8_t) (lon / 256));
    for (int j = 0; j < lon; j++) {
        if((j%32)==0)
         delay(50);
         delay(_Comdelay);
        c=pgm_read_byte_near(data+j);
        write(c);
    }
}
void DigoleSerialDisp::drawBitmap256(unsigned int x, unsigned int y, unsigned int w, unsigned int h, const uint8_t *bitmap) {   //display 256 color image
    uint8_t i = 0;
    Print::print("EDIM1");
    writePosition(x); //x;
    writePosition(y);
    writePosition(w);
    writePosition(h);
    for (int j = 0; j < h * w; j++) {
        write(pgm_read_byte_near(bitmap + j));
//        delay(5);
    }
}
void DigoleSerialDisp::drawBitmap262K(unsigned int x, unsigned int y, unsigned int w, unsigned int h, const uint8_t *bitmap) {  //display 256 color image
    uint8_t i = 0;
    Print::print("EDIM3");
    writePosition(x); //x;
    writePosition(y);
    writePosition(w);
    writePosition(h);
    for (int j = 0; (j < h * w *3); j++) {
        write(pgm_read_byte_near(bitmap + j));
//        delay(5);
    }
}
void DigoleSerialDisp::setTrueColor(uint8_t r, uint8_t g, uint8_t b) {  //Set true color
    uint8_t i = 0;
    Print::print("ESC");
    write(r);
    write(g);
    write(b);
}

//DigoleSerial.h

//Digole Digital Solutions: www.digole.com
#ifndef DigoleSerialDisp_h
#define DigoleSerialDisp_h

#include <inttypes.h>
#include "Print.h"
#include <Wire.h>
#include "Arduino.h"

// Communication set up command
// Text function command
// Graph function command

#define Serial_UART 0;
#define Serial_I2C 1;
#define Serial_SPI 2;
#define _TEXT_ 0
#define _GRAPH_ 1

class DigoleSerialDisp : public Print {
public:
#if defined(_Digole_Serial_UART_)

DigoleSerialDisp(HardwareSerial *s, unsigned long baud) //UART set up
    {
        _mySerial = s;
        _Baud = baud;
        _Comdelay=2;
    }

    size_t write(uint8_t value) {
        _mySerial->write(value);
        return 1; // assume sucess
    }

    void begin(void) {
        _mySerial->begin(9600);
        _mySerial->print("SB");
        _mySerial->println(_Baud);
        delay(100);
        _mySerial->begin(_Baud);
    }
#endif
#if defined(_Digole_Serial_I2C_)

void begin(void) {
        _myWire->begin();
    }

    DigoleSerialDisp(TwoWire *s, uint8_t add) //U2C set up
    {
        _myWire = s;
        _I2Caddress = add;
        _Comdelay=6;
    }

    size_t write(uint8_t value) {
        _myWire->beginTransmission(_I2Caddress);
        _myWire->write(value);
        _myWire->endTransmission();
        return 1; // assume sucess
    }
#endif
#if defined(_Digole_Serial_SPI_)

void begin(void) {
    }

    DigoleSerialDisp(uint8_t pin_data, uint8_t pin_clock, uint8_t SS) //spi set up
    {
        _Clockpin = pin_clock;
        _Datapin = pin_data;
        _SSpin = SS;
        pinMode(_Clockpin, OUTPUT);
        pinMode(_Datapin, OUTPUT);
        pinMode(_SSpin, OUTPUT);
        digitalWrite(_SSpin, HIGH);
        digitalWrite(_Clockpin, LOW);
        digitalWrite(_Datapin, LOW);
        _Comdelay=6;
    }

    size_t write(uint8_t value) {
        digitalWrite(_SSpin, LOW);
        digitalWrite(_SSpin, LOW);
        digitalWrite(_SSpin, LOW);
        shiftOut(_Datapin, _Clockpin, MSBFIRST, value);
        digitalWrite(_SSpin, HIGH);
        return 1; // assume sucess
    }
#endif
    //    virtual size_t write(uint8_t);
    //    void begin(void);

        /*---------fucntions for Text and Graphic LCD adapters---------*/
    void writePosition(int p)
    {
    if(p>255)
    {
        write(255);
        p-=255;
    }
    write(p);
    }
    void disableCursor(void) {
        Print::print("CS0");
    }

    void enableCursor(void) {
        Print::print("CS1");
    }

    void drawStr(unsigned int x, unsigned int y, const char *s) {
        Print::print("TP");
    writePosition(x);
    writePosition(y);
        Print::print("TT");
        Print::println(s);
    }

    void setPrintPos(unsigned int x, unsigned int y, uint8_t graph = _TEXT_) {
        if (graph == _TEXT_) {
            Print::print("TP");
            writePosition(x);
            writePosition(y);
        } else {
            Print::print("GP");
            writePosition(x);
            writePosition(y);
        }
    }

    void clearScreen(void) {
        Print::print("CL");
    }

    void setLCDColRow(uint8_t col, uint8_t row) {
        Print::print("STCR");
        write(col);
        write(row);
        Print::print("\x80\xC0\x94\xD4");
    }

    void setI2CAddress(uint8_t add) {
        Print::print("SI2CA");
        write(add);
        _I2Caddress = add;
    }

    void displayConfig(uint8_t v) {
        Print::print("DC");
        write(v);
    }
    //print function

    size_t println(const __FlashStringHelper *v) {
        preprint();
        Print::println(v);
        Print::print("\x0dTRT");
    }

    size_t println(const String &v) {
        preprint();
        Print::println(v);
        Print::println("\x0dTRT");
    }

    size_t println(const char v[]) {
        preprint();
        Print::println(v);
        Print::println("\x0dTRT");
    }

    size_t println(char v) {
        preprint();
        Print::println(v);
        Print::println("\x0dTRT");
    }

    size_t println(unsigned char v, int base = DEC) {
        preprint();
        Print::println(v, base);
        Print::println("\x0dTRT");
    }

    size_t println(int v, int base = DEC) {
        preprint();
        Print::println(v, base);
        Print::println("\x0dTRT");
    }

    size_t println(unsigned int v, int base = DEC) {
        preprint();
        Print::println(v, base);
        Print::println("\x0dTRT");
    }

    size_t println(long v, int base = DEC) {
        preprint();
        Print::println(v, base);
        Print::println("\x0dTRT");
    }

    size_t println(unsigned long v, int base = DEC) {
        preprint();
        Print::println(v, base);
        Print::println("\x0dTRT");
    }

    size_t println(double v, int base = 2) {
        preprint();
        Print::println(v, base);
        Print::println("\x0dTRT");
    }

    size_t println(const Printable& v) {
        preprint();
        Print::println(v);
        Print::println("\x0dTRT");
    }

    size_t println(void) {
        Print::println("\x0dTRT");
    }

    size_t print(const __FlashStringHelper *v) {
        preprint();
        Print::println(v);
    }

    size_t print(const String &v) {
        preprint();
        Print::println(v);
    }

    size_t print(const char v[]) {
        preprint();
        Print::println(v);
    }

    size_t print(char v) {
        preprint();
        Print::println(v);
    }

    size_t print(unsigned char v, int base = DEC) {
        preprint();
        Print::println(v, base);
    }

    size_t print(int v, int base = DEC) {
        preprint();
        Print::println(v, base);
    }

    size_t print(unsigned int v, int base = DEC) {
        preprint();
        Print::println(v, base);
    }

    size_t print(long v, int base = DEC) {
        preprint();
        Print::println(v, base);
    }

    size_t print(unsigned long v, int base = DEC) {
        preprint();
        Print::println(v, base);
    }

    size_t print(double v, int base = 2) {
        preprint();
        Print::println(v, base);
    }

    size_t print(const Printable& v) {
        preprint();
        Print::println(v);
    }
    void preprint(void);
    /*----------Functions for Graphic LCD/OLED adapters only---------*/
    //the functions in this section compatible with u8glib
    void drawBitmap(unsigned int x, unsigned int y, unsigned int w, unsigned int h, const uint8_t *bitmap);
    void drawBitmap256(unsigned int x, unsigned int y, unsigned int w, unsigned int h, const uint8_t *bitmap);
    void drawBitmap262K(unsigned int x, unsigned int y, unsigned int w, unsigned int h, const uint8_t *bitmap);
    void setTrueColor(uint8_t r, uint8_t g, uint8_t b);
    void setRot90(void);
    void setRot180(void);
    void setRot270(void);
    void undoRotation(void);
    void setRotation(uint8_t);
    void setContrast(uint8_t);
    void drawBox(unsigned int x, unsigned int y, unsigned int w, unsigned int h);
    void drawCircle(unsigned int x, unsigned int y, unsigned int r, uint8_t = 0);
    void drawDisc(unsigned int x, unsigned int y, unsigned int r);
    void drawFrame(unsigned int x, unsigned int y, unsigned int w, unsigned int h);
    void drawPixel(unsigned int x, unsigned int y, uint8_t = 1);
    void drawLine(unsigned int x, unsigned int y, unsigned int x1, unsigned int y1);
    void drawLineTo(unsigned int x, unsigned int y);
    void drawHLine(unsigned int x, unsigned int y, unsigned int w);
    void drawVLine(unsigned int x, unsigned int y, unsigned int h);
    //-------------------------------
    //special functions for our adapters
    void setFont(uint8_t font); //set font, availale: 6,10,18,51,120,123, user font: 200-203
    void nextTextLine(void); //got to next text line, depending on the font size
    void setColor(uint8_t); //set color for graphic function
    void backLightOn(void); //Turn on back light
    void backLightOff(void); //Turn off back light
    void directCommand(uint8_t d); //send command to LCD drectly
    void directData(uint8_t d); //send data to LCD drectly
    void moveArea(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1, char xoffset, char yoffset); //move a area of screen to another place

    void displayStartScreen(uint8_t m) {
        Print::print("DSS");
        write(m);
    } //display start screen

    void setMode(uint8_t m) {
        Print::print("DM");
        write(m);
    } //set display mode

    void setTextPosBack(void) {
        Print::print("ETB");
    } //set text position back to previous, only one back allowed

    void setTextPosOffset(char xoffset, char yoffset) {
        Print::print("ETO");
        write(xoffset);
        write(yoffset);
    }

    void setTextPosAbs(unsigned int x, unsigned int y) {
        Print::print("ETP");
        writePosition(x);
        writePosition(y);
    }
    void setLinePattern(uint8_t pattern) {
        Print::print("SLP");
        write(pattern);
     }
    void setLCDChip(uint8_t chip) {      //only for universal LCD adapter
        Print::print("SLCD");
        write(chip);
     }
    void uploadStartScreen(int lon, const unsigned char *data); //upload start screen
    void uploadUserFont(int lon, const unsigned char *data, uint8_t sect); //upload user font
    void digitalOutput(uint8_t x) {Print::print("DOUT");write(x);}
private:
    unsigned long _Baud;
    HardwareSerial *_mySerial;
    uint8_t _I2Caddress;
    TwoWire *_myWire;
    uint8_t _Clockpin;
    uint8_t _Datapin;
    uint8_t _SSpin;
    uint8_t _Comdelay;
};

#endif

And qMenuSystem has 4 files :
qMenuDisplay.cpp
#include "qMenuDisplay.h"
#include <Wire.h>

//DigoleSerialDisp _disp(8,9,10);
DigoleSerialDisp _disp(&Wire,'\x3C');

qMenuDisplay::qMenuDisplay()
{
}

qMenuDisplay::qMenuDisplay(DigoleSerialDisp disp)
{
  _disp=disp;
}

void qMenuDisplay::Start()
{
  _disp.clearScreen();
  _disp.setFont(18);
}

void qMenuDisplay::Finish()
{
}

void qMenuDisplay::Title(const char text[])
{
  _disp.setTextPosAbs(64-strlen(text)*9/2,11);
  _disp.print(text);
  _disp.drawHLine(0,14,128);
}

void qMenuDisplay::Item(int index,const char text[])
{
  _disp.setTextPosAbs(5,(index*14)+32);
  _disp.print(text);
}

void qMenuDisplay::Highlight(int index)
{
  _disp.setMode('~');
  _disp.drawBox(4,(index*14)+20,120,13);
}

void qMenuDisplay::MessageBox(const char text[])
{
  int textWidth=strlen(text)*9;
  int x=64-(textWidth/2);
  int y=32;

  _disp.setMode('&');
  _disp.setColor(0);
  _disp.drawBox(x-5,y-12,textWidth+9,21+3);
  _disp.setMode('~');
  _disp.setColor(1);
  _disp.drawFrame(x-3,y-10,textWidth+5,17+3);

  _disp.setTextPosAbs(x,y+5);
  _disp.print(text);
}

qMenuDisplay.h

#define _Digole_Serial_I2C_
#include <DigoleSerial.h>
#ifndef qMenuDisplay_h
#define qMenuDisplay_h

class qMenuDisplay
{
  public:
    qMenuDisplay(DigoleSerialDisp disp);
    qMenuDisplay();
    void Start();
    void Finish();
    void Title(const char text[]);
    void Item(int index,const char text[]);
    void Highlight(int index);
    void MessageBox(const char text[]);
  private:
//    char tempBuffer[32];
};

#endif

qMenuSystem.cpp

/////////////////////
// qMenuSystem
// version: 1.0
// 22.12.2013
// CLASS
/////////////////////
#include <avr/pgmspace.h>
#include "qMenuSystem.h"
#include "qMenuDisplay.h"

//DigoleSerialDisp disp(255,255,255);
//qMenuDisplay qmd;

qMenuSystem::qMenuSystem(DigoleSerialDisp disp)
{
  qmd=qMenuDisplay(disp);
  _selectedIndex=0;
  _itemCount=0;
  _firstVisible=1;
}

void qMenuSystem::InitMenu(const char ** page, int itemCount, int selectedIndex)
{
  CurrentMenu=page;
  _selectedIndex=selectedIndex;
  _itemCount=itemCount;
//  ProcessMenu(ACTION_NONE);
  ShowMenu();
}

int qMenuSystem::ProcessMenu(int action)
{
  if (action==ACTION_DOWN)
    _selectedIndex++;
  if (action==ACTION_UP)
    _selectedIndex--;

  if (_selectedIndex>_itemCount)
    _selectedIndex=1;
  if (_selectedIndex<1)
    _selectedIndex=_itemCount;

  if (action==ACTION_SELECT)
    return _selectedIndex;

  ShowMenu();

  return 0;
}

void qMenuSystem::ShowMenu()
{
  if (_selectedIndex>_firstVisible+2)
    _firstVisible=_selectedIndex-2;
  else if (_selectedIndex<_firstVisible)
    _firstVisible=_selectedIndex;

  qmd.Start();

  // display title
  strcpy_P(tempBuffer, (char*)pgm_read_word(&(CurrentMenu[0])));
  qmd.Title(tempBuffer);

  // display items
  int p = 3;
  if (p > (_itemCount-_firstVisible+1))
    p=_itemCount-_firstVisible+1;
  for (int i=0;i<p;i++)
  {
    strcpy_P(tempBuffer, (char*)pgm_read_word(&(CurrentMenu[i+_firstVisible])));
    qmd.Item(i,tempBuffer);
  }

  // display selection
  qmd.Highlight(_selectedIndex-_firstVisible);

  qmd.Finish();
}

qMenuSystem.h

/////////////////////
// qMenuSystem
// version: 1.0
// 22.12.2013
// HEADER
/////////////////////
#include "qMenuDisplay.h"

#ifndef qMenuSystem_h
#define qMenuSystem_h

#define ACTION_NONE    0
#define ACTION_UP      1
#define ACTION_DOWN    2
#define ACTION_SELECT  3
#define ACTION_BACK    4

class qMenuSystem
{
  public:
    qMenuSystem(DigoleSerialDisp disp);
    void InitMenu(const char ** page, int itemCount, int selectedIndex);
    int ProcessMenu(int action);
    void ShowMenu();
    void MessageBox(const char text[]) { qmd.MessageBox(text); };

    const char ** CurrentMenu;
  private:
    int _selectedIndex;
    int _itemCount;
    int _firstVisible;

    char tempBuffer[32];
    qMenuDisplay qmd;
};

#endif

Here is what it should show on the screen : https://www.youtube.com/watch?v=rjON_enuOGs
The example code that I'm using it this:
/*
======================================
qMenuSystem example #1
======================================

1. Connect OLED in SPI mode: DATA=D8, CLOCK=D9, SS=D10
2. Compile & upload
3. Open Serial monitor (Ctrl+Shift+M)
4. Use "q", "a", "s" to move across menu ("q" = up, "a" = down, "s" = select)

*/

#define _Digole_Serial_I2C_
#include <DigoleSerial.h>
#include <Wire.h>

#include <qMenuDisplay.h>
#include <qMenuSystem.h>

#include "TestMenu.h"

//DigoleSerialDisp mydisp=DigoleSerialDisp(8,9,10);
//DigoleSerialDisp _disp(&Wire,'\x3C');

//DigoleSerialDisp mydisp=DigoleSerialDisp _disp(&Wire,'\x3C');
//qMenuSystem menu=qMenuSystem(mydisp);
DigoleSerialDisp _mydisp(&Wire,'\x3C');
qMenuSystem menu(_mydisp);

void setup()
{
  //mydisp.begin();
  //mydisp.clearScreen(); //CLear screen
  menu.InitMenu(mnuRoot,cntRoot,1);
  //mydisp.write(0);
  Serial.begin(9600);
}

void loop()
{
  int keycode=0;
  int clickedItem=0;

  if (Serial.available()>0)
  {
    switch(Serial.read())
    {
      case 97:
        menu.ProcessMenu(ACTION_DOWN);
        break;
      case 113:
        menu.ProcessMenu(ACTION_UP);
        break;
      case 115:
        clickedItem=menu.ProcessMenu(ACTION_SELECT);
        break;
    }
  }

  if (clickedItem>0)
  {
    // Logic for Root menu
    if (menu.CurrentMenu==mnuRoot)
      switch (clickedItem)
      {
        case 1:
          menu.InitMenu(mnuSubmenu1,cntSubmenu1,1);
          break;
        case 2:
          menu.InitMenu(mnuSubmenu2,cntSubmenu2,1);
          break;
        case 3:
          menu.InitMenu(mnuSubmenu3,cntSubmenu3,1);
          break;
        case 4:
          menu.MessageBox("Some message!");
          break;
      }
    // Logic for Submenu 1
    else if (menu.CurrentMenu==mnuSubmenu1)
      switch (clickedItem)
      {
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
          menu.MessageBox("Item clicked");
          break;
        case 6:
          menu.InitMenu(mnuRoot,cntRoot,1);
          break;
      }
    // Logic for Submenu 2
    else if (menu.CurrentMenu==mnuSubmenu2)
      switch (clickedItem)
      {
        case 1:
          menu.MessageBox("On");
          break;
        case 2:
          menu.MessageBox("Off");
          break;
        case 3:
          menu.InitMenu(mnuRoot,cntRoot,2);
          break;
      }
    // Logic for Submenu 3
    else if (menu.CurrentMenu==mnuSubmenu3)
      switch (clickedItem)
      {
        case 1:
          menu.MessageBox("Enabled");
          break;
        case 2:
          menu.MessageBox("Disabled");
          break;
        case 3:
          menu.InitMenu(mnuRoot,cntRoot,3);
          break;
      }

  }
}

and with the bundled progmem part :
// required for "prog_char" and "PROGMEM"
#define _PROG_TYPES_COMPAT_
#include <avr/pgmspace.h>

// texts for menus

const char itmBack[] PROGMEM = "< Back";
const char itmOn[] PROGMEM = "On";
const char itmOff[] PROGMEM = "Off";
const char itmEnabled[] PROGMEM = "Enabled";
const char itmDisabled[] PROGMEM = "Disabled";

const char itmRoot[] PROGMEM = "Root menu";
const char itmSubmenu1[] PROGMEM = "Submenu 1";
const char itmSubmenu2[] PROGMEM = "Submenu 2";
const char itmSubmenu3[] PROGMEM = "Submenu 3";
const char itmMessageBox[] PROGMEM = "Message box";
const char itmItem1[] PROGMEM = "Item 1";
const char itmItem2[] PROGMEM = "Item 2";
const char itmItem3[] PROGMEM = "Item 3";
const char itmItem4[] PROGMEM = "Item 4";
const char itmItem5[] PROGMEM = "Item 5";

////////////////////////////////////////////////////////////////
// menus - first item is menu title and it does not count toward cnt

const char* mnuRoot[] = {
  itmRoot,
  itmSubmenu1,itmSubmenu2,itmSubmenu3,itmMessageBox};
const int cntRoot = 4;

const char* mnuSubmenu1[] = {
  itmSubmenu1,
  itmItem1,itmItem2,itmItem3,itmItem4,itmItem5,itmBack};
const int cntSubmenu1 = 6;

const char* mnuSubmenu2[] = {
  itmSubmenu2,
  itmOn,itmOff,itmBack};
const int cntSubmenu2 = 3;

const char* mnuSubmenu3[] = {
  itmSubmenu3,
  itmEnabled,itmDisabled,itmBack};
const int cntSubmenu3 = 3;

Can somebody please help me figuring out what's wrong that it doesn't show on the screen? (there are no errors on the code while compiling.)
Thank you so much for reading all the code I posted and for your time.

try changing the first include in qMenuDisplay.h

Thank you for reply, sorry but it's a little bit unclear. First   in which file ? in the test code it's present straight from the start.


text:
qMenuSystem Oled I2C can't make it work
I'm trying to make the qMenuSystem to work with my I2C Monochrome OLED display but without any luck.
To summarize all here's what's with it :
- the qMenuSystem is using a library called : DigoleSerial but has the things set as SPI connection
- the library itself can work with I2C but i'm receiving some strange errors like this :

Arduino: 1.8.9 (Mac OS X), Board: "Arduino/Genuino Uno"

TestMenu:25:42: error: expected primary-expression before '_disp'
 DigoleSerialDisp mydisp=DigoleSerialDisp _disp(&Wire,'\x3C');
                                          ^
exit status 1
expected primary-expression before '_disp'

Here is the video of what i'm trying to display:
https://www.youtube.com/watch?v=rjON_enuOGs (I already tried what's suggested in the comments)
Here's the code so far:
#define _Digole_Serial_I2C_
#include <DigoleSerial.h>
#include <Wire.h>

#include <qMenuDisplay.h>
#include <qMenuSystem.h>

#include "TestMenu.h"

//DigoleSerialDisp mydisp=DigoleSerialDisp(8,9,10);
//DigoleSerialDisp _disp(&Wire,'\x3C');

DigoleSerialDisp mydisp=DigoleSerialDisp _disp(&Wire,'\x3C');
qMenuSystem menu=qMenuSystem(mydisp);

void setup()
{
  menu.InitMenu(mnuRoot,cntRoot,1);
  Serial.begin(9600);
}

void loop()
{
  int keycode=0;
  int clickedItem=0;

  if (Serial.available()>0)
  {
    switch(Serial.read())
    {
      case 97:
        menu.ProcessMenu(ACTION_DOWN);
        break;
      case 113:
        menu.ProcessMenu(ACTION_UP);
        break;
      case 115:
        clickedItem=menu.ProcessMenu(ACTION_SELECT);
        break;
    }
  }

  if (clickedItem>0)
  {
    // Logic for Root menu
    if (menu.CurrentMenu==mnuRoot)
      switch (clickedItem)
      {
        case 1:
          menu.InitMenu(mnuSubmenu1,cntSubmenu1,1);
          break;
        case 2:
          menu.InitMenu(mnuSubmenu2,cntSubmenu2,1);
          break;
        case 3:
          menu.InitMenu(mnuSubmenu3,cntSubmenu3,1);
          break;
        case 4:
          menu.MessageBox("Some message!");
          break;
      }
    // Logic for Submenu 1
    else if (menu.CurrentMenu==mnuSubmenu1)
      switch (clickedItem)
      {
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
          menu.MessageBox("Item clicked");
          break;
        case 6:
          menu.InitMenu(mnuRoot,cntRoot,1);
          break;
      }
    // Logic for Submenu 2
    else if (menu.CurrentMenu==mnuSubmenu2)
      switch (clickedItem)
      {
        case 1:
          menu.MessageBox("On");
          break;
        case 2:
          menu.MessageBox("Off");
          break;
        case 3:
          menu.InitMenu(mnuRoot,cntRoot,2);
          break;
      }
    // Logic for Submenu 3
    else if (menu.CurrentMenu==mnuSubmenu3)
      switch (clickedItem)
      {
        case 1:
          menu.MessageBox("Enabled");
          break;
        case 2:
          menu.MessageBox("Disabled");
          break;
        case 3:
          menu.InitMenu(mnuRoot,cntRoot,3);
          break;
      }

  }
}

and the progmem part :
// required for "prog_char" and "PROGMEM"
#define _PROG_TYPES_COMPAT_
#include <avr/pgmspace.h>

// texts for menus

const char itmBack[] PROGMEM = "< Back";
const char itmOn[] PROGMEM = "On";
const char itmOff[] PROGMEM = "Off";
const char itmEnabled[] PROGMEM = "Enabled";
const char itmDisabled[] PROGMEM = "Disabled";

const char itmRoot[] PROGMEM = "Root menu";
const char itmSubmenu1[] PROGMEM = "Submenu 1";
const char itmSubmenu2[] PROGMEM = "Submenu 2";
const char itmSubmenu3[] PROGMEM = "Submenu 3";
const char itmMessageBox[] PROGMEM = "Message box";
const char itmItem1[] PROGMEM = "Item 1";
const char itmItem2[] PROGMEM = "Item 2";
const char itmItem3[] PROGMEM = "Item 3";
const char itmItem4[] PROGMEM = "Item 4";
const char itmItem5[] PROGMEM = "Item 5";

////////////////////////////////////////////////////////////////
// menus - first item is menu title and it does not count toward cnt

const char* mnuRoot[] = {
  itmRoot,
  itmSubmenu1,itmSubmenu2,itmSubmenu3,itmMessageBox};
const int cntRoot = 4;

const char* mnuSubmenu1[] = {
  itmSubmenu1,
  itmItem1,itmItem2,itmItem3,itmItem4,itmItem5,itmBack};
const int cntSubmenu1 = 6;

const char* mnuSubmenu2[] = {
  itmSubmenu2,
  itmOn,itmOff,itmBack};
const int cntSubmenu2 = 3;

const char* mnuSubmenu3[] = {
  itmSubmenu3,
  itmEnabled,itmDisabled,itmBack};
const int cntSubmenu3 = 3;

I'm kinda new and I have no idea how can I make it work. Can anyone please help me figure it out what's wrong ?
Thank you for your time reading all of this.

As the compiler is indicating, the line
DigoleSerialDisp mydisp=DigoleSerialDisp _disp(&Wire,'\x3C');

is broken.
This part:
DigoleSerialDisp _disp(&Wire,'\x3C')

declares and constructs an object named _disp of class DigoleSerialDisp.
You're trying to assign that to another variable, mydisp - that's not valid C++ - you can assign another variable, but you'd need to declare and construct it first, not in the assignment. There's also no need to construct it, name it _disp and then assign it to another variable.
Just do this:
DigoleSerialDisp mydisp(&Wire,'\x3C');

You'll probably want to rewrite
qMenuSystem menu=qMenuSystem(mydisp);

as
qMenuSystem menu(mydisp);

as well.

Thank you very much for your explanation and for your help. Now it's compiling without any error. All's good but I can't see anything on the display. My OLED is working well when I use the Adafruit SSD1306 library with Adafruit GFX library, but I don't know about this DigoleSerial library.  Here's my OLED (sort of , it looks the same) : https://bit.ly/2kgZa6p . It's using the address 0x3C when I use the Adafruit libraries. Is it anything i still missing ? Thank you again for the fast help.

I'm glad this was helpful. If you have another question the best thing to do is accept this as the answer to the question you asked and ask your other question separately. This helps other people with similar problems find the answer to their problem, and lets other people who may be able to help you with your next problem find the question and offer help (they won't find it here in the comments).

Thank you again. I'm new here so i don't really know the flow but I get it. I'll ask a new question in a new topic.

You're doing great :) Thanks!


text:
How do you write to a specific register using I2C communcation?
I am trying to write to a charging IC (BQ24193) and I am trying to figure out how to use I2C to write to a specific register so I can set up the charging IC properly. I have watched a few videos on the communication protocol, but I don't understand how to write to a register directly. Your help would be appreciated. Thanks.
Datasheet: http://www.ti.com/lit/ds/symlink/bq24193.pdf

use Wire library

figure 18 in the datasheet

The Arduino uses the Wire.h library to communicate on an I2C bus.
Writing to a register in I2C is usually done by sending two bytes to the correct I2C address.  The first byte is usually the register address, and the second is the value to place into the register:
#define CHIP_ADDRESS     0x6B
#define REGISTER_ADDRESS 0x12

Wire.beginTransmission(CHIP_ADDRESS);
Wire.write(REGISTER_ADDRESS);
Wire.write(0x18);
Wire.endTransmission();

Reading from a register is slightly more tricky, in that first you need to write to the chip to set the register address, then as a separate operation you need to read from that address:
Wire.beginTransmission(CHIP_ADDRESS);
Wire.write(REGISTER_ADDRESS);
Wire.endTransmission();
Wire.requestFrom(CHIP_ADDRESS, 1); // We want one byte
uint8_t val = Wire.read();

So with my IC, how do I find the address for each register? I checked the datasheet, and it only included the slave address.

@Jay page 26: "8.5 Register Map"


text:
How can I make my code Thread-Safe?
So I made a post yesterday running into an issue on my ESP32 using both cores on the microcontroller (with wifi enabled, incase that is important).
I'm using both cores to control two Neopixel strips individually. I'm making a music visualizer, and I want the neopixels to react to the change in music as quickly as possible, so I felt like having one for every individual core was the best way for that to happen. The issue I am running into is that when audio is playing, the Music Visualizer function either in the primary core (Core 1), or secondary core (Core 0) will just completely freeze. I tried troubleshooting with some Serial.Print statements to understand where the code breaks, and it seems to happen around the setPixelColor command. I think my code is being thread locked, and I wanted to know what I could do to make it thread safe.
void musicVisualizer(void) {
  middle_strip.clear();
  upper_strip.clear();

  middle_strip.show();
  upper_strip.show();

  // Add code to tell Core 0 to wait until LED's are cleared.
  while (vu_meter) {
    tweeter_prev = tweeter;
    if (analogRead(tweeter_sample) <= 490)
      tweeter_adc = 0;
    else {
      tweeter_adc = (analogRead(tweeter_sample) - 490);
      if (tweeter_adc < 0)
        tweeter_adc = 0; // Filter for changing reference voltage
      else if (tweeter_adc > MIDDLE_LED_COUNT)
        tweeter_adc = tweeter_prev; // Filter for if there are intermittent spikes in the adc
    }
    tweeter_filter.Filter(tweeter_adc);
    tweeter = tweeter_filter.Current() * 6;  // 6 scaler is for when Alexa is at Volume Level 4

    //    /* Changing LED Number to improve efficency when turning on LED's */
    //    if (tweeter > 43)
    //      LED_COUNT = 65;
    //    else if (tweeter > 21)
    //      LED_COUNT = 43;
    //    else if (tweeter <= 21)
    //      LED_COUNT = 21;

    /* LED's turning on and off in response to audio */
    if ((tweeter > tweeter_prev) && (tweeter <= MIDDLE_LED_COUNT)) {
      for (int x = tweeter_prev; x < tweeter; x++) {
        //        middle_strip.setPixelColor(x, color);
        middle_strip.setPixelColor(x, 0, 0, middle_strip.gamma32(brightness));
        middle_strip.show();
      }
    }
    else if (tweeter_prev > tweeter) {
      for (int x = tweeter_prev; x >= tweeter; x--) {
        middle_strip.setPixelColor(x, 0, 0, 0);
        middle_strip.show();
      }
    }
  }

  /* Leaving VU Meter, returning to current lamp color set */
  if (led_on) {
    if (!color_white) {
      for (int i = 0; i < LOWER_LED_COUNT; i++) {
        lower_strip.setPixelColor(i, color);
        lower_strip.show();
      }
      for (int i = 0; i < MIDDLE_LED_COUNT; i++) {
        middle_strip.setPixelColor(i, color);
        middle_strip.show();
      }
      for (int i = 0; i < UPPER_LED_COUNT; i++) {
        upper_strip.setPixelColor(i, color);
        upper_strip.show();
      }
    }
    else {
      for (int i = 0; i < LOWER_LED_COUNT; i++) {
        lower_strip.setPixelColor(i, 0, 0, 0, lower_strip.gamma32(brightness));
        lower_strip.show();
      }
      for (int i = 0; i < MIDDLE_LED_COUNT; i++) {
        middle_strip.setPixelColor(i, 0, 0, 0, middle_strip.gamma32(brightness));
        middle_strip.show();
      }
      for (int i = 0; i < UPPER_LED_COUNT; i++) {
        upper_strip.setPixelColor(i, 0, 0, 0, upper_strip.gamma32(brightness));
        upper_strip.show();
      }
    }
  }
  else {
    upper_strip.clear();
    middle_strip.clear();
    lower_strip.clear();

    upper_strip.show();
    middle_strip.show();
    lower_strip.show();
  }
}

void vu_meter_sub(void * parameter) {
  while (true) {
    esp_task_wdt_init(30, false);
    if (vu_meter) {
      lower_strip.clear();
      lower_strip.show();
      while (vu_meter) {
        sub_prev = sub;
        sub_adc = analogRead(sub_sample);
        if (sub_adc > LOWER_LED_COUNT)
          sub_adc = LOWER_LED_COUNT-1;
        sub_filter.Filter(sub_adc);
        sub = sub_filter.Current();
        //        if (sub < 0)
        //          sub = 0;
        Serial.println(sub);
        if ((sub > sub_prev) && (sub <= LOWER_LED_COUNT)) {
          for (int x = sub_prev; x < sub; x++) {
            //            lower_strip.setPixelColor(x, color);
            lower_strip.setPixelColor(x, 0, lower_strip.gamma32(brightness), 0);
            lower_strip.show();
          }
        }
        else if (sub_prev > sub) {
          for (int x = sub_prev; x >= sub; x--) {
            lower_strip.setPixelColor(x, 0, 0, 0);
            lower_strip.show();
          }
        }
        Blynk.run();
      }
    }
  }
}

I am not sure this is related to thread-safety, but you should be aware
that strip.show() is a slow function that blocks while the data is
being sent. setPixelColor(), in contrast, is fast, as it only updates
the data in memory.
I suggest you modify musicVisualizer() in such a way that it only
show()s each strip once. The bulk of the function should be about
computing the colors you want and setting them with setPixelColor().
Then, at the very end of the function, show() the three strips.

I thank you for the suggestion. I implemented this into my code, but this did not fix the issue I'm experiencing with one of the cores freezing up. I feel like this might have to do with the fact that they are sharing the same library header?


text:
ISR Issue: Arduino Pro Micro
I'm trying to do a small test where I am using the ISR on the Arduino Pro Micro it up from sleep mode. I'm using a Force Sense Resistor (FSR, a resistor that changes it's resistance depending on how hard you press it) with a voltage divider circuit with the output of the voltage divider connected to an analog pin and the digital interrupt pin. I'm not able to get the interrupt to trigger no matter what condition I have. I don't believe the Vout on the voltage divider is too low since the ADC registers values between 0 to 1000 (0V to about 4.8V) when the FSR is pressed. Is there anything wrong with my code that is preventing my test from working properly?
uint8_t LED = 9;
uint8_t wakeup = 2;
uint8_t enable = 0;

void Wakeup(void);

void setup() {
  // put your setup code here, to run once:
  pinMode(LED, OUTPUT);
  pinMode(wakeup, INPUT);
  attachInterrupt(digitalPinToInterrupt(1), Wakeup, RISING);
  Serial.begin(115200);
}

void loop() {
  // put your main code here, to run repeatedly:
  //Serial.println(analogRead(A2));
  if (enable == HIGH)
    digitalWrite(LED, HIGH);
  else if (enable == LOW)
    digitalWrite(LED, LOW);
  if (analogRead(A2) < 700)
    enable = 0;
}

void Wakeup(void) {
  enable = 1;
  Serial.println("Interrupt");
}

perhaps you should not be using the serial port pin for the interrupt

I thought 0 and 1 were serial pins. I'm using digital pin 2

@jsotola it's pro micro with 32U4. it doesn't use pin 2 for serial

please review your code

Don't do serial prints inside an ISR.

Your variable enable should be declared volatile as it changes inside an ISR. The compiler is entitled to cache the variable value if you don't do that.

You are inconsistent in your use of enable. You test for LOW or HIGH but set it to 0 or 1. Now they happen to be the same, but someone might wonder. If you are going to test for LOW or HIGH, then assign LOW or HIGH to it.

See my reference question How do interrupts work on the Arduino Uno and similar boards?.

I thought 0 and 1 were serial pins. I'm using digital pin 2

Not in the code you are not:
attachInterrupt(digitalPinToInterrupt(1), Wakeup, RISING);

Do you mean:
attachInterrupt(digitalPinToInterrupt(wakeup), Wakeup, RISING);

It's kind of confusing to have two names which differ only in case.


text:
Arduino Due as Triggered DMA SPI Slave is possible?
Is it possible for arduino Due to act as DMA-SPI-slave device which can exchange SPI data (uint16_t TX[10] and RX[10]) in triggered slave mode?
I have a setup in which time period is very short (~500uS/cycle). so I need to exchange data with another Microcontroller (acting as 'Master') within the mensioned time limit. Some other tasks are also to be processed. This is why I have to go for DMA and fast data transfer without intervension of processor. All the codes available are to be used in Master mode of SPI. Not a single one is in SLAVE mode.
I wrote a code but I cannot implement a transfer triggered by SPI hardware. Also how to implement data transfer complete Interrupt after all 10 datas(16bit) have been transferred and received?
Here is my initialization code:
    void DMAslaveBegin()
{
    // Configure the pins for SPI in peripheral mode
    PIO_Configure(
        g_APinDescription[PIN_SPI_MOSI].pPort,
        g_APinDescription[PIN_SPI_MOSI].ulPinType,
        g_APinDescription[PIN_SPI_MOSI].ulPin,
        g_APinDescription[PIN_SPI_MOSI].ulPinConfiguration);
    PIO_Configure(
        g_APinDescription[PIN_SPI_MISO].pPort,
        g_APinDescription[PIN_SPI_MISO].ulPinType,
        g_APinDescription[PIN_SPI_MISO].ulPin,
        g_APinDescription[PIN_SPI_MISO].ulPinConfiguration);
    PIO_Configure(
        g_APinDescription[PIN_SPI_SCK].pPort,
        g_APinDescription[PIN_SPI_SCK].ulPinType,
        g_APinDescription[PIN_SPI_SCK].ulPin,
        g_APinDescription[PIN_SPI_SCK].ulPinConfiguration);
    PIO_Configure(
        g_APinDescription[PIN_SPI_SS0].pPort,
        g_APinDescription[PIN_SPI_SS0].ulPinType,
        g_APinDescription[PIN_SPI_SS0].ulPin,
        g_APinDescription[PIN_SPI_SS0].ulPinConfiguration);
    //pmc_enable_periph_clk(ID_SPI0);
#if USE_SAM3X_DMAC
    pmc_enable_periph_clk(ID_DMAC);
    DMAC_Disable();
    DMAC->DMAC_GCFG = DMAC_GCFG_ARB_CFG_FIXED;  //Fixed priority arbiter
    DMAC_Enable();

#if USE_SAM3X_BUS_MATRIX_FIX    // not active here
    MATRIX->MATRIX_WPMR = 0x4d415400;
    MATRIX->MATRIX_MCFG[1] = 1;         //Single Access
    MATRIX->MATRIX_MCFG[2] = 1;         //Single Access
    MATRIX->MATRIX_SCFG[0] = 0x01000010;
    MATRIX->MATRIX_SCFG[1] = 0x01000010;
    MATRIX->MATRIX_SCFG[7] = 0x01000010;

#endif  // USE_SAM3X_BUS_MATRIX_FIX
#endif  // USE_SAM3X_DMAC
    //  initialize SPI controller - Slave mode
    SPI.begin(_pin);
    SPI_Disable(SPI0);
    REG_SPI0_CR = SPI_CR_SWRST;     // reset SPI
    REG_SPI0_CR = SPI_CR_SPIEN;     // enable SPI
    REG_SPI0_MR = 0x10;              // DLYBCS=0, PCS=0, MODFDIS=1, PS=0, MSTR=0(slave)
    REG_SPI0_CSR = 0x80;            // DLYBCT=0, DLYBS=0, SCBR=0, 16 bit transfer, Mode 0/1
    REG_SPI0_IDR = ~SPI_IDR_RDRF;
    REG_SPI0_IER = SPI_IDR_RDRF;
    NVIC_EnableIRQ(SPI0_IRQn);
    SPI_Enable(SPI0);
}

Is this a valid condition for DMA?
How can I utilize SPI ISR handler like system in DMA for my code so that the complete transaction (simultaneous Transmit & Receive) becomes fully automatic without processor utilization?

It is more than likely possible.  However, we lowly Arduino users probably aren't knowledgeable enough about Atmel's SDK and the workings of the Due's MCU to give you the best answer. Your best source of information would probably be a dedicated Atmel ARM MCU forum. One that deals on a more professional level than Arduino.

Thanks. I'll post. but, does DMA callbacks on SPI interrupt?

What does the datasheet / SDK API manual say?

PDC can employ Handler, but I couldn't find DMA Handler for SPI slave mode. The datasheet DMAC section is also messy.

I don't think DMA really cares about what "mode" SPI is running in.

Looking at the datasheet though it only talks about dma in master mode, so maybe it cant...

Your point of view might be right about "DMA really cares about what "mode" SPI is running in".@Majenko. We are using SPI RX and TX Buffers as Source and Destination respectively. So, the SPI hardware is handling all data transfer and Interrupts; after this, DMA takes over for interaction with memory. The DMA and SPI both have a seperate clock and need to be activated seperately. This is the proof that two modules are seperate. Also, DMA is acting on behalf of processor, so it needs to be in master mode. Then, how we can enable and access "Chained buffer transmit complete" interrupt?

I think I have discovered a solution while searching:
https://github.com/avrxml/asf/blob/master/sam/drivers/spi/spi_dmac_slave_example/spi_dmac_slave_example.c It is an example for atmel's sam3X8EK. But the MCU cores are same. Though the code serves different purpose, we can manage to mold it in the direction we need. Only thing remained to do is to push an array through it.
Fellows, what do you think?


text:
How to make procedures triggered remotely
I am installing lights in a model train and there are multiple prototypical lighting procedures that need to be activated. The lights are connected as follows:
Headlight Top - Pin 1
Headlight Bottom - Pin 2
Front Right Marker - Pin 3
Front Left Marker - Pin 4
Rear Right Marker - Pin 5
Rear Left Marker - Pin 6
Rear Left Headlight - Pin 7
Rear Right Headlight - Pin 8
Front Right Ditch Light - Pin 9
Front Left Ditch Light - Pin 10
I would like to simply address a forward procedure which would turn on pins 1, 2, 3, 4, 5, 6, 9, and 10. This is the lighting configuration when the loco is shifted into the forward gear. For reverse, pins 3, 4, 5, 6, 7, and 8 would be activated. There will be a few others too but those are the primary procedures. Is there a way I could set up a variable which names all those pins at once? Or is there some other way I could name a forwards or backwards lighting procedure with a single short name such as "Procedure 2"? I am using Arduino IDE.

perhaps an array and a loop? (dont have the Arduino IDE atm, so sorry about any typos)
int lights[] = {1, 2, 3, 4, 5, 9, 10};
int count = 7;//because there are 7 items in the array
//

main(){
    for (int i = 0; i < count; i++){
         digitalWrite(lights[i], HIGH);
         delay(1000);
    }
}

EDIT: still no IDE, but here is a little more depth.
forward(true) = forward lights on
forward(false) = forward lights off
reverse(true) = reverse lights on
reverse(false) = reverse lights off
void forward(bool state){
    int lights[] = {1, 2, 3, 4, 5, 6, 9, 10};
    int count = sizeof(lights) / sizeof(lights[0]);

    for (int i = 0; i < count; i++){
        switch (state){

            case true: //turn on
                digitalWrite(lights[i], HIGH);
                break;

            case false: //turn off
                digitalWrite(lights[i], LOW);
                break;
        }
        //delay(1000); //optional delay between lights?
    }
}

void reverse(bool state){
    int lights[] = {3, 4, 5, 6, 7, 8};
    int count = sizeof(lights) / sizeof(lights[0]);

    for (int i = 0; i < count; i++){
        switch (state){

            case true: //turn on
                digitalWrite(lights[i], HIGH);
                break;

            case false: //turn off
                digitalWrite(lights[i], LOW);
                break;
        }
        //delay(1000); //optional delay between lights?
    }
}

I would like to simply address a forward procedure which would turn on
  pins 1, 2, 3, 4, 5, 6, 9, and 10.

And what about pins 7 and 8? You didn't say what to do with them in the
forward procedure. Should they be turned off? Should they stay in
whatever state they were before? I know it is kind of obvious to you,
but it doesn't hurt being specific, for the benefit of those lacking the
required background. Lacking a complete specification, we are left to
making assumptions.
kei, in his answer, assumed that any pin you did not mention should be
left alone, in whatever state it was before. In this answer I will
instead assume that you want to always control the 10 pins, turning
each of them either on or off.
With this assumption, the obvious solution is to have, for each
procedure, an array of 10 “states” (either HIGH or LOW), and loop
through the array setting each pin to its appropriate state:
for (int i = 0; i < LED_COUNT; i++)
    digitalWrite(led_pins[i], pattern[i]);

Here, pattern[i] is the state associated to led_pin[i] in this
specific procedure. Now, since all these pins are consecutive, you don't
need the led_pins array, and you can replace led_pins[i] by
i + FIRST_LED_PIN (i.e. i+1).
This way you can implement as many procedures as you want, each one
being defined as a simple 10-number array. I would add a single
function to activate any procedure. This function would take as an
argument a pointer to the light pattern you want to apply:
const uint8_t FIRST_LED_PIN = 1;
const int LED_COUNT = 10;
const uint8_t formward_pattern[LED_COUNT] = {
    HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, LOW,  LOW,  HIGH, HIGH
};
const uint8_t reverse_pattern[LED_COUNT] = {
    LOW,  LOW,  HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, LOW,  LOW
};

void set_led_pattern(const uint8_t *pattern)
{
    for (int i = 0; i < LED_COUNT; i++)
        digitalWrite(i + FIRST_LED_PIN, pattern[i]);
}

With this in place, you can set the light pattern of the forward
procedure by issuing the single statement:
set_led_pattern(formward_pattern);

and for the reverse procedure:
set_led_pattern(reverse_pattern);