text:
Stuttering motor using rf module
I am trying to control a stepper motor wirelessly with a button. I am using the 433MHZ rf module and the Virtualwire library.
the code is working, the receiver is getting the messages from the transmitter, but the problem is the messages are sent extremely slowly, so much so that the receiver circuit led is flashing on and off instead of staying in the on position when the transmitter button is being held down. consequently the stepper motor stutters instead of moving smoothly.
I have tried increasing the bits per second in the vw_setup but that just makes the led flash faster and not stay in the on position. it also makes the stepper vibrate more.
how do i make the stepper motor move smoothly wirelessly over rf?
transmitter code:
#include <VirtualWire.h>

int currentlocation = 0;
const int stepPin = 3;
const int dirPin = 4;
int active = 0;
const int ledPin =  13;      // the number of the LED pin
String dataout;
char buffer[1];
int idx=0;

class Button {

  public:

    int pin;
    int state;
    int location;
    int Speed;
    int Direction;
    int active;
    int prevstate;

    Button(int pin1, int state1, int location1, int active1, int previousState)
    {
      pin = pin1;
      state = state1;
      location = location1;
      active = active1;
      prevstate = previousState;
    }

    Button(int pin1, int state1, int speed1, int direction1)
    {
      pin = pin1;
      state = state1;
      Speed = speed1;
      Direction = direction1;
    }

    Show(){
      if (digitalRead(pin) == HIGH){
          digitalWrite(ledPin, HIGH);
          } else {
          // turn LED off:
          digitalWrite(ledPin, LOW);
          }
    }
};

Button button(7,0,0,0,0);
Button button2(8,0,30,0,0);
Button Movebutton1(5,0,500,HIGH);
Button Movebutton2(6,0,500,LOW);
Button buttons[2] = {button, button2};
Button Movebuttons[2] = {Movebutton1, Movebutton2};

void setup() {
      vw_setup(2000);
      pinMode(stepPin,OUTPUT);
      pinMode(dirPin,OUTPUT);
      pinMode(ledPin, OUTPUT);
      Serial.begin(9600);      // open the serial port at 9600 bps:
}

void loop() {
    for (int i = 0; i<2; i++){
      buttons[i].Show();
      if (digitalRead(buttons[i].pin) == HIGH){
      sprintf(buffer, "%d", i);
      vw_send((uint8_t *)buffer, strlen(buffer));
      vw_wait_tx();
      }
    }
    for (int i = 0; i<2; i++){
      Movebuttons[i].Show();
      if (digitalRead(Movebuttons[i].pin) == HIGH){
      sprintf(buffer, "%d", i+2);
      vw_send((uint8_t *)buffer, strlen(buffer));
      vw_wait_tx();
      }
    }
}

Receiver code:
#include <VirtualWire.h>

char message[VW_MAX_MESSAGE_LEN]; // a buffer to store the incoming messages
byte messageLength = VW_MAX_MESSAGE_LEN; // the size of the message
int last_idx = 0;

int currentlocation = 0;
const int stepPin = 3;
const int dirPin = 4;
int active = 0;
const int ledPin =  13;      // the number of the LED pin
String str_out;

class Button {

  public:

    int pin;
    int state;
    int location;
    int Speed;
    int Direction;
    int active;
    int prevstate;

    Button(int pin1, int state1, int location1, int active1, int previousState)
    {
      pin = pin1;
      state = state1;
      location = location1;
      active = active1;
      prevstate = previousState;
    }

    Button(int pin1, int state1, int speed1, int direction1)
    {
      pin = pin1;
      state = state1;
      Speed = speed1;
      Direction = direction1;
    }

    Relocate(){
      int shift = location - currentlocation;
      if (shift > 0){
        Direction = 0;
      }
      else{
        Direction = 1;
      }
      shift = abs(shift);
      digitalWrite(dirPin,Direction); // Enables the motor to move in a particular direction
      // Makes 200 pulses for making one full cycle rotation
      for(int x = 0; x < shift; x++) {
        digitalWrite(stepPin,HIGH);
        delayMicroseconds(500);
        digitalWrite(stepPin,LOW);
        delayMicroseconds(500);
      }
      currentlocation = location;
    }

    Move(){
      digitalWrite(dirPin,Direction); // Enables the motor to move in a particular direction
      // Makes 200 pulses for making one full cycle rotation
        digitalWrite(stepPin,HIGH);
        delayMicroseconds(Speed);
        digitalWrite(stepPin,LOW);
        delayMicroseconds(Speed);
      if (Direction == 1){
      currentlocation -= 1;
      }
      else{
      currentlocation += 1;
      }
    }

    Show(){
      if (vw_get_message(message, &messageLength)){
          digitalWrite(ledPin, HIGH);
          } else {
          // turn LED off:
          digitalWrite(ledPin, LOW);
          }
    }
};

Button button(7,0,0,0,0);
Button button2(8,0,30,0,0);
Button Movebutton1(5,0,500,HIGH);
Button Movebutton2(6,0,500,LOW);
Button buttons[2] = {button, button2};
Button Movebuttons[2] = {Movebutton1, Movebutton2};

void setup() {
        // Initialize the IO and ISR
      vw_setup(2000); // Bits per sec
      vw_rx_start(); // Start the receiver
      Serial.begin(9600);
      pinMode(stepPin,OUTPUT);
      pinMode(dirPin,OUTPUT);
      pinMode(ledPin, OUTPUT);
}

void loop() {

      // Set buffer to size of expected message
    if (vw_get_message(message, &messageLength)){
    int idx=atoi(message);
    Serial.print(message);
    for (int i = 0; i<2; i++){
      buttons[i].Show();
      if (idx == i){
      buttons[i].Relocate();
      active = i;
      //buttons[i].location = currentlocation;
      }
    }
    for (int i = 2; i<4; i++){
      Movebuttons[i-2].Show();
      if (idx == i){
      Movebuttons[i-2].Move();
      buttons[active].location = currentlocation;
      }
    }
    }
}

how do i make the motor move smoothly when i hold down the button wirelessly, how do i stop the jittering

what is the relationship between the button and the motor?  .... please provide a clear description of the expected behavior of the device

the button will cause the receiver to
    digitalWrite(stepPin,HIGH);
    delayMicroseconds(Speed);
    digitalWrite(stepPin,LOW);
    delayMicroseconds(Speed);

in other words, step the motor once

when held in the on position it will continue to step

press the button, hold for 5 seconds, then release ..... that requires only two messages to be sent 5 seconds apart ..... why should the motor stutter in between the two messages?

no i want to hold the button and send the on position while im holding it down

the motor is stuttering because the messages are stuttering

read my comment again and think about it

every  time the loop function executes it checks to see if the button is on right? so if the message is not getting there on time it assumes that it is off

A transmit bit rate of 2000 is normal. Some 433MHz modules can do 4kHz, but that should be specified and such specifications are hard to find. There is overhead, I'm guessing that one value takes about 20 to 25 pulses. By law the transmitter may only be busy for 10%. That results into sending data 8 times per second. Just 8 per second, no more.

What is the incoming message interval (1/incomingMessageFrequency)? Whenever the receiving end receives a "button-down" message, it should activate the motor for that interval + long enough to receive or not receive the next "button-down". Once the next "button-down" should have been received and has been missed, that's when you should stop the motor.


text:
Random artifacts on SSD1306 OLED screen
I'm having a really strange problem with my screen. It's connected in i2c to my Arduino Nano and I'm using a rotary encoder to navigate through a menu.
At startup everything is fine, but when I change menus a couple of times, there are flickering artifacts that start showing up in the bottom right corner. Did anyone ever get that kind of localized noise?
I thought maybe it would be my refresh rate that was a bit too high, I only had 10ms. But I cranked it up to 50 and it didn't change a thing.
https://youtu.be/riwLRgtHG0g
EDIT: Thank you for your feedback! I tried a different approach, like you suggested, and got rid of all the calls to displayMenu() and the multiple while loops. The artifacts are smaller now, but they're still there...
They used to occur all the time and now they're just appearing during chooseValue() and action3() now. As if it was linked to the "value" variable. I don't get it...
Here's the updated code:
#include <Arduino.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_I2CDevice.h>
#include <math.h>

#include <RotaryEncoder.h>
#include <ButtonStates.h>

#define SCREEN_WIDTH    128
#define SCREEN_HEIGHT   64
#define OLED_RESET      -1                                                  // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS  0x3C

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

RotaryEncoder encoder(A2, A3);                                              // Rotary encoder connected to A2 and A3
ButtonSwitch button(2);                                                     // Rotary encoder button

int value = 0;                                                              // Value changed in one of the menus
int selection = 0;                                                          // Encoder position

struct menuItem {                                                           // Structure defining a menu item
  const char *name;                                                         // Item name
  void (*action)();                                                         // Pointer pointing to the function handling the action
};

struct menu {                                                               // Structure defining a menu
  char *name;                                                               // Menu name
  int items;                                                                // Number of items in the menu
  struct menuItem *collection;                                              // Array containing all the menu items
};

struct menuItem menu1collection[5];                                         // Array for the menu
struct menuItem item1, item2, item3, item4, item5;                          // Items of the menu
struct menu menu1 = { "Today's menu", 5, menu1collection };                 // Structure holding all the menu's info

struct menuItem menu2collection[4];
struct menuItem item6, item7, item8, item9;
struct menu menu2 = { "Tomorrow's menu", 4, menu2collection };

struct menu currentmenu = menu1;

enum screens { MENU, CHOOSEVAL };
enum screens screen = MENU;

void chooseValue(){
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 20);
  display.write( 17 );
  display.setCursor(45, 20);
  display.print(selection);
  display.print("g");
  display.setCursor(115, 20);
  display.write( 16 );
  display.display();
}

void displayMenu(){                                                         // Function displaying the menu passed in argument
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 5);
  display.println(currentmenu.name);                                        // Display menu title

  int div = floor((selection-0.5)/4);                                       // Handle menus with more than 4 elements

  for(int i=(4*div+1), j=0 ; i<=currentmenu.items && j<4 ; i++, j++){       // Cycle through 4 menu items
    if(i==selection){                                                       // Highlight selected item
      display.fillRect(0, 18+10*j, 128, 10, SSD1306_WHITE);
      display.setCursor(20, 20+10*j);
      display.setTextColor(SSD1306_BLACK);
      display.println(currentmenu.collection[i-1].name);
    }
    else{
      display.setTextColor(SSD1306_WHITE);
      display.setCursor(20, 20+10*j);
      display.println(currentmenu.collection[i-1].name);                    // Display item
    }
  }
  display.display();
}

ISR(PCINT1_vect) {                                                          // Interrupt routine for the rotary encoder
  encoder.tick();                                                           // Check the state of the encoder
}

// Functions handling the actions for each menu item ------------------------------------------------------------------
void action1(){
  screen = CHOOSEVAL;
}

void action2(){
  currentmenu = menu2;
  encoder.setPosition(1);
}

void action3(){
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(45, 20);
  display.print(value);
  display.println("g");
  display.display();

  delay(1000);
}

void action4(){
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 20);
  display.println("Action 4!");
  display.display();

  delay(500);
}

void action5(){
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 20);
  display.println("Action 5!");
  display.display();

  delay(500);
}

void action6(){
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 20);
  display.println("Action 6!");
  display.display();

  delay(500);
}

void action7(){
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 20);
  display.println("Action 7!");
  display.display();

  delay(500);
}

void action8(){
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 20);
  display.println("Action 8!");
  display.display();

  delay(500);
}

void action9(){
  currentmenu = menu1;
  encoder.setPosition(1);
}
// -------------------------------------------------------------------------------------------------------------------

void handleMenu(){
}

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

  // Creating a menu requires the following ----------------------------------------------------------------------------
  item1.name = "Choose a value";
  item1.action = action1;
  menu1collection[0] = item1;

  item2.name = "Go to menu 2";
  item2.action = action2;
  menu1collection[1] = item2;

  item3.name = "Display value";
  item3.action = action3;
  menu1collection[2] = item3;

  item4.name = "Item 4";
  item4.action = action4;
  menu1collection[3] = item4;

  item5.name = "Item 5";
  item5.action = action5;
  menu1collection[4] = item5;

  item6.name = "Item 6";
  item6.action = action6;
  menu2collection[0] = item6;

  item7.name = "Item 7";
  item7.action = action7;
  menu2collection[1] = item7;

  item8.name = "Item 8";
  item8.action = action8;
  menu2collection[2] = item8;

  item9.name = "< Back";
  item9.action = action9;
  menu2collection[3] = item9;
  // -------------------------------------------------------------------------------------------------------------------

  PCICR |= (1 << PCIE1);                                                  // This enables Pin Change Interrupt 1 that covers the Analog input pins or Port C.
  PCMSK1 |= (1 << PCINT10) | (1 << PCINT11);                              // This enables the interrupt for pin 2 and 3 of Port C.

  if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {              // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);                                                              // Don't proceed, loop forever
  }

  // Init display
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 20);
  display.println("Loading...");
  display.display();

  delay(500);
}

void loop() {
  switch(screen){
    case MENU:
      selection = encoder.getPosition();                                      // Get the encoder's position

      if (selection < 1) {                                                    // Stop the encoder on the min position
        encoder.setPosition(1);
        selection = 1;

      } else if (selection > currentmenu.items) {                             // Stop the encoder on the max position (number of items minus 1)
        encoder.setPosition(currentmenu.items);
        selection = currentmenu.items;
      }

      displayMenu();

      if (button.triggerSingle()){
        currentmenu.collection[selection-1].action();                         // If a click is detected do the item's action
      }
      break;
    case CHOOSEVAL:
      selection = value + encoder.getPosition() * 10;

      if (selection < 1) {                                                    // Stop the encoder on the min position
        encoder.setPosition(1);
        selection = 1;
      }

      chooseValue();

      if (button.triggerSingle()){
        value = selection;
        encoder.setPosition(1);
        screen = MENU;
      }
      break;
  }
}

You called the displayMenu method at all over the program and  recursive in itself. Why? Also, you use an eternal while (1) { in the display method. I suggest to remove the 'while(1)' loop. The only call to displayMenu that make sense, is the one in the loop() method. remove all others. I would also copy the code that starts actions from the display to the loop. Don't use delay() in the display method that stops the whole system. Use millis() (the example Blinlking LED without Delay shows you how.

Remove the while from the chooseValue method too.  Then move it to the loop function. I'm not sure I have seen all problems, but that would be a good start. If it does not hel, edit the question wit the new observations.

It looks to me like your stack is smashing into your heap.

Thanks for your feedback @PeterPaulKiefer! I updated my code in the original post.

I don't get the reference @Majenko, what do you mean?

The fact that the corruption is in the bottom right means it's at the end of the screen buffer. That will be (one of) the last thing on the heap. The stack is above the heap and grows down into it. Too many nested function calls and local variables will cause the stack to grow downwards until it overlaps with the heap, and the end of your screen buffer, corrupting the screen buffer in the bottom right of the screen. Flatten your program. Reduce RAM usage.

Ooh right! Jeez, I just turned all "ints" into "uint8_t" and it's almost gone. I think maybe my strings might take up a lot of memory. How can I optimize this? I mean, I'm used to JavaScript handling those... and here I don't know how to make it flexible and usable at the same time.

Where is ButtonStates.h from? As Majenko said, you are getting very close memory exhaustion.  I wasn't able to actually detect that that is actually happening but then I wasn't running your exact code.  Ultimately whatever the cause you may want to switch to something like u8g2 to avoid the 1kbyte malloc that the Adafruit library is doing.  So far as I can tell, you have about 130 bytes left when running your originally posted code.

For a start use F(...) around all string literals in print(...) calls and such.

ButtonStates is a library I've written to debounce buttons and recognize double clicks and long clicks. You can find it on platformio. It should be quite low consuming in RAM though. It would seem the artifacts are gone now, but I will try u8g2 in a future version! Many thanks!!

This is a solution that I accidentally came up with. I had a problem of strange artifacts corruption in bottom right corner of my SSD1306 display when I tried to print scrolled row of text.
It does its job, so if anyone come by this topic in the future feel free to test it:
int x, minX;
oled_dispMidTextScroll(F("SETPOINT REACHED! LONG PRESS LEFT TO SET UP A TIMER"));

void oled_dispMidTextScroll(String str){
  char text[50];
  int size = 1;
  str.toCharArray(text, 50);
  display.setTextSize(size);
  minX = (-1 * size * 6) * strlen(text);  // 12 = 6 (px/char) * 2 (textsize)
  display.setCursor(x,28);
  display.print(text);
  x -= 4; // speed
  if (x < minX) {x = display.width();}
}

source: Stack Exchange

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

sort: votes


text:
Oscillating Output from Arduino Pins when not in use, why?
I have A1 set to be an input, have the program read it, and then print to the serial monitor. My question is, when the circuit is not receiving power, but is grounded, and is still connected to A1, when do I see an output pattern of, for example:
0,0,0,0,7,23,16,9,4,0,0,0,0,3,18,21,15,0,0,0.....

I have a different detector inputing to A0 and if I don't have A1 connected then I get a reading that is similar to what I would see if I was actually reading A0 (around 900). Then if I plug back into A1 the value drops to around 350. When A0 is unplugged and only A1 is plugged in I only get noise (ie the pattern above in the code section).

Looks like the input pin is 'floating', picking up stray signals from the air. Do the numbers go higher as you move your hard closer, and decrease as you move farther?

looks like a sine wave to me, maybe AC coupling? Drawing current on the connected module could also pull up the ground, like seen on a shunt resistor.

@dandavis what can I do to prevent this?

@VE7JRO that's not exactly what I'm getting at, but thanks for the thought

I'm thinking along the same lines as CrossRoads and dandavis above. Would you be able to post a circuit diagram? If you haven't grounded the input, it could be floating or picking up noise from the surrounding environment. A 5k pulldown resistor may fix the problem, depending on what your circuit looks like and the environment its in.

. Please for give me for any breach of standard practice, MechE by training haha

any thoughts @SirBagels?

@RyanB Without knowing more about what your'e trying to do with that circuit, it's hard to tell. The first thing I noticed was the 3M resistors, it seems pretty large. What caused you to pick that value? 5V/3M is approx 1.5uA. It doesn't take a ton of current to hit the high side of your Analog input. Try a few smaller values, 100k, 10k, etc. and see how that affects your results. I'd guess your're picking up noise from somewhere and the 3M resistor is kicking that into a readable voltage.

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


text:
What type of Arduino to buy
I am doing a project for school to run 462 LEDs in 6 series (77 each) and a stepper motor altogether, I wanna know what model of Arduino I should buy (not so expensive)?
I am using individually addressable WS2812B RGB LED strips ...
So it should be controlled in 6 groups of 77 LEDs in each group.

Are the LEDs build into a strip or just simple LEDs? If the former: What type of strip/LEDs to you have? Should every LED be controlled individually or together in groups?

Can you give more details. It is hard to recommend a board with so little details.

With these requirements you can use most available Arduinos. The WS2812 LED strips need 1 pin per strip (or 1 pin in total, if you daisy-chain all the strips, meaning connecting the data lines of them to one big strip). How many pins you need for the stepper motor depends on the type of motor and what type of driver you have for it. Most stepper drivers need 2 digital pins from your Arduino (1 direction pin and 1 pulse pin). There are also cheap drivers based on the ULN2003 chip, where you have to control the phases directly, needing 4 pins.
You should also buy an Arduino, that leaves you a big headroom to develop your project further, if you want.
An Arduino Uno or Nano would be good fitting for this project (though smaller Arduinos like the Pro Micro also would work). If you are able to order them over sites like Aliexpress directly from china (and if you are ok with a longer shipping time), you can get Nanos for 1 - 2$.

Since you have many LEDs, you really have to consider your power supply. 462 LEDs, which need up to 60mA each (20mA for each colour in full brightness), means you need at least a 28A power supply (in total). And don't draw the LED current through the Arduino, or you will fry it's voltage regulator or diode.

I corrected the needed current for the supply XD 28A instead of 2,8A

And you might want to look at this guide from Adafruit. It describes, how you use the WS2812 LEDs and what you have to consider.

I need two pins for stepper Nema 17, and the driver is DRV8825 Stepper Driver ...

The power supply is old pc power supply Model LPG12 550W ATX Computer Power Supply Desktop PC

I don't know, if this computer power supply can give you enough current. Source it's datasheet for the current, that you can get out of the 5V pins. 28A is a lot. Be sure to use cables, that are big enough, or they will melt from the current.

Take care about timing issues such that stepper motor and WS2812 don't interfere.

If that's only 6 on/off (or even fading) LED groups (no RGB-color led stripes) and one stepper motor, any Arduino (Uno / Nano) would do. There are clones, even cheaper than the original.
The peripheral electronics:

Motor driver
Transistors to switch the LED (77 standard LED need 1.5 A, so you have to search for Logic Level MOSFET transistors)

are as expensive as the controller itself,
... and wiring all those LEDs is the hardest work.

The LEDs are WS2812B strips, meaning that you don't need transistors to switch them. The WS2812B is actually the driver chip of each RGB LED in that strip and already consists the needed transistors. You only need to connect the data line to the Arduino

the 6* 77 is because of the design.


text:
Trouble with reading Bitmaps from SD-Card
I'm having problems with reading a bitmap file with the SD library.
I wrote a small header that reads uncompressed 24-bit bitmap files. It works fine when I try it on Windows 10 MingW with fread() instead of SD.read().
On my UNO it only reads the correct offset address, the other parts are garbage.
For a pure red 1x1 px bitmap I get the following expected output on Windows with MingW:
Fname: ..\rot.bmp
Offset: 00000036
W * H: 1 * 1
Bit# 24
Cmp: 0
ArraySize: 1
---------------------------
RGB: ff0000

Arduino outputs:
Fname: rot.bmp
Offset: 00000036
W * H: 0 * 2304
Bit# 58
Cmp: 0
ArraySize: 8
---------------------------
Error while reading BMP file

bmp.hpp
#ifndef BMP_HEADER
#define BMP_HEADER

#if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_MEGA)
#include <SD.h>
#include<stdint.h>
#define BYTE uint8_t
#define WORD uint16_t
#define DWORD uint32_t
#define LONG int32_t
#else
#include<stdlib.h>
#include<windows.h>
#endif // defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_MEGA)
#pragma pack(2)
typedef struct
{
  BYTE B;
  BYTE G;
  BYTE R;
} pixel;

typedef struct
{
  WORD bfType;
  DWORD bfSize;
  DWORD bfReserved;
  DWORD bfOffset; //offset to byte array
} bfheader;

typedef struct
{
  DWORD biSize; //size of this header
  LONG biWidth; //image width
  LONG biHeight;//image height
  WORD biPlanes;
  WORD biBitCount; //color depth in bit per pixel
  DWORD biCompression; //0 for none(RGB mode)
  DWORD biSizeImage; //size of image in byte; may be 0 if biCompression is RGB
  LONG biXPelsPerMeter;
  LONG biYPelsPerMeter;
  DWORD biClrUsed; //palete stuff
  DWORD biClrImportant; //more palete stuff
} biheader;

//returns BGR array of bitmap
//header and biheader are assumed to be allocated upon execution
//returns null if unsuccessful
inline pixel* readBMP(const char* filename, bfheader* header, biheader* infoheader)
{
    #if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_MEGA)
    SDLib::File f = SD.open(filename);
    if(!f) return NULL;
    f.read((uint8_t *)header, sizeof(bfheader)); // read the 14-byte file header
    f.read((uint8_t *)infoheader, sizeof(biheader)); //read the 40-byte info header
    #else
    FILE* f = fopen(filename, "rb");
    if(f == NULL) return NULL;
    fread(header, sizeof(bfheader), 1, f);
    fread(infoheader, sizeof(biheader), 1, f);
    #endif //defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_MEGA)
  if(infoheader->biCompression != 0 || infoheader->biBitCount != 24) //if the file is not RGB encoded or if its not 24bit
  {
    #if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_MEGA)
    f.close();
    #else
    fclose(f);
    #endif // defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_MEGA)
    return NULL;
  }
  int size = (int) infoheader->biSizeImage/sizeof(pixel); //get byte size of pixel array
  pixel* data = (pixel*) malloc(sizeof(pixel)*size); // allocate
  #if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_MEGA)
    f.seek(header->bfOffset); //set file cursor to starting address of RGB array
    f.read((uint8_t *)data, sizeof(uint8_t)*size); // read the rest of the data at once
    f.close();
  #else
    fseek(f, header->bfOffset, SEEK_SET);
    fread(data, sizeof(pixel), size, f);
    fclose(f);
  #endif //__arm__
  return data;
}
#endif //BMP_HEADER

readbmp_test.ino
#include<arduino.h>
#include <SPI.h>
#include "bmp.hpp"

void setup() {
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  Serial.print("Initializing SD card...");

  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");
}

void loop()
{
  char debug[160];
  char rgbdata[8];
  const char* const files[] = {"rot.bmp", "gruen.bmp", "blau.bmp"};
  int files_len = 3;
  bfheader header;
  biheader infoheader;
  pixel* image;
  for(int i=0; i<files_len; i++)
  {
    image = readBMP(files[i], &header, &infoheader);
    Serial.println("----------------------------");
    sprintf(debug,  "Fname: %s\n"
                "Offset: %08lx\n"
                "W * H: %ld * %ld\n"
                "Bit# %u\n"
                "Cmp: %lu\n"
                "ArraySize: %lu\n"
                "---------------------------\n",
                  files[i],
                  header.bfOffset,
                  infoheader.biWidth, infoheader.biHeight,
                  infoheader.biBitCount,
                  infoheader.biCompression,
                  infoheader.biSizeImage/sizeof(pixel));
    Serial.print(debug);
    if(image != NULL)
    {

      for(unsigned j=0; j<infoheader.biSizeImage/sizeof(pixel); j++)
      {
        sprintf(rgbdata, "%02x %02x %02x", image[j].R, image[j].G, image[j].B);
        Serial.println(rgbdata);
      }
    }else{
        sprintf(debug, "Error while reading BMP file\n");
        Serial.print(debug);
    }
    free(image);
  }
}

main.cpp //MingW Windows Test
#if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_MEGA)  //arduino compiler wants to run this main?
#else
#include<stdio.h>
#include "bmp.hpp"

int main(const int argc, const char** argv)
{
    if(argc < 2) return -1;

    bfheader header;
    biheader infoheader;
    for(int i=1; i<argc; i++)
    {
        pixel* image = readBMP(argv[i], &header, &infoheader);
        if(image != NULL)
        {
            printf("Fname: %s\n"
                    "Offset: %08x\n"
                    "W * H: %d * %d\n"
                    "Bit# %d\n"
                    "Cmp: %d\n"
                    "ArraySize: %d\n"
                    "---------------------------\n",
                    argv[i],
                    header.bfOffset,
                    infoheader.biWidth, infoheader.biHeight,
                    infoheader.biBitCount,
                    infoheader.biCompression,
                    infoheader.biSizeImage/sizeof(pixel));
            for(int j=0; j<infoheader.biSizeImage/sizeof(pixel); j++)
            {
                printf("RGB: %02x%02x%02x\n", image[j].R, image[j].G, image[j].B);
            }
        }else{
                printf("Error while reading BMP file\n");
                return 1;
        }
        free(image);
    }
    return 0;
}
#endif

I'm really stuck on this, I actually rewrote it a couple times already.
I would really appreciate some help.

print out the number of bytes read with file.read (return value). try to use readBytes instead of read if the count of read bytes doesn't match the expected size

@Juraj I tried with with readBytes and read. Same result: The first read returns the expected 14 bytes. The second only returns 2 instead of the expected 40.

print the structure as bytes with println(b, HEX), to see the raw bytes to check their position in struct fields

How would I do so? Serial.println(*infoheader, HEX); results in 'HardwareSerial::println(biheader&, int)'

I tried  withfor(int i=0; i<sizeof(biheader); i++) The output seems to match the hex dump of the file. I put a a hexdump of the bitmap and the output on Pastebin

it could be a problem of printf. you have %d and that reads only two bytes on Arduino. print the values without sprintf as Serial.println(number)

Hint: Start by correcting the header read. The sizeof is wrong. Use sizeof the struct and not the pointer. Use the same sizeof for both variants.

@MikaelPatel thanks for your input. I fixed that part, but I still have problems.

@Juraj Your tipp with the sprintf was pretty good. I turned on all warnings during compile and saw that the datatypes didn't match the format strings. I fixed that and now my header information is displayed correctly. There is sadly still a problem left as the pure red bitmap displays false pixel values: sprintf(rgbdata, "%02x %02x %02x", image[j].R, image[j].G, image[j].B);         Serial.println(rgbdata); displays: c5 00 00 dispite the bitmap not containing C5 at all.

f.read((uint8_t *)infoheader, sizeof(infoheader));
should be
f.read((uint8_t *)infoheader, sizeof(biheader));
the size of the variable (pointer) is only 2. you want to read 40 bytes of biheader struct
and
f.read((uint8_t *)data, sizeof(uint8_t)*size)
should be
f.read((uint8_t *)data, sizeof(pixel)*size)

The next problem is %d and %x in sprintf. %d and %x read two bytes on Arduino, not 4, not 1. Print the values without sprintf as Serial.println(number)

Oh wow, thanks for pointing that out. It reads the expected amount of bytes. However he output is still wrong. Fname: rot.bmp
Offset: 00000036
W * H: 0 * 1
Bit# 0
Cmp: 1
ArraySize: 0

Hey @juraj I answered on your comment on the main post.

Hey @Juraj, I modified the format string so the correct datatype is expected, lu for uint32_t etc. For the header that works fine now. Pixeldata is still wrong. I followed your advise and tried displaying the Pixeldata using raw Serial.print. Problem still persists. `Fname: rot.bmp
Offset: 00000036
W * H: 1 * 1
Bit# 24
Cmp: 0
ArraySize: 1
58 0 0` is my current output

@MatC, did it help?


text:
Milliseconds using square wave RTC
i am trying to make a code that prints the time hh:mm:ss:ms using RTC,i have made it using millis() but it  is not accurate +/-2 milliseconds
ho can i make it using sq wave and intterupt
here is the code that i have used
#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 RTC;      // This is the DS1307 hardware RTC
RTC_Millis SoftRTC;   // This is the millis()-based software RTC
long startMS;  // This will hold the start time in milliseconds

void setup ()
{
    Wire.begin();
    RTC.begin();                       // Connect to the DS1307
    SoftRTC.begin(RTC.now());  // Initialize SoftRTC to the current time
    startMS = millis();  // get the current millisecond count
}

void loop()
{
    DateTime now = SoftRTC.now();
    long nowMS = millis();

    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.print(':');
    Serial.print((nowMS - startMS)%1000, DEC);  // print milliseconds
    Serial.println();

i tried to put this code that is based on ISR but with no luck
volatile time_t isrUTC;         // ISR's copy of current time in UTC
volatile time_t millisecondsFromISR;         // ISR's copy of current time millisecond offset

void incrementTime()
{
    millisecondsFromISR = millis();  //do first to get most accuracy
    ++isrUTC;
}

int getMilliseconds() {
    // need to make an atomic copy:
    nointerrupts();
    unsigned long t = millisecondsFromISR;
    interrupts();

    return millis() - t;
}

what is not accurate +/-2 milliseconds? ... the prints the time hh:mm:ss:ms takes time to execute

so if i make it with external clock will it make a diff?

You cannot get better than ±2 ms with millis(). If you need more accuracy, use micros().

same code
or what do u suggest?

All you have to do is record the number of milliseconds at the moment the square wave toggles on its 1 second cycle. Then your milliseconds is the difference between that and the current.
In short: update startMS when triggered by the RTC's output.

do u have a helping code?

@AmrAhmed no, but you already have code to set startms in your program, and there are plenty of interrupt examples on the web.

yes i have checked these codes for interrupt with no luck  to make a running code

@AmrAhmed Then maybe you should try again, and then show us what you tried, and we may be able to help you with it.

volatile time_t isrUTC;         // ISR's copy of current time in UTC
volatile time_t millisecondsFromISR;         // ISR's copy of current time millisecond offset
...
void incrementTime()
{
millisecondsFromISR = millis();  //do first to get most accuracy
++isrUTC;
}
...
int getMilliseconds() {
// need to make an atomic copy:
nointerrupts();
unsigned long t = millisecondsFromISR;
interrupts();
return millis() - t;

}
this one of the codes that i tried to work on with no luck

@AmrAhmed Comments are not for code.

i have added the code in my question

And what didn't work with it? How is that code snippet integrated with the rest of your code?

i could not make it working

Without seeing how that snippet is integrated with the rest of your code, or how the RTC module is wired up, we cannot help/.

unfortunately this what i got when i tried to integrate both


text:
connection of led with dht and code combination
Hi again? I saw my last question did not come out well, so let me rephrase it.
Ideally, my project is composed of 3 sensors: 2 dht-22 sensors and an mq-7 sensor.
For the dht22 sensors, I am using data pin connections 9 and 10 PWM on the Arduino mega 2560 board with their respective 10 kilo-ohm resistors, with 5v supply and ground connections.
The issue is that I want to set limits for both temperature and humidity for both sensors to be:  (16

#include "DHT.h"

#define DHT1PIN 9     // what pin we're connected to
#define DHT2PIN 10

#define DHT1TYPE DHT22
#define DHT2TYPE DHT22

// Connect pin 1 (on the left) of the sensor to +5V
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

DHT dht1(DHT1PIN, DHT1TYPE);
DHT dht2(DHT2PIN, DHT2TYPE);

void setup() {
  Serial.begin(115200);
  Serial.println("DHTxx test!");

  dht1.begin();
  dht2.begin();
}

void loop() {
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h1 = dht1.readHumidity();
  float t1 = dht1.readTemperature();
  float h2 = dht2.readHumidity();
  float t2 = dht2.readTemperature();

  // check if returns are valid, if they are NaN (not a number) then something went wrong!
  if (isnan(t1) || isnan(h1)) {
    Serial.println("Failed to read from DHT #1");
  } else {
    Serial.print("Humidity 1: ");
    Serial.print(h1);
    Serial.print(" %\t");
    Serial.print("Temperature 1: ");
    Serial.print(t1);
    Serial.println(" *C");
  }
  if (isnan(t2) || isnan(h2)) {
    Serial.println("Failed to read from DHT #2");
  } else {
    Serial.print("Humidity 2: ");
    Serial.print(h2);
    Serial.print(" %\t");
    Serial.print("Temperature 2: ");
    Serial.print(t2);
    Serial.println(" *C");
  }
  Serial.println();
}

Ps: LEDs used are 10mm.
For the MQ-7 sensor, this is it's code.
/* MQ-7 Carbon Monoxide Sensor Circuit with Arduino */

 const int AOUTpin=0;//the AOUT pin of the CO sensor goes into analog pin A0 of the arduino
 const int DOUTpin=8;//the DOUT pin of the CO sensor goes into digital pin D8 of the arduino
 const int ledPin=13;//the anode of the LED connects to digital pin D13 of the arduino

 int limit;
 int value;

 void setup() {
 Serial.begin(115200);//sets the baud rate
 pinMode(DOUTpin, INPUT);//sets the pin as an input to the arduino
 pinMode(ledPin, OUTPUT);//sets the pin as an output of the arduino
 }

 void loop()
 {
 value= analogRead(AOUTpin);//reads the analaog value from the CO sensor's AOUT pin
 limit= digitalRead(DOUTpin);//reads the digital value from the CO sensor's DOUT pin
 Serial.print("CO value: ");
 Serial.println(value);//prints the CO value
 Serial.print("Limit: ");
 Serial.print(limit);//prints the limit reached as either LOW or HIGH (above or underneath)
 delay(100);
 if (limit == HIGH){
 digitalWrite(ledPin, HIGH);//if limit has been reached, LED turns on as status indicator
 }
 else{
 digitalWrite(ledPin, LOW);//if threshold not reached, LED remains off
 }
 }

I am yet to buy a relay circuit to be able to connect it with the circuit using a , but for now I would appreciate it the scenarios highlighted for the sensors could be addressed and also, how the two codes could be combined to be one single code.
If there is any question, feel free to ask.
The project is for silo monitoring and control.

Only thing that gives people problems when combining two simple sketches are "delay" commands. There is just one "delay" so it's perfect.

Create new sketch
Paste everything that's not in a method from the two sketches.
Combine setup methods together by pasting first one and second one below.
Remove duplicated commands like Serial.begin(115200); from the method
Combine loop methods together by pasting first one and second one below.
Move code in loop to make the code visually pleasing (it's called the "smell" of code)

This should not be a big problem with those two particular sketches.
Please ask more precise questions as soon as you will have problems.


text:
Arduino Uno - temperature sensor DS18B20 not responding
I try to use a new DS18B20+ temperature sensor (sealed water proof version).
It doesn't work. My own code doesn't work, examples from DallasTemperature Library don't work, example from OneWire library doesn't work.
For example function sensors.getDeviceCount(); (DallasTemperature library) returns '0'.
Function tempSensor.getTempCByIndex(0); returns 65409 (int variable). !ds.search(addr) (OneWire library) also always return '0'. Then I am sure, Arduino code is alright.
I am sure DS18B20 is connected correctly:

white wire (onewire data) - onewire Arduino pin (tested with pin 2 and pin 13)
red wire (+V) - 5V Arduino pin
black wire (GND) - GND Arduinp pin
between 5V and DATA there is a 4k7 resistor

I have measured resistances between the temperature sensor's wires:

'+V' to 'data': 4,7 kOhm
'GND' to 'data': ~3 Ohm

I think between the GND and DATA sensor wires resistance should be much higher - am I right? Below you can see a block diagram copied from the sensor datasheet (https://datasheets.maximintegrated.com/en/ds/DS18B20.pdf):

Maybe black and white wires are +V and GND (which one is +V?), red is data? Or it's broken? Or something else?
I have bought it here - https://botland.com.pl/pl/czujniki-temperatury/10936-sonda-wodoodporna-z-czujnikiem-temperatury-ds18b20-5m-brazowy-silikon.html?search_query=sonda+temperatury&results=43 (language: polish). it is written:

VCC - red
GND - black or green
data 1-wire - white or yellow

between 5V and GND there is a 4k7 resistor the diagram tells you to pullup the data line (DQ) to V_PU (5V), not between 5V and ground. That is just a power dissipator.

Yes, sorry, it was a typo. 4k7 is between the data and +V.

Can you verify the meaning of the wire colors according to the package information of the datasheet? All the "DS18B20+" I see on e.g. digikey don't have color-coded wires on them. Do you have a link to where you bought them?

First post edited (added a link where I bought it)

Did you try to use the code in https://botland.com.pl/pl/content/134-arduino-w-polaczeniu-z-czujnikiem-temperatury-ds18b20? Did you, for the fun of it, remove the 4k7 resistor between DQ and VCC and see if that works?

It's a code copied from OneWire library example ('DS18x20_Temperature' example). I have tested it. I havn't removed pull-up resistor, it's a OneWire interface, I think it won't work without pull-upped data line. Is 'GND' to 'data': ~3 Ohm resistance normal? Look, between GND and DATA is a capacitor (DS18B20 block diagram).

If you measure 3 Ohms then there is a short between the wires. The sensor is bad.

When you test the sensor with nothing connected, is the resistance between the red and white wire the same in both directions? Does it change when the temperature changes? Perhaps there is an other temperature sensor inside. But it is probably a shortcut as @Rudy wrote.

Jot, no, it does not. I think thermistor would have higher resistance than 3 Ohm (~23oC).

Yes, thermistors have much higher resistance. Have you measured the resistance in the correct direction? A protection diode might produce a missleading measurement. Otherwise I'd say, your sensor is broke


text:
Arduino Uno: external power supply +5V and serial communication with pc over USB
I have connected to my Arduino Uno outputs relay module. Relay module has 16 relays (5VDC) which are controlled by transoptors pins (HIGH from Arduino = specific relay is off).
Link to relay module (lang: polish): https://botland.com.pl/pl/przekazniki/6940-modul-przekaznikow-16-kanalow-z-optoizolacja-styki-7a240vac-cewka-5v.html?search_query=modul+przekazniko&results=75 (SRD-05VDC-SL-C relays).
Arduino is supplied by +5V pin and GND pins with external power supply MDR-5-10. Relay module is supplied with the same power supply.
I control Arduino from PC using serial communication over USB (I send a command eg. 1;1;1;1;1;1;, then 6 outputs goes to HIGH). And now there is a problem. When I disconnect relay module control pins from Arduino outputs everything works fine. But when it is connected, I get serial com. error "device not found" (after some switches: sometimes it works for about 20 output switches, sometimes for 1 output switch) and I have to open serial communication again. Probably error appears only when I'm switching outputs.
I think the problem is because my external power supply +5V drops for a while when switching and then Arduino switches to +5V from USB (which doesn't drop), which has not enough power and then error occurs.
Am I right? Any suggestions to fix the problem?
EDIT #1:
Thank you for help. Answers:
@Jot, after disconnecting +5V Arduino pin, but with connected relay module, I get serial error immediately with first relay switch. If i dosconnect both +5V pin and relay module control pin, my application works fine.
My wires: external power supply - Arduino: 0,5 mm2; Arduino - relay module control pins: 23 AWG (~0,25 mm2); external power supply - relay module +5V and GND: 1,5 mm2. It flows through relays: 24VDC <30W or 230VAC ~20mA.
@CrossRoads, no I use A0-A4 and Q3-Q12 (for relay module: Q3-Q7, Q9-Q11, Q13).
@Duncan C: Currently, I use only 9 relays, other control pins are disconnected and off. Here - http://botland.com.pl/index.php?controller=attachment&id_attachment=244 (power consumption per relay - 0,36W 5VDC) - you can see relay datasheet. Relays are isolated from Arduino with opto-isolators (signal HIGH from Arduino = relay is off).
I never switch them all at once. In specific function I never use more then 5 relays together.
@Majenko, thank you, I'll give it a try in Tuesday!
Further informations:

Probably problems occur more often when I connect wires to relays pins (I use them all as NO: 7x 30W 24VDC - coils, 2x 230VAC ~20mA - contactor).
Serial communication error can occur during both reading or writing to serial.

2A output should be more than enough. You can try adding a large electrolytic capacitor across the 5V and GND pins on the Arduino though to see if that helps.

The arduino uno does not switch between the power supplies. Everything stays connected. Only when the barrel jack or the vin pin is used, then the usb power is switched off at about 7.5v. What happens if you disconnect the relay module and keep the gnd connected (arduino gnd to relay module gnd to external power gnd)? How thin are the wires that you use from the external power supply and between the arduino and the relay module?

Do you have D0, D1 connected to the relay module? If so, try using two other pins instead.

I can't make much sense of the Polish language specs on that relay module. What's the max current the relay module will draw? 16 relays are likely to use a WHOLE LOT of current if you activate them all at once. I thought I remembered each relay in mine as drawing about .2 amps, so 16 relays would be 3.2 amps.

I have a similar rig using a 4-channel optically isolated relay, but I use different power supplies for the Arduino and for the relay. (It works perfectly.) My guess is that the relays are causing the voltage on your arduino to droop when they switch on. I suggest using separate power supplies.
As @Majenko suggests, you might try adding a filtering cap (capacitor) between +5V and ground very near the Arduino. The cap should slow the drop in voltage to the Arduino long enough for the power supply to recover, but separate power supplies is the surest fix.


text:
Converting code for ATTINY85 to ATMEGA2560. Pin change interupts
I have code that compiles correctly for an ATTINY85 board using the ARDUINO IDE but I don't have an ATTINY85 board. I have an Arduino Mega ATMEGA2560 and when I select this board in the Arduino IDE the code does not compile and throws this error message
sketch_feb21a:216:3: error: 'GIMSK' was not declared in this scope

   GIMSK |= _BV(PCIE);                     // Enable Pin Change Interrupts

   ^

sketch_feb21a:216:16: error: 'PCIE' was not declared in this scope

   GIMSK |= _BV(PCIE);                     // Enable Pin Change Interrupts

                ^

sketch_feb21a:217:3: error: 'PCMSK' was not declared in this scope

   PCMSK |= _BV(PCINT2);                   // Use PB3 as interrupt pin

   ^

exit status 1
'GIMSK' was not declared in this scope

Here is the code snippet that throws the error
void sleep()
{
  GIMSK |= _BV(PCIE);                     // Enable Pin Change Interrupts
  PCMSK |= _BV(PCINT2);                   // Use PB3 as interrupt pin
  ADCSRA &= ~_BV(ADEN);                   // ADC off
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);    // replaces above statement

  MCUCR &= ~_BV(ISC01);
  MCUCR &= ~_BV(ISC00);       // Interrupt on rising edge
  sleep_enable();                         // Sets the Sleep Enable bit in the MCUCR Register (SE BIT)
  sei();                                  // Enable interrupts
  sleep_cpu();                            // sleep

  cli();                                  // Disable interrupts
  PCMSK &= ~_BV(PCINT2);                  // Turn off PB3 as interrupt pin
  sleep_disable();                        // Clear SE bit
  ADCSRA |= _BV(ADEN);                    // ADC on

  sei();                                  // Enable interrupts
}

ISR(PCINT0_vect) {
   /*noInterrupts();
   while (digitalRead(BUTTON_PIN) == LOW);

   delay(50);
   while (digitalRead(BUTTON_PIN) == LOW);
   playTrack(1 + (curTrack++ % 2));
   delay(400);

   interrupts();*/

}

Do you have a arduino atmega 2560 board? why do you want to put that into sleep mode?

Each processor has different registers, things that control stuff like interrupts, input and output. I would not expect code written for one processor, especially if it directly accesses the registers, to work on another processor.
You would need to look at the datasheet for the Atmega2560 and see how to control its pin change interrupts.

I have been looking at datasheets for both but I am just having trouble understanding what to change in order to make it work correctly.


text:
Electric meter with Arduino and RS485 module
I'm a Arduino newbie. I have an Electric meter with an RS485 output. I want to get the MeterID value over the RS485 module and the Arduino. I just have document from manufacturer.
Sent by computer : 68 99 99 99 99 99 99 68 01 02 67 F3 C3 16.
Return from meter : FE 68 99 99 99 99 99 99 68 81 08 67 F3 A6 9B 34 4B 33 33 6F 16.

My Arduino code:
#include <SoftwareSerial.h>

#define SSerialRX        10
#define SSerialTX        11
#define SSerialTxControl 3
#define RS485Transmit    HIGH
#define RS485Receive     LOW

SoftwareSerial RS485Serial(SSerialRX, SSerialTX);
byte request[] = {0x68, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x68, 0x01, 0x02, 0x67, 0xF3, 0xC3, 0x16};
int byteRead;

void setup()
{
  Serial.begin(9600);
  RS485Serial.begin(1200);
  pinMode(SSerialTxControl, OUTPUT);
  digitalWrite(SSerialTxControl, RS485Receive);
  delay(20);
  Serial.println("Get Meter Address App");
}
void loop()
{
  digitalWrite(SSerialTxControl, RS485Transmit);
  RS485Serial.write(request, sizeof(request));
  delay(2000);
  digitalWrite(SSerialTxControl, RS485Receive);
  delay(2000);
  if (RS485Serial.available())
  {
    byteRead = RS485Serial.read();
    Serial.println(byteRead, HEX);
  }
}

Serial Monitor show:

I'm using combo like this topic modbus-rtu-controller-monitoring-with-arduino-and-rs485-module. My code is in C# below. I used the code before and it worked fine, but on the computer I use a COM port (Baudrate 1200, data 8bits, Parity EVEN, Stopbit 1) with an RS485-R232 converter:
#Send data
dataOUT = WriteData("68 99 99 99 99 99 99 68 01 02 67 F3 C3 16");
serialPort_Meter.Write(dataOUT, 0, dataOUT.Length);

#WriteData method
private static byte[] WriteData(string hex)
{
return hex.Split(' ').Select(s => Convert.ToByte(s, 16)).ToArray();
}

#Read data
private static string ReadData(SerialPort serial)
{
byte[] buffer = new byte[serial.BytesToRead];
serial.Read(buffer, 0, buffer.Length);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < buffer.Length; i++)
sb.AppendFormat("{0:X2} ", buffer[i]);
return sb.ToString();
}

you don't have delays in C#. why do you have delays in Arduino?

It's still blank

with delay you missed the data. without delay you check too early

Please advise me

Hi Cosi Nguyen. Can you share some details about the electric meter you are trying out this with? Even the document you are referring to can be helpful to understand.

Hi Sumit Panse. My meter is http://electrique.com.sg/?product_cat=amsys. This is private company of my country and document don't public in the internet

Hello all, I figured out the reason is because SoftwareSerial's default library does not support connection configuration. I use CustomSoftwareSerial and fixed it by connecting the required data bit, stop bit, ...

Using readBytes would do the same as your C# code. readBytes is blocking. It will wait for every byte until timeout. Default timeout is 1 second. If the count of bytes is smaller then the size of the buffer, it will wait a second after the last byte received. You can set the timeout with RS485Serial.setTimeout(500); (500 milliseconds for example).
void loop()
{
  digitalWrite(SSerialTxControl, RS485Transmit);
  RS485Serial.write(request, sizeof(request));
  RS485Serial.flush();
  digitalWrite(SSerialTxControl, RS485Receive);
  int recvLen = RS485Serial.readBytes(buffer, sizeof(buffer));
  for (int i = 0; i < recvLen; i++) {
    Serial.println(buffer[i], HEX);
  }
}

It's still blank. I think issue from the sent request ?

You mean i need create another function and call in loop() ?

Thank your advise my new code to fix this problem

#include <CustomSoftwareSerial.h>
CustomSoftwareSerial RS485Serial(SSerialRX, SSerialTX);
RS485Serial.begin(1200, CSERIAL_8E1);

sorry, I overlooked that you set non standard serial parameters


text:
Sniffing thermostat protocol CC1101 868MHZ
I am using this libary from github:https://github.com/veonik/arduino-cc1101
With this example code. I will try to read the data which is send from a 868Mhz thermostat. I am using a arduino Mega and wired it like in the following picture.

First I get this error:

When i upload the code. I get this Serial Output. But no packages send and no packacges recived. Can somebody help me?
   CC1101_PARTNUM 0
CC1101_VERSION 20
CC1101_MARCSTATE 9
CC1101 radio initialized.

example code:
 #include <Arduino.h>
    #include <cc1101.h>
    #include <ccpacket.h>

    // Attach CC1101 pins to their corresponding SPI pins
    // Uno pins:
    // CSN (SS) => 10
    // MOSI => 11
    // MISO => 12
    // SCK => 13
    // GD0 => A valid interrupt pin for your platform (defined below this)

    #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__)
    #define CC1101Interrupt 4 // Pin 19
    #define CC1101_GDO0 19
    #elif defined(__MK64FX512__)
    // Teensy 3.5
    #define CC1101Interrupt 9 // Pin 9
    #define CC1101_GDO0 9
    #else
    #define CC1101Interrupt 0 // Pin 2
    #define CC1101_GDO0 2
    #endif

    CC1101 radio;

    byte syncWord[2] = {199, 10};
    bool packetWaiting;

    unsigned long lastSend = 0;
    unsigned int sendDelay = 5000;

    void messageReceived() {
        packetWaiting = true;
    }

    void setup() {
        radio.init();
        radio.setSyncWord(syncWord);
        radio.setCarrierFreq(CFREQ_868);
        radio.disableAddressCheck();
        radio.setTxPowerAmp(PA_LongDistance);

        Serial.begin(9600);
        Serial.print(F("CC1101_PARTNUM "));
        Serial.println(radio.readReg(CC1101_PARTNUM, CC1101_STATUS_REGISTER));
        Serial.print(F("CC1101_VERSION "));
        Serial.println(radio.readReg(CC1101_VERSION, CC1101_STATUS_REGISTER));
        Serial.print(F("CC1101_MARCSTATE "));
        Serial.println(radio.readReg(CC1101_MARCSTATE, CC1101_STATUS_REGISTER) & 0x1f);

        Serial.println(F("CC1101 radio initialized."));
        attachInterrupt(CC1101Interrupt, messageReceived, FALLING);
    }

    // Get signal strength indicator in dBm.
    // See: http://www.ti.com/lit/an/swra114d/swra114d.pdf
    int rssi(char raw) {
        uint8_t rssi_dec;
        // TODO: This rssi_offset is dependent on baud and MHz; this is for 38.4kbps and 433 MHz.
        uint8_t rssi_offset = 74;
        rssi_dec = (uint8_t) raw;
        if (rssi_dec >= 128)
            return ((int)( rssi_dec - 256) / 2) - rssi_offset;
        else
            return (rssi_dec / 2) - rssi_offset;
    }

    // Get link quality indicator.
    int lqi(char raw) {
        return 0x3F - raw;
    }

    void loop() {
        if (packetWaiting) {
            detachInterrupt(CC1101Interrupt);
            packetWaiting = false;
            CCPACKET packet;
            if (radio.receiveData(&packet) > 0) {
                Serial.println(F("Received packet..."));
                if (!packet.crc_ok) {
                    Serial.println(F("crc not ok"));
                }
                Serial.print(F("lqi: "));
                Serial.println(lqi(packet.lqi));
                Serial.print(F("rssi: "));
                Serial.print(rssi(packet.rssi));
                Serial.println(F("dBm"));

                if (packet.crc_ok && packet.length > 0) {
                    Serial.print(F("packet: len "));
                    Serial.println(packet.length);
                    Serial.println(F("data: "));
                    Serial.println((const char *) packet.data);
                }
            }

            attachInterrupt(CC1101Interrupt, messageReceived, FALLING);
        }
        unsigned long now = millis();
        if (now > lastSend + sendDelay) {
            detachInterrupt(CC1101Interrupt);

            lastSend = now;
            const char *message = "hello world";
            CCPACKET packet;
            // We also need to include the 0 byte at the end of the string
            packet.length = strlen(message)  + 1;
            strncpy((char *) packet.data, message, packet.length);

            radio.sendData(packet);
            Serial.println(F("Sent packet..."));

            attachInterrupt(CC1101Interrupt, messageReceived, FALLING);
        }
    }

That is not serial output. That is compiler output. To see serial output open the serial monitor.

Also note that 868MHz is not the frequency. It is the band.  That band is typically subdivided into a number of channels with a specific bandwidth (no standard, but implementation specific). The actual frequency could be anywhere between 865MHz and 870MHz.  You should use an SDR dongle (I use RTL2832U) to both locate and capture the data. Also note that there are multiple different modulation techniques that you will need to account for.

I updated the question. @Majenko thank you. When I capture the data with the RTL2842U, how can I then capture the data with the cc1101. Because I dont get any data with the cc1101. I understood that the RTL2843U is to understand the protocol. But how can I read the data with the cc1101? Or do you mean it is impossible to read the data from thermostat with cc1101?

I'm so confused: https://arduino.stackexchange.com/questions/62605/cc1101-sniffing-868mhz-protocol-from-thermostat

This was another problem I already solved...

Why is this not part of your question from yesterday on the exact same topic?

because it is another problem. I can delete this topic and change the question from yesterday. If you want it.

Before you can start messing around with a CC1101 you first have to know exactly what it is you are trying to capture. You can't configure the CC1101 until you know some basic facts about the transmission. Such things as: what is the carrier frequency? What is the modulation system used? Is there a sync word at the start of a packet, and what is it? How long is the packet? Is there a CRC that needs calculating? Without that information the CC1101 can't receive any data.

Just because the CC1101 runs in the same frequency band it doesn't necessarilly follow that it will be able to receive the data. After all Bluetooth and WiFi both run in the 2.4GHz range. So does the nRF24L01. And none of them can communicate with each other.

@Majenko, it appears that the CC1101 has "asynchronous mode" which allows the raw data to be read


text:
Reaction timer using millis
I've written this code for a reaction timer game. The reaction time is to be displayed in milliseconds to the serial monitor as accurately as possible. The reaction time is not being displayed correctly. I'm including my timer setup routine and where I increment milliseconds.
TCCR1A=0;
TCCR1B=0;
timer1_counter=65536;
TCNT1=timer1_counter;
TCCR1B |=(1<<CS12);

TIMSK1 |=(1<<TOIE1);
interrupts();
}

ISR(TIMER1_OVF_vect)
{
  TCNT1=timer1_counter;
  int_flag=1;
 }

  digitalWrite(LED,LOW);
  randomSeed(analogRead(A1));
  NumSecs=random(1000,7000);
  delay(NumSecs);
  digitalWrite(LED,HIGH);
  while(digitalRead(PUSHBUTTON) == HIGH)
  {
  }
  if (int_flag==1){
  millisecs++;
  int_flag=0;
  }

You're over-thinking this:
  digitalWrite(LED,LOW);
  randomSeed(analogRead(A1));
  NumSecs=random(1000,7000);
  delay(NumSecs);
  digitalWrite(LED,HIGH);
  unsigned int startTime = millis();
  while(digitalRead(PUSHBUTTON) == HIGH)
  {
  }
  unsigned int elapsed = millis() - startTime;

After that code, elapsed will contain the number of milliseconds it took the user to press the button. Note, however, that the user could cheat and simply press the button the whole time while waiting for the LED to change states. You could add logic to make sure the button isn't pressed just before you change the LED state, but I'll leave that up to you.

Your ISR is not counting the elapsed milliseconds. Instead, it just sets
a flag and lets the main program do the counting when it sees the flag.
Here:
while(digitalRead(PUSHBUTTON) == HIGH)
{
}

you are waiting for the user to press the button. The program does
nothing else during the wait. It doesn't event count the time. Here:
if (int_flag==1){
    millisecs++;
    int_flag=0;
}

you increment once the millisecond count after the wait.
The obvious solution is to count the milliseconds while waiting for the
button press:
millisecs = 0;  // don't forget to reset the stopwatch!
while (digitalRead(PUSHBUTTON) == HIGH) {  // button not pressed
    if (int_flag) {
        millisecs++;
        int_flag = false;
    }
}

(side note: int_flag should be a bool).
There are still many issues with this program. First of all, it should
check that the user did not press the button before the LED came up.
Then, the interrupt period is not one millisecond, because the interrupt
takes some time to be processed by the CPU and to go through its
prologue. By the time you do TCNT1=timer1_counter; you are at least
several tens of cycles late. You should instead configure the timer to
keep the correct period by itself, typically using CTC mode.
Also, there is no point in letting the main program count the
milliseconds when the ISR could do it. E.g.
ISR(TIMER1_OVF_vect)
{
    millisecs++;
}

// Avoid a race condition when reading millisecs.
static inline unsigned int getMillisecs()
{
    noInterrupts();
    int millisecsCopy = millisecs;
    interrupts();
    return millisecsCopy;
}

Note that the time keeping variables should be unsigned in order to
avoid undefined behaviour on overflows.
Finally, it may be a good learning experience for working with
interrupts, but in the end just using millis() or micros() would be
the easiest way to achieve what you want.

Ok thank you. I'll give millis() a try.


text:
Matter protocol with Arduino Mega/Giga
I would like to try matter protocol with Arduino mega or Arduino giga.
But I don't find any sample or library. I have only found libraries compatibles with ESP32.
Do you know how I can work with matter protocol on an Arduino Mega or Giga ?
Thanks

What kind of answer do you expect? "Why" something is the way it is usually cannot be answered, and the probable reason will not help you, I'm afraid. It might be as simple as "Because the authors did not make it for those Arduino models." So please [edit] your question and ask what you really want to know.

Sorry, i have edit my question. Thanks

If this is the source code repository for the ESP32 Matter project, then this statement from the README file found there:

Make sure that ESP32 board version is 2.0.14. This is crucial, because
this library contains pre-compiled files.

...would infer that not all the source code is available. It follows that the application can not be ported to a different processor.

Apparently it is an 'open' standard per wikipedia https://en.wikipedia.org/wiki/Matter_(standard) so theoretically one could write their own source with enough effort... Not that there aren't 'open' standards where just about every implementation is proprietary and fails to be compatible with items of other (or even the same) proprietor(s).


text:
Webserver on Arduino Mega with Ethernet Shield
I am working with an official Arduino Mega. I have mounted an officiel Ethernet Shield rev 2.
Everything works great, i have wrote a very basic webserver.
I wanted to host a bootstrap css file on my webserver. This file has a size of about 150 kilo-bytes. So i have inserted an SD card on the Ehternet Shield. I have put my css file on this SD card.
I am writing the content of my css file with this code:
File myFile = SD.open("bootstrap.min.css");
if (myFile)
{
    byte clientBuf[2048];
    int clientCount = 0;
    while (myFile.available())
    {
        clientBuf[clientCount] = myFile.read();
        clientCount++;

        if(clientCount > 2048-1)
        {
            client.write(clientBuf,2048);
            clientCount = 0;
        }
     }
     if(clientCount > 0) client.write(clientBuf,clientCount);
     myFile.close();
 }

It works, but it is very slow.
It takes about 30-40 seconds to load file into my browser.
I have tried to change clientBuf size but this is the optimal value i've set.
Any idea ?
Thanks

you should set Expires: header to let the browser cache the file. and set the content-length header to let the browser know how many bytes to expect. https://github.com/jandrassy/Regulator/blob/8262f28b7452df0b75aa6c5a7bc676e14cd0cd26/Regulator/WebServer.ino#L112

I agree but it will be slow for first load...

sorry, my largest file is only 10 kB. can you load framework files from Internet?


text:
Boolean function call with character pointer input - dont understand how to get updated pointer value
Thank you for everyone's help in trying to find a solution. This library I'm working with was prewritten and is one of the most buggy hardware libraries I've had the misfortune to use. I have now solved to problem by reusing the response parsing code from the library and rewriting my own sequence to return the number using a completely different approach. Many Thanks again!
I am currently attempting to understand how this function works and am struggling. I want to be able to access the 'number' variable in my main function but currently when I do that I get nothing (as in "") when I try to printout the variable with:
Serial.println(incomingNumber);

I am currently preassigning the number as:
char incomingNumber[14];

at the top of my project file.
With a class initial setup of:
DFRobot_SIM808 sim808(&Serial);

I'm then later calling the function like this:
if(sim808.isCallActive(incomingNumber)){Serial.println(incomingNumber);}

This seems like I'm currently making a fundamental error in understanding data types but I'm a bit lost so any help would be really appreciated.
I havent included my entire project here because its currently quite long and spread across both the main and some library files but if anyone needs more info please ask and I'll upload the extras.
The function from the library I'm working with is included below:
bool DFRobot_SIM808::isCallActive(char *number)
{
char gprsBuffer[46];  //46 is enough to see +CPAS: and CLCC:
char *p, *s;
int i = 0;

sim808_send_cmd("AT+CPAS\r\n");
/*Result code:
    0: ready
    2: unknown
    3: ringing
    4: call in progress

  AT+CPAS   --> 7 + 2 = 9 chars
            --> 2 char
  +CPAS: 3  --> 8 + 2 = 10 chars
            --> 2 char
  OK        --> 2 + 2 = 4 chars

  AT+CPAS

  +CPAS: 0

  OK
*/

sim808_clean_buffer(gprsBuffer,29);
sim808_read_buffer(gprsBuffer,27);
//HACERR cuando haga lo de esperar a OK no me har閾哸 falta esto
//We are going to flush serial data until OK is recieved
sim808_wait_for_resp("OK\r\n", CMD);
//Serial.print("Buffer isCallActive 1: ");Serial.println(gprsBuffer);
if(NULL != ( s = strstr(gprsBuffer,"+CPAS:"))) {
  s = s + 7;
  if (*s != '0') {
     //There is something "running" (but number 2 that is unknow)
     if (*s != '2') {
       //3 or 4, let's go to check for the number
       sim808_send_cmd("AT+CLCC\r\n");
       /*
       AT+CLCC --> 9

       +CLCC: 1,1,4,0,0,"656783741",161,""

       OK

       Without ringing:
       AT+CLCC
       OK
       */

       sim808_clean_buffer(gprsBuffer,46);
       sim808_read_buffer(gprsBuffer,45);
        //Serial.print("Buffer isCallActive 2: ");Serial.println(gprsBuffer);
       if(NULL != ( s = strstr(gprsBuffer,"+CLCC:"))) {
         //There is at least one CALL ACTIVE, get number
         s = strstr((char *)(s),"\"");
         s = s + 1;  //We are in the first phone number character
         p = strstr((char *)(s),"\""); //p is last character """
         if (NULL != s) {
            i = 0;
            while (s < p) {
                number[i++] = *(s++);
            }
            number[i] = '\0';
         }
         //I need to read more buffer
         //We are going to flush serial data until OK is recieved
         return sim808_wait_for_resp("OK\r\n", CMD);
       }
     }
  }
}
return false;
}

On the face of it, what you are doing is perfectly correct. Either the library isn't detecting the phone number correctly or the module you are using doesn't report the phone number.

so the gsm module is on Serial or the Serial Monitor? 14 is the size of the array, not the value. the char array content is uninitialized.

From what I understand is it generally better to initialize the array size at the maximum, even if the end product is much shorter?

you write "I am currently preassigning the number as char incomingNumber[14];"

Yeah, DFRobot libraries SUCK. For example, I had to rewrite their DFPlayerMini MP3 player library cause it was so terrible

You can't use Serial.println(array);. In fact, I'm not even sure how the compiler even let you do this...
A better approach would be to use Serial.write(array, sizeof(array));
Also, in order to ensure the function is even executing that portion of the code in the first place, you should but some debugging prints in the code. Like this:
     if (NULL != s) {
        i = 0;
        while (s < p) {
            number[i++] = *(s++);
            Serial.write(number[i++]); //-------- debug
            Serial.print(' '); //-------- debug
        }
        number[i] = '\0';
        Serial.println(); //-------- debug
     }

Also, proper use of whitespace is your friend ;)

You can't use Serial.println(array); -- Yes you can. It's just a C string that's NULL terminated. There's absolutely nothing wrong with that.


text:
Arduino FFT Heart Rate Monitor
Part of my project is to build heart rate monitor from Nano and a PulseSensor. I am having trouble working with the Fast Fourier Transform part of the code.
This code here is from a library (arduinofft) that can be found in the arduino IDE. When testing the arduino the serial printer returns values of about 51 bpm, which is far to low, compared to other devices of about 70bpm.
What i have done:

edited the library to only take the last 25 to 128 samples (only when computing the max peak), to off-set the DC. Previously getting readings of 5 BPM
changed the sampling frequency to 5.6Hz to get the range of 0 to 2.8Hz range for the hate rate

What i don't understand:

the sampling period, if the samples are taken and put into an array every second what does the period do.
Also if samples are taken every second is this enough to get a good reading on a heart rate shouldn't the sample be maybe of 15-30 seconds?
If this is so, should i put another array at the bottom. To capture the results every second upto 15 or 30, print the average then first in first out  the array of new values?

#include "arduinoFFT.h"

arduinoFFT FFT = arduinoFFT(); /* Create FFT object */

#define CHANNEL A0
const uint16_t samples = 128; //This value MUST ALWAYS be a power of 2
const double samplingFrequency = 5.6; //Hz, must be less than 10000 due to ADC

unsigned int sampling_period_us;
unsigned long microseconds;

double vReal[samples];
double vImag[samples];

#define SCL_INDEX 0x00
#define SCL_TIME 0x01
#define SCL_FREQUENCY 0x02
#define SCL_PLOT 0x03

void setup()
{
  sampling_period_us = round(1000000*(1/samplingFrequency));
  Serial.begin(115200);
  Serial.println("Ready");
}

void loop()
{
  /*SAMPLING*/
  for(int i=0; i<samples; i++)
  {
      microseconds = micros();    //Overflows after around 70 minutes!
      vReal[i] = analogRead(CHANNEL);
      vImag[i] = 0;
      while(micros() < (microseconds + sampling_period_us)){
        }
  }

  FFT.Windowing(vReal, samples, FFT_WIN_TYP_RECTANGLE, FFT_FORWARD);    /* Weigh data */
  FFT.Compute(vReal, vImag, samples, FFT_FORWARD); /* Compute FFT */
  FFT.ComplexToMagnitude(vReal, vImag, samples); /* Compute magnitudes */
  double x = FFT.MajorPeak(vReal, samples, samplingFrequency); /* Compute largest peak*/
  double y = round((60/(1/x)));
  Serial.println(y);  //print bpm
  delay(2000); /* Repeat after delay */
}

Thanks for any help

compared to other devices of about 70bpm .... are you sure that the other devices are accurate? ..... check the pulse rate manually

I have checked my heart rate manually and should have rate higher than 60 consistently. Other device is the finger clip that the NHS gives you so should be accurate

it's just the first step in troubleshooting .... confirming that there really is a problem


text:
Bug in code of Self-Balancing Bot
1)The values drifts to the extreme every time I run this , I guess this is due to my mistake in the calculation of angles or in the filter that I have applied which I have been trying to but can't find it. 2)I have tried to  calibrate MPU many times but failed as the x-axis value is showing 0 only when I tilt the bot to 12-14 degrees on x-axis(data from only accelometer),(if you can just tell me the variable to modify)
#include <Wire.h>
long accelX, accelY, accelZ;
float gForceX, gForceY, gForceZ,elapsedTime;
long gyroX, gyroY, gyroZ;
float rotX, rotY, rotZ;
double x,y,z,dx,dy,dz,ex,ey,ez,desx=0,desy=0,desz=0;
float PID, PWM, error, previous_error,timePrev,time1;
float pid_p;
float pid_i;
float pid_d;
float rad_to_deg = 180/3.141592654;
/////////////////PID CONSTANTS/////////////////
double kp=2;
double ki=0;
double kd=0;
int motor1pin1 = 2;
int motor1pin2 = 3;
int led = 9;           // the PWM pin the LED is attached to
int brightness = 0;    // how bright the LED is
int fadeAmount = 5;

void setup()
{
  Serial.begin(115200);
  Wire.begin();
  pinMode(motor1pin1, OUTPUT);
  pinMode(motor1pin2, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(13, OUTPUT);
  setupMPU();
  delay(500);
}

void loop()
{
    timePrev = time1;  // the previous time is stored before the actual time read
    time1 = millis();  // actual time read/
    elapsedTime = (time1 - timePrev) / 1000;
    recordAccelRegisters();
    recordGyroRegisters();
   processangle();
    Apply_PID();
    printData();
    delay(100);
}
void right(int PWM)
{
   analogWrite(9, PWM);
  digitalWrite(motor1pin1, HIGH);
  digitalWrite(motor1pin2, LOW);
  digitalWrite(13, HIGH);
  Serial.println("RIGHT");
}
void left(int PWM)
{
   analogWrite(9, PWM);
  digitalWrite(motor1pin1, LOW);
  digitalWrite(motor1pin2, HIGH);
   Serial.println("LEFT");
}
void stopper()
{
   analogWrite(9, PWM);
  digitalWrite(motor1pin1, LOW);
  digitalWrite(motor1pin2, HIGH);
   Serial.println("STOPPED");
  }
void setupMPU()
{
  Wire.beginTransmission(0b1101000); //This is the I2C address of the MPU (b1101000/b1101001 for AC0 low/high datasheet sec. 9.2)
  Wire.write(0x6B); //Accessing the register 6B - Power Management (Sec. 4.28)
  Wire.write(0b00000000); //Setting SLEEP register to 0. (Required; see Note on p. 9)
  Wire.endTransmission();
  Wire.beginTransmission(0b1101000); //I2C address of the MPU
  Wire.write(0x1B); //Accessing the register 1B - Gyroscope Configuration (Sec. 4.4)
  Wire.write(0x00000000); //Setting the gyro to full scale +/- 250deg./s
  Wire.endTransmission();
  Wire.beginTransmission(0b1101000); //I2C address of the MPU
  Wire.write(0x1C); //Accessing the register 1C - Acccelerometer Configuration (Sec. 4.5)
  Wire.write(0b00000000); //Setting the accel to +/- 2g
  Wire.endTransmission();
}

void recordAccelRegisters()
{
  Wire.beginTransmission(0b1101000); //I2C address of the MPU
  Wire.write(0x3B); //Starting register for Accel Readings
  Wire.endTransmission();
  Wire.requestFrom(0b1101000,6); //Request Accel Registers (3B - 40)
  while(Wire.available() < 6);
  accelX = Wire.read()<<8|Wire.read(); //Store first two bytes into accelX
  accelY = Wire.read()<<8|Wire.read(); //Store middle two bytes into accelY
  accelZ = Wire.read()<<8|Wire.read(); //Store last two bytes into accelZ
  processAccelData();
}

void processAccelData()
{
  gForceX = accelX / 16384.0;
  gForceY = accelY / 16384.0;
  gForceZ = accelZ / 16384.0;
  x= (RAD_TO_DEG * (atan2(-gForceY, -gForceZ)+PI));
  y= RAD_TO_DEG * (atan2(-gForceX, -gForceZ)+PI);
  z= RAD_TO_DEG * (atan(sqrt(square(-gForceY) + square(-gForceX)) / -gForceZ));
 /* x=map(x,340,11,-90,90);*/

    Serial.print(" AccelX=");
  Serial.print(x);

}

void recordGyroRegisters()
{
  Wire.beginTransmission(0b1101000); //I2C address of the MPU
  Wire.write(0x43); //Starting register for Gyro Readings
  Wire.endTransmission();
  Wire.requestFrom(0b1101000,6); //Request Gyro Registers (43 - 48)
  while(Wire.available() < 6);
  gyroX = Wire.read()<<8|Wire.read(); //Store first two bytes into accelX
  gyroY = Wire.read()<<8|Wire.read(); //Store middle two bytes into accelY
  gyroZ = Wire.read()<<8|Wire.read(); //Store last two bytes into accelZ
  processGyroData();
}

void processGyroData()
{
  rotX = (gyroX / 131.0);
  rotY = gyroY / 131.0;
  rotZ = gyroZ / 131.0;
  Serial.print(" GyroX=");
  Serial.println(rotX*elapsedTime);
}
void processangle()
{
  dx=0.98 *(dx + rotX*elapsedTime) + 0.02*x;
  dy=0.98 *(dy + rotY*elapsedTime) + 0.02*y;
  dz=0.98 *(dz + rotZ*elapsedTime) + 0.02*z;
  ex=dx-desx;
  ey=dy-desy;
  ez=dz-desz;
  Serial.print("After Filter Angle");
  Serial.println(ex);
}
void Apply_PID()
{
  float l=(float)ex;
  pid_p=kp*l;
  pid_i = pid_i+(ki*l);
pid_d = kd *((l - previous_error)/elapsedTime);
PID = pid_p + pid_i + pid_d;
/*Serial.print("I=");
Serial.println(pid_d);
Serial.print("p=");
Serial.println(pid_p);*/
Serial.print("PID");
Serial.println(PID);

if(l>5.5 || l<5.5)
  {
    if(l<0)
    right(PID);
    else
    left(PID);
  }
  else
  {
    stopper();
    }
previous_error = l;
}

void printData()
{
  /*Serial.print("Gyro (deg)");
  Serial.print(" X=");
  Serial.print(rotX);
  Serial.print(" Y=");
  Serial.print(rotY);
  Serial.print(" Z=");
  Serial.print(rotZ);
  Serial.print(" Accel (g)");
  Serial.print(" X=");
  Serial.print(gForceX);
  Serial.print(" Y=");
  Serial.print(gForceY);
  Serial.print(" Z=");
  Serial.println(gForceZ);*/
 /* Serial.print(" PWM");
  Serial.println(PID);*/
}

It might be something with " Wire.read()<<8|Wire.read()". If you șhift a byte 8 bits you get 0. Read the Wire.read() to a long first.


text:
Wanted to control 2 servos with serial read
I want to use 2nd servo only when 1st is in up state by asking user whether he wants to fire or not.(code in bold is not working )
#include <Servo.h>

    Servo myservo;
    Servo trigervo;
    int pos = 0;
    int u = 0, p = 0, t = 0;
    int incomingByte = 0; // for incoming serial data

    void setup() {
      Serial.begin(9600);
      myservo.attach(9);
      trigervo.attach(10);
      pinMode(13, OUTPUT);
      myservo.write(0);
    }

    void loop() {
      if (Serial.available() > 0) {
        // read the incoming byte:
        incomingByte = Serial.read();
        Serial.print("I received: ");
        if (incomingByte == 111 && u == 0) {
          for (pos = 0; pos <= 80; pos += 1) {
            myservo.write(pos);
            delay(5); //
            digitalWrite(13, HIGH);
          }
          u = 1;
          p = 0;
          Serial.println(incomingByte, DEC);
          Serial.print("Want to Shoot? \n");
          Serial.print("1\n");
          ***t = Serial.read(); // from here
          if (t == 107) {
            Serial.print("2\n");
            trigervo.write(60);
            trigervo.write(0);
          } // to here, it is not working***
        } else if (incomingByte == 102 && p == 0) {

          for (pos = 100; pos >= 0; pos -= 1) {
            myservo.write(pos);
            delay(7);
            digitalWrite(13, HIGH);
          }
          u = 0;
          p = 1;
          Serial.println(incomingByte, DEC);
        }
        Serial.println(incomingByte, DEC);

      }
    }

read() doesn't wait. it returns -1 if there is nothing in the RX buffer

you forgot to ask a question ... you also forgot to describe what happens when you run the program

Without knowing, what exactly you want it to do (since you didn't tell us), I see 2 problems in your code:

The code around the line marked with "from here" will ask the user over Serial, if he wants to shoot, but directly after it, it will read a value, without waiting for the user to input something. Serial.read() will not wait for data to arrive, it will just return -1 if nothing is in the buffer. You have to check, if there is actually something in the buffer with Serial.available() and only proceed, if there is actually data to read.

In the following if-statement, you first write the value 60 to the servo and directly after it, without any delay, the value 0. The servo doesn't have enough time to get to 60 - or to even start to move - before you tell him to go to 0. The servo needs time for movements.

Apart from the specific problems with your code, I would use a finite state machine (FSM), to implement it, instead. You declare a global state variable, which represents the possible states, in which your machine can be. If I assume some type of gun/shooting device, these states could be ASK_USER_TO_POSITION_GUN' and 'ASK_USER_TO_SHOOT'. In each state you check the Serial interface (first with Serial.available()then reading withSerial.read()` if it returns something greater than 0) and based on that input you first take the appropriate action and then do the state transition, by changing the state variable.
As example of the general structure:
int state = 0;

void loop(){
    switch(state){
        case 0:
            if(Serial.available()>0){
                int input = Serial.read();
                //take appropriate action
                state = 1; //do state transistion
            }
            break;
        case 1:
            if(Serial.available()>0){
                int input = Serial.read();
                //take appropriate action
                state = 0; //do state transition
            }
            break;
    }
}

Depending on the exact actions to do, you can also tune this, by reading Serial outside of the switch statement and in the case statement only check the input variable. In this case reset the input variable after every interaction.
EDIT: For giving a better explanation about finite state machines, I've drawn a graphical representation of the states. Mostly it is way easier to code, when you first have drawn such a graph to visualize the codes functionality. Note, that this is the logic from your code. You may want it to work another way, but this is beyond the scope and only for understanding. Also note the different numbers of the states than I used above, which I only change, because I needed more states.
See first this graph:

We begin in state 0, where we are waiting for user input through serial. If we go some input, we make a decision: If the value is 111, we will transition to the next state (state 1) to position the gun, else we will wait again for more input. In stage 1, we are positioning the gun and go directly to state 2. There we are again waiting for user input. If we received something, we will again make a decision: On the value 107 we will do the transition to state 3 to shoot, else we will go to state 0, to ask again for positioning, like we did before. In state 3 we are shooting and directly go to state 0 again. This is rather strict division into states.
Since in state 1 and 3 we are only doing a short action and then going directly to another state, we might cut those states away, implementing the corresponding code in the transition from state 0 to 2 and vice versa. This is the logic from my FSM code example above (action together with transition). The graph would look like this:

Which version you should implement depends on other factors. If you are OK with the action code to be blocking, you can implement version 2, since it has less states. If you want to write the action in a non-blocking style, you might find version 1 easier to implement.

As you have asked I have changed the question to be pinpointed , please help me......

The answer stays the same. Your direct problems are the two stated above.  Is this helping? If not: What prevents you from implementing this? Maybe I can write the answer more understandable, if I knew, what isn't clear about it.

In case 0, I want to get value through serial read again and implement it by calling a function , in this case calling a trigger function.

I rejected your edit, because that is not the way a FSM works. In the states you are waiting for user input. Instead of directly (still in case 0) trying to read more data, you make a transition to the next state, where you are waiting for the new data. That makes the code way better structured and also the waiting for user input will not block the code execution, in case, that you want to do something simultaneously (like blinking an LED or other tasks). I will add a graphical representation of the FSM for your case, so it is better understandable.

Ok now I  am getting the idea of it


text:
Effective Controlling of Continous Servo Motor
I have difficulty in controlling a MG995 continuous motor. For I know I can control the speed of the motor as writing servo1.write(p) , where the value of p changes the speed of the motor. When the value of p is set to 90 then the motor stops ,whereas 0 and 180 values allows it to move in the top speed in C.W and Anti C.W direction respectively.
...........** I had difficulty in writing a code where I can rotate the servo motor for 180 degrees then rotating back again to 0 and whenever my ultrasonic sensor finds any object the servo should stop at that point for further action. ** ........
(I think this value could be useful :Operating speed: 0.2 s/60º (4.8 V), 0.16 s/60º (6 V))

You want to rotate at any speed that you want, or you want to rotate to any angle that you want?

I want to rotate at a specific angle .

Then you need some form of feedback from the motor's shaft to know what angle it is at. Normally if you want an angle then you don't want a continuous rotation servo.

I have a feeling that by using time functions we can rotate it at any angle .If my calculations are correct then for every angle it takes 3 milliseconds to turn.Well I don't know if we can use this

You can get an approximation, but it will drift over time. That's a "nominal" speed, not taking into account acceleration and deceleration and variances in manufacturing.

what are you trying to do ... your question says nothing about the end goal of your project

I am trying to make a Radar type mechanism which will sweep to a particular angle and help the ultrasonic sonic sensor to locate an object .....

According to your project description, it sounds like you need a typical non-continuous servo motor - one that rotates to a specific angle. Do you actually need rotational speed control? You could do both with a continuous, speed-controlled servo but it is only going to servo on rotational speed; you'll need to do the control on angle with a shaft encoder and software.

Initially I wanted a typical non-continuous servo but instead amazon got me a continuous servo even when the description had clearly mentioned of a non-continuous servo.

Have you been able to rotate the servo to a position, stop and go back to the initial position? Could you try doing it with the "servo1.write" function and the delay function (or using a busy-loop)?


text:
Button and twist knob to send keystroke to PC
As a novice, I would like to create a small breadboard with 5 items on it. 3 toggle buttons, and two constant spin (ie. no stop at 360 degrees) knobs.
Is then like the bottoms to send what ever key stroke (single key pee click) to the pc as if it was from a keyboard (maybe even a shift+key?)
And the knobs send keystrokes too. On each “click” as I don’t want smooth knobs. Ones that kinda of click per degree. Not sure how to explain that.
It’s for Flight Simulator. Doing it with a mouse, from distance, with small buttons is challenging. And twisting knobs with the mouse in bumpy conditions is even worse.
So planning on using my Nana, connected to a USB port for
Power and signal.
Can anyone guide me in the right direction? Would I need 3rd party software to convert signals to keystrokes on the pc?
I think there is a keyboard library - but from what I read, it takes over your keyboard. That is, once the Arduino is connected and listening - the main keyboard no longer functions. Is that a misunderstanding? I need both to be operational.
I’m guessing something like this as it has “positions”.
https://www.ebay.com.au/itm/Rotary-Encoder-Module-Arduino-Compatible/232624628710?hash=item36298223e6:g:JIIAAOSwg31aVFVW

As a novice, I would like to create a small breadboard with 5 items on it. 3 toggle buttons, and two constant spin (ie. no stop at 360 degrees) knobs.

Those knobs are called "Rotary Encoders".

Is then like the bottoms to send what ever key stroke (single key pee click) to the pc as if it was from a keyboard (maybe even a shift+key?)

Then you really want an Arduino with a "native" USB connection, like the Leonardo or Micro.

Can anyone guide me in the right direction? Would I need 3rd party software to convert signals to keystrokes on the pc?

Not with a Micro or Leonardo - you just use the Keyboard.h library.  If you want to use your Nano then yes, you can only talk serial, and you will have to have some third party software that interprets serial commands and injects keyboard signals into your OS.  I think there's some Python projects around that do that kind of thing. Or there is "professional" software, like 232key that can do it for you.

Thanks for that. I can get a different board if it’s more suitable for the application. Would this take over the keyboard? Or would the keyboard still be fully functional while my project is connected and sending keystrokes?

connect two keyboards to your PC and see

@Craig Your keyboard would be fully functional. You can connect multiple keyboards to a computer and they all work as one keyboard.

Thank you, @majenko. I’ll order a Arduino Micro (seems to be the new version of the Leonardo?) and the Rotary Encoder I linked in my post. Your post indicated I don’t need software on the pc? Basically connect the Micro, it will get power off the same USB that is sending the signal - and write the code to send the commands using Keyboard.h?

@Craig The Micro is to the Leonardo what the Nano is to the Uno. With that you don't need software on your PC. Just Keyboard.begin(); and Keyboard.println("format c:"); https://www.arduino.cc/reference/en/language/functions/usb/keyboard/

The twisty click per degree thing is called a rotary encoder.
You can already send serial commands to a computer, so to keep it simple, I'd try to find a way of turning the serial commands into a keyboard click.

Thanks. I think that’s the hard part. Converting things from the board, into a signal that the pc sees as a keystroke. I’ll look around.