text:
Initalizing library object in own library
EDIT: @Juraj fixed the Issue, changes at the end of the post
I am developing an application to program OneWire ID Chips. I am using the OneWire library (https://github.com/PaulStoffregen/OneWire) and built my own Library for the DS28EC20 Chip on top of it.
It is working but it's not very elegant. I have issues initalizing the OneWire object in my own library. At the moment it is only working with a fixed pin declared in my own library.
I want to call a function in my code which initalizes the OneWire library aswell as my own library for the DS28EC20.
I am not using the Arduino IDE, I am using Platform.io for VSCode because it's more powerful.
It would be awesome if someone could help me, because I need to use multiple ID Chips in my application.
Because of unkown reasons I need to pass a variable to the constructor of the DS28EC20. Calling the OneWire library in there does not work...
I excluded the other functions in the DS28EC20.cpp file, I think they are not necessary rn
Thank you very much in advance!
- pitchbent
main.cpp:
#include <Arduino.h>
#include <OneWire.h>
#include <DS28EC20.h>

uint8_t scratchpad[32];                                                   // Array for scratchpad
uint16_t location;                                                        //Memory location to store scratchpad in
//uint8_t memory[32];
bool status;                                                              // Status of the crc check

DS28EC20 One(5);

void setup() {

  pinMode(13,OUTPUT);
  Serial.begin(115200);                                                   //begin serial connection 0
  location = 0x460;                                                       //Memory location

  for (uint8_t i = 0; i < 32; i++)                                        //filling array for scratchpad
  {
    scratchpad[i]=0x22;
  }
  Serial.println(scratchpad[2]);

  status = One.write_scratchpad(scratchpad,32,location);                  //write scratchpad
  Serial.println("Status:");                                              //print status
  Serial.println(status);

  // put your setup code here, to run once:
}

void loop() {

  // put your main code here, to run repeatedly:
}

DS28EC20.cpp:
#include "Arduino.h"
#include "OneWire.h"
#include "DS28EC20.h"

OneWire Wire(31);

DS28EC20::DS28EC20(uint8_t)
{

}
bool DS28EC20::write_scratchpad(uint8_t *data, uint8_t leng, uint_fast16_t adress)
{
  Serial.println("123");
  uint8_t TA1;                                                            // Var for adress Bytes
  uint8_t TA2;
  uint8_t crc_rec[6];                                                     // Array for recieved CRC Bytes
  uint8_t crc_array[leng+3];                                              // Array for calculation of CRC value

  TA1 = (adress & 0xFF);                                                  // calculation of TA1 & TA2
  TA2 = ((adress >> 8) & 0xFF);
 crc_array[0]=WRITE_SCRATCHPAD;                                            // The CRC sum is computed out of the command aswell as the adress byteys
  crc_array[1]=TA1;                                                         //
  crc_array[2]=TA2;

  for (int i = 0; i < leng; i++)                                            // write data into crc array
  {
    crc_array[i+3]=data[i];
  }
 Wire.reset();                                                             // Reset
  Wire.write(SKIP_ROM);                                                     // Skip ROM
  Wire.write(WRITE_SCRATCHPAD);                                             // write Scratchpad

  Wire.write(TA1);                                                          // send adress bytes
  Wire.write(TA2);

  for(int i=0;i<leng; i++)                                                  // write data
  {
    Wire.write(data[i]);
  }

  Wire.read_bytes(crc_rec,6);                                               // safe CRC values sent from chip

  delay(10);
 Wire.reset();                                                             // Reset
if(Wire.check_crc16(crc_array,leng+3,&crc_rec[0]))                        // CRC Check
  {
    return true;
  }
  else
  {
    return false;
  }

}

DS28EC20.h
/*
Library for DS28EC20, built on top of OneWire.h lib
*/

#ifndef DS28EC20_h
#define DS28EC20_h

#include "Arduino.h"
#include "OneWire.h"
#include "DS28EC20.h"

#define WRITE_SCRATCHPAD 0xF                                              // commands für DS28EC20
#define READ_SCRATCHPAD 0xAA
#define COPY_SCRATCHPAD 0x55
#define READ_MEMORY 0xF0
#define EXTENDED_READ_MEMORY 0xA5

#define READ_ROM 0x33
#define MATCH_ROM 0x55
#define SEARCH_ROM 0xF0
#define SKIP_ROM 0xCC
#define RESUME 0xA5

class DS28EC20
{
    public:
     DS28EC20(uint8_t); // Constructor, add DS28EC20 to "pin"
     bool write_scratchpad(uint8_t *data, uint8_t leng, uint_fast16_t adress);
     bool write_memory(uint16_t adress);
     void read_memory(uint16_t adress,uint8_t *data, uint8_t leng);

     private:

};

Fix:
In main.cpp call Object with corresponding pin:
DS28EC20 One(31);

In DS28EC20.cpp add
OneWire Wire;

after includes, change the constructor aswell:
DS28EC20::DS28EC20(uint8_t pin)
{
  Wire.begin(pin);
}

In DS28EC20.h you need to change the class to:
class DS28EC20
{
    public:

     DS28EC20(uint8_t pin); // Constructor, add DS28EC20 to "pin"
     bool write_scratchpad(uint8_t *data, uint8_t leng, uint_fast16_t adress);
     bool write_memory(uint16_t adress);
     void read_memory(uint16_t adress,uint8_t *data, uint8_t leng);

     private:
     OneWire Wire;

};

Do you get an error, if you don't provide a constructor parameter?

Yes. The answer of @Juraj kinda solved the issue. The only issue which still persists i calling a second instance...

Use the constructor without parameter OneWire wire; and call wire.begin(pin); to set the pin.
And to use more sensors on different pins, make the OneWire instance member of the DS28EC20 class.

It works better than before now, thank you. Initializing via DS28EC20 One(31)works now, but if I initalize a second instance (for example DS28EC20 Two(32) i return the same results as in the first object....

Please notice the commenct above yours :)

Thank you so much! I still need to learn a lot of things.


text:
Is it possible to run two small motors off an Arduino and have the motors move separately based on a random number generator?
I am a 2nd year design engineering student working on a design project where we are tasked with automating the movement of a rainfall simulator. One of our design ideas consists of two small motors running perpendicular to each other with the movements based on a random number generator. I was told that this would be fairly easy if we used a Siemens Program Logic Controller, but we have a very limited budget so I thought I would check out other options.
I am not familiar with the Arduino or much of anything to do with programming so I thought it would be beneficial to ask for advice from some people who know what they are doing. I attached an initial sketch of the idea and a picture of the rainfall simulator to hopefully clarify what I am hoping to accomplish. The most the device can move from its rested state is only 0.5".
Is this a path worth working towards? Or is this not the proper choice of equipment?
Any advice would be greatly appreciated!
Thanks,
Nick

What is a PLC? And it is not clear, what exactly you want. You could easily generate a random number between -1 and 1 and let the motor move for a time based on that, or with a speed based on that. I also don't understand, what exactly a "rainfall simulator" does here. How big are the motors, that you want to control (in terms of needed current and voltage)? You should give us more information

Thanks for letting me know it was unclear! I added a sketch of the idea and a picture of the rainfall simulator. I don't currently information on current and voltage as it is still a conceptual idea and we are in the process of figuring everything out.

I'm not sure, what I should write as an answer here, because your question is very broad. Surely you can build this with an Arduino and depending on your exact requirements, it will be rather easy. But that is too few for a real answer. So I suggest, you ask mores specific

Random is hard. Pseudo-random is easy.

Leaving your mechanical equipment uncommented *), an Arduino itself cannot drive 7.4V 1A Stepper Motors. An Arduino itself cannot drive any motor. You need a sufficient power supply and motor driver electronics. And there's a vast amount of different devices to choose from.
But then, the answer to "is it possible (random, two motors, moving independently)" is yes.
*) Well, regarding "uncommented" :
200 lbs is quite heavy to simulate/produce a few raindrops. Small motors won't move such gear as in your pic.

The Rainfall simulator itself can weigh a maximum of 200lbs when it is completely filled with water. The rainfall is produced through a vacuum in the tanks and drips out of small holes by itself. Currently the lab tech needs to stand beside the machine and push it every so often.  The task we are assigned with is just moving it side to side in a "random" sense. Thank you for your answer though as that was all I was looking for at the time! I will continue to pursue this design with my group with the information you provided.

source: Stack Exchange

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

sort: votes


text:
What is difference between ATMEGA32 and ATMEGA328?
I'm new in electronics. Just playing with Arduino boards.I just wanted to program ATMEGA328 micro-controller and use it without Arduino for compact design for my personal hobby project. I found there are ATMEGA32 and ATMEGA328 micro controllers in my local store. So, I wanted to know can I use ATMEGA32 instead of ATMEGA328 ? Which one is latest and whats are benefits. Thanks in advance.

The ATMega32 looks to be essentially the "big brother" of the ATMega328.  Just the same chip internally, but with more IO pins. I don't know about register / code compatibility, or Arduino core API support, having never used one.

you can't put ATmega32 into the DIP socket on Uno. the DIP version has a different size

I cannot tell for sure, but from a cursory look at the datasheets, the
ATmega32 looks older:

16 MHz maximum frequency v.s. 20 MHz for the ATmega328
4.5 V minimum supply voltage v.s; 1.8 V for the ATmega328
only one PWN channel per 8-bit timer

From an Arduino-programming point of view, I would prefer the 328, as it
would allow you to prototype your code on an Uno, and then move it to
the bare MCU, knowing it would work identically. The ATmega32 would be
worth consideration if you need more IO than the Uno can provide.

I can't post comments.
One difference is that the ATmega32 has JTAG; ATmega328P has not.

+1 It's not terribly complete, but it seems okay to post an answer.  It's answer type material at least.  And something not pointed out by others.

To answer this you'd need to study the according data sheets:
ATmega32
ATmega32u4
ATmega328
ATmega328P
ATmega328PB
Despite a similar name, the chips are quite different.
32u4 for examle has USB built in.
328PB has more 16-bit Timer/Counters.
... and many more differences.
They only differ on the hardware features and can be programmed in more or less the same way. It is up to you to choose which one you want to use.

The only nearly identical ones are 328 and 328P. If you don't care about the "picopower" feature you just have to know they have different signatures. To easiest move from an arduino (UNO or NANO) to a standalone controller, atmega328p is your choice.

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


text:
ultrasonic sencor give wrong distances
. I used      the inbuilt basic example of measuring the distance to test my ultrasonic sensor. the object is kept at 10 - 15 cm. form the ultrasonic sensor but still the readings show 135 cm only
#include <Ultrasonic.h>
int trigPin = 5;
int echoPin = 6;
#include <Servo.h>   //servo library
Servo servo;
int servoPin = 7;
long duration, dist, average;
long aver[3];   //array for average

void setup() {
    Serial.begin(9600);
    servo.attach(servoPin);
    pinMode(trigPin, OUTPUT);
    pinMode(echoPin, INPUT);
    servo.write(0);         //close cap on power on
    delay(100);
    servo.detach();
}

void measure() {
 digitalWrite(100,HIGH);
digitalWrite(trigPin, LOW);
delayMicroseconds(100);
digitalWrite(trigPin, HIGH);
delayMicroseconds(150);
digitalWrite(trigPin, LOW);
pinMode(echoPin, INPUT);
duration = pulseIn(echoPin, HIGH);
dist = (duration/2.0) / 29.1;    //obtain distance
}
void loop() {
  for (int i=0;i<=2;i++) {   //average distance
    measure();
   aver[i]=dist;
    delay(100);              //delay between measurements
  }
 dist=(aver[0]+aver[1]+aver[2])/3;

if ( dist<15 ) {
//Change distance as per your need
 servo.attach(servoPin);
  delay(1);
 servo.write(0);
 delay(2500);
 servo.write(100);
 delay(500);
 servo.detach();
}
Serial.print(dist);
}

#include <Ultrasonic.h>
int trigPin = 5;
int echoPin = 6;
#include <Servo.h>   //servo library
Servo servo;
int servoPin = 7;
long duration, dist, average;
long aver[3];   //array for average

void setup() {
    Serial.begin(9600);
    servo.attach(servoPin);
    pinMode(trigPin, OUTPUT);
    pinMode(echoPin, INPUT);
    servo.write(0);         //close cap on power on
    delay(100);
    servo.detach();
}

void measure() {
    digitalWrite(100,HIGH);
    digitalWrite(trigPin, LOW);
    delayMicroseconds(100);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(150);
    digitalWrite(trigPin, LOW);
    pinMode(echoPin, INPUT);
    duration = pulseIn(echoPin, HIGH);
    dist = (duration/2.0) / 29.1;    //obtain distance
}

void loop() {
  for (int i=0;i<=2;i++) {   //average distance
    measure();
   aver[i]=dist;
    delay(100);              //delay between measurements
  }
  dist=(aver[0]+aver[1]+aver[2])/3;

  if ( dist<15 ) {
    //Change distance as per your need
    servo.attach(servoPin);
    delay(1);
    servo.write(0);
    delay(2500);
    servo.write(100);
    delay(500);
    servo.detach();
  }
  Serial.print(dist);
}

No, we are not able to, because you didn't give us enough information. You should edit your question to include your complete code (format it correctly please) and your wiring. Also you should explain, how you are testing the project. An ultrasonic sensor needs a rather hard surface in front of it, so that the ultrasonic waves get reflected enough. Soft materials like fabric, or surfaces, that are not parallel to the sensor, will make the measurement more difficult/less accurate.

i have sent my code

To provide additional information, please always edit your question. There is an edit button for this. Your code is not the answer for your question, thus it should not be posted as answer. As you are a new contributor (welcome!), you might find the Tour rather helpful. High quality question have way more probability to get good answers.

I edited your question for you

Re “digitalWrite(100, HIGH);”: There is no pin 100 on the Uno.

Why did you added your code a second time to your question? I don't see a difference. Also you should really write more text and explain something. I asked more question in my first comment and you still didn't answer them

You have a lot of redundant code:

include Ultrasonic.h is unnecessary.
servo.attach and servo.detach without reusing pin is unnecessary
The ultrasonic code is not correct.
It should be:

    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);

    // measure duration of pulse from ECHO pin
    duration_us = pulseIn(echoPin, HIGH);

    // calculate the distance
    distance_cm = 0.017 * duration_us;

Refer to the Ultrasonic sensor tutorial and Servo motor tutorial


text:
PCINT0, PCINT1, PCINT2, etc. on ATtiny45/85
According to the datasheet:

we could think that, if we want to have a pin change interrupt for 3 pins, we have to create multiple instances:
ISR(PCINT0_vect){
   ...
}

ISR(PCINT1_vect){
   ...
}

ISR(PCINT2_vect){
   ...
}

void setup(){
  GIMSK = 0b00100000;
  PCMSK = 0b00000111;
}

However, this does not work, and I read here and here that we have to define just one interrupt function:
ISR(PCINT0_vect){
   if (digitalRead(0) == LOW)
     ...
   if (digitalRead(1) == LOW)
     ...
   if (digitalRead(2) == LOW)
     ...
}

Why is that so? What is PCINT1, 2, 3, ... made for then in this pinout schematics, if we don't have to use it?

You are confusing Pin Change Interrupt pins with Pin Change Interrupt vectors. The two are very different.
Many Pin Change Interrupt pins are associated with just one Pin Change Interrupt vector.
You use the pin number (the value shown in the pinout) to decide if you want that pin to respond or not. You use the vector to respond any of the pins that are assigned to that vector.
In the ATTiny chips, since there are so few Pin Change Interrupt pins (8 or less) you only need one Pin Change Interrupt vector to handle them.
You can know if "PCINT4" corresponds to a pin or a vector by the context. If you see it on a pin then it is a pin. If you see it in code with _vect after it then it's a vector.

Perfect answer, thanks!

That is simply the difference between an external interrupt INTx and a pin change interrupt PCINT. The first is an interrupt for a single pin. The second is an interrupt for a complete group of pins. Normally this group is a complete port. As the Attiny85 only has one port, this is the case here. So the whole group is only 1 single interrupt source. Thus it only has one interrupt vector named PCINT0_vect.
A pin change interrupt triggers, when any of the pins under it's supervision changes. You can remove pins from it's supervision by masking them with the PCMSK register.
So the interrupt vector PCINT_vect will be triggered by every change on any of the pins, that are not masked out. It is up to you to check, which one changed it's level.

On bigger microcontrollers, there are more pins and mostly also most of them are connected to a pin change interrupt. Here mostly every complete port is connected to a single pin change interrupt. Thus the corresponding registers are additionally marked with a number (PCINT0_vect as the interrupt vector for the first port, ...)

Ok, so in fact for ATtiny45, PCINT0_vect works for all the pins 0..5? Then why put "PCINT1", "PCINT2" on the pinout schematics? Then PCINT0_vect should be called PCINT_vect0, don't you think so? Because it's the the "first" vector of pin change interrupts... With a naming like PCINTx_vect, we could think it's relative to the pin x since the pinout schematics shows PCINTx for every pin x=0..5.

I cannot say, why they named them as such, that is only known by Atmel. A PCINT_vect0 doesn't exist, because their naming convention is <Interrupt Name>_vect for the interrupt vectors. For the pin description I think, they wanted to keep it short. On bigger microcontrollers, the PCINT pins are numbered completely though, so on the Atmega328P (from the Uno) there are pins up to PCINT20

Basically you need to understand what Pin Change interrupts are. Those things are normally explained rather detailed in the datasheet. For example this sentence from the External Interrupt section of the datasheet: "Pin change interrupts PCI will trigger if any enabled PCINT[5:0] pin toggles."

I know what they are, and I do understand they are grouped, but I don't understand the naming...

For example for the 328p, PCINT0_vect covers which group of pins? Idem for PCINT1_vect? I can imagine they can handle up to 8 pins each?

If you look at the register description for the corresponding mask registers in the datasheet, you see that each bit of the mask is marked with the corresponding pin name. Also in the description of the PCI enable bits you find the information, for which pins they are used and also which mask register.

Let us continue this discussion in chat.

You can enable/disable Pin Change INTerrupts for individual pins using the Pin Change Mask Register PCMSK.
The names on the pins map the bit in PCMSK to the physical pin.
You find more information in section 9.3.4 on p. 52 in the ATtiny85 Data Sheet

I did this with PCMSK = 0b00000111; indeed. But why don't we use PCINT1_vect? The pinout schematics mentions "PCINT1", why don't we use it?

Section 9.1 lists all available interrupt vectors. Pin Change Interrupts are grouped to not waste resources. Only INTx is dedicated to a single pin. It is also much more powerful, als it can be triggered on rising or falling edges instead of each change. ATtiny85 only has with INT0 one dedicated pin for that.

I understand that they are grouped to not waste resources @Kwasmich, but then if all pins can be handled with just PCINT0_vect alone, isn't this a mistake in the schematics to write PCINT0, PCINT1, ..., PCINT5?

No, again, it is to show you wich bit in PCMSK corresponds to which physical pin. Otherwise you would not know what pin is affected. The naming is ambiguos, for sure.


text:
Determine if Arduino is rapidly pulsed on and off several times
Greetings fellow humans!
I've set myself the task of ascertaining whether an Arduino has been rapidly power cycled to force it into a setup state, a feature common with many IoT devices. So I essentially need to keep a count - of, say, three - prior on/off cycles. I could look at a custom bootloader that stores a power-on count in EEPROM then check if the attempts are >= 3 once the sketch is running (resetting the count), but I'm concerned that the EEPROM data could become corrupted during the cycle, or the the power cycle would be so rapid for even a bootloader to complete the count at all.
So, I figure I need another solution: an external counter, powered by the Arduino, that increments each time the Arduino receives power, but doesn't rely on the Arduino getting so far as running anything of consequence to keep count.
Could some kind soul point me in the direction of a discrete counter solution that would fit the task?  The simpler (fewer discrete components) the better.
Thanks!
SOLVED: less-than-discrete but fully functional solution adopted; noted in comments. Thanks for the feedback.

Greetings fellow humans! -- How dare you! I am not human!

Hello, Voldemort, good to see, that you are also an enthusiast of muggle technology XD

delete the bootloader and count the resets as first in sketch. on some MCUs a reset doesn't erase SRAM so a not initialized variable could hold the count. some MCUs have RTC memory, which is not cleared at reset.

@Juraj: Keeping the count in SRAM (in the .noinit section) would only work for warm resets. The OP seems to be concerned with power cycles.

Thanks for the feedback guys. I settled on a reasonably trivial additive resistance PWM signal fed by a decade counter. Works a treat.

Normally you wouldn't.
How I would implement it is:

Have the MCU monitor the incoming power
Provide a large-ish reservoir of power (capacitor) to run the MCU for a short time
Isolate the incoming power monitoring from the reservoir with a diode

When the power is removed the MCU runs off the stored power in the capacitor. The MCU then sees that the power is removed (by 1 above) and maybe reduces its power by turning off as much as it can to prolong the runtime. If the power is re-applied before the reservoir runs out then it enters the setup state.  If the reservoir runs out, then not much really happens.
For example:

simulate this circuit – Schematic created using CircuitLab
The size of the capacitor will determine the runtime. You may also choose to replace the capacitor with an "LC PI" filter to give more runtime but at the cost of space:

simulate this circuit

Thanks for the feedback. I use a similar technique to buy enough time on power loss to ensure a graceful shutdown where necessary. However...  I dug out a bunch of 74LS90s and, through additive serial resistance, came up with a solution that near enough fits the criteria.


text:
WS2812 Stair lighting - not all LEDS lighting up
I'm doing a Arduino based stair light project and have a little problem with the code. I have used Simon Jowett's code from the instructable website which after a couple of tweaks works perfect. Apart from the final section, the waterfall effect. The original project used 117 WS2812 LED's I'm using 188. When the white LED's trigger running up or down the stairs they work fine on all 188, the breathe LED's light up on the first and last LED too. But the waterfall effect stops at LED 117. Can anyone see if there is somewhere else that I need to change the amount of LED's in the code apart from here Adafruit_NeoPixel strip = Adafruit_NeoPixel(188, PIN, NEO_GRB + NEO_KHZ800);? Thanks
// "Bling" up your Staircase By Simon Jowett November 2014
// Thanks to the Neopxel Library by Adafruit

#include <Adafruit_NeoPixel.h>
//#define LDRSensor 1
#define PIN 3

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(188, PIN, NEO_GRB + NEO_KHZ800);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel.  Avoid connecting
// on a live circuit...if you must, connect GND first.

// Set up Variables
 unsigned long timeOut=60000; // timestamp to remember when the PIR was triggered.
 int downUp = 0;              // variable to rememer the direction of travel up or down the stairs
 int alarmPinTop = 5;        // PIR at the top of the stairs
 int alarmPinBottom =7;      // PIR at the bottom of the stairs
 int alarmValueTop = LOW;    // Variable to hold the PIR status
 int alarmValueBottom = LOW; // Variable to hold the PIR status
 int ledPin = 13;           // LED on the arduino board flashes when PIR activated
 int LDRSensor = A0;        // Light dependant resistor
 int LDRValue = 0;          // Variable to hold the LDR value
 int colourArray[350];      // An array to hold RGB values
 int change = 1;            // used in 'breathing' the LED's
 int breathe = 0;           // used in 'breathing' the LED's

void setup() {
   strip.begin();
   strip.show(); // Initialize all pixels to 'off'
   Serial.begin (9600);  // only requred for debugging
   pinMode(ledPin, OUTPUT);  // initilise the onboard pin 13 LED as an indicator
   pinMode(alarmPinTop, INPUT_PULLUP);     // for PIR at top of stairs initialise the input pin and use the internal restistor
   pinMode(alarmPinBottom, INPUT_PULLUP);  // for PIR at bottom of stairs initialise the input pin and use the internal restistor
   delay (100); // it takes the sensor 2 seconds to scan the area around it before it can
   //detect infrared presence.
   for (int i=0 ;i < 350; i++)  { // initilise the colourArray to zero
   colourArray[i]=0;
   }
}

void loop() {

  LDRValue = analogRead(LDRSensor);
  Serial.println(LDRValue);

  if (timeOut+57000 < millis()) {        // idle state - 'breathe' the top and bottom LED to show program is looping

     breathe = breathe + change;
     strip.setPixelColor(0,0,0,breathe);
     strip.setPixelColor(187,0,0,breathe);
     strip.show();
     if (breathe == 100 || breathe == 0) change = -change;      // breathe the LED from 0 = off to 100 = fairly bright
     if (breathe == 100 || breathe == 0) delay (300);           // Pause at beginning and end of each breath
     delay(25);
  }

  if (LDRValue > 1010) {        // only switch on LED's at night when LDR senses low light conditions - you may have to change the number for your circumstances!

    alarmValueTop = digitalRead(alarmPinTop);        // Constantly poll the PIR at the top of the stairs
    alarmValueBottom = digitalRead(alarmPinBottom);  // Constantly poll the PIR at the bottom of the stairs

    if (alarmValueTop == HIGH && downUp != 2)  {      // the 2nd term allows timeOut to be contantly reset if one lingers at the top of the stairs before decending but will not allow the bottom PIR to reset timeOut as you decend past it.
      timeOut=millis();  // Timestamp when the PIR is triggered.  The LED cycle wil then start.
      downUp = 1;
      topdown();         // lights up the strip from top down
    }

    if (alarmValueBottom == HIGH && downUp != 1)  {    // the 2nd term allows timeOut to be contantly reset if one lingers at the bottom of the stairs before decending but will not allow the top PIR to reset timeOut as you decend past it.
      timeOut=millis();    // Timestamp when the PIR is triggered.  The LED cycle wil then start.
      downUp = 2;
      bottomup();         // lights up the strip from bottom up
    }
    if (timeOut+10000 < millis() && timeOut+15000 < millis()) {    //switch off LED's in the direction of travel.
       if (downUp == 1) {
          colourWipeDown(strip.Color(0, 0, 0), 50); // Off
       }
       if (downUp == 2)  {
        colourWipeUp(strip.Color(0, 0, 0), 50);   // Off
       }
      downUp = 0;
      //   for (int i=0 ;i < 350; i++)  {          // Depending on your preference you may want to include this loop to clear out the colourArray
      //    colourArray[i]=0;
      // }
    }

    if (timeOut+15000 < millis() && timeOut+54999 > millis()) waterfall();    // Waterfall effect to play between these times after a PIR trigger.

    if (timeOut+55000 < millis() && timeOut+56999 > millis()) fade();   // Fade/switch off LED's
  }
}

 void topdown() {
    Serial.println ("detected top");                // Helpful debug message
    colourWipeDown(strip.Color(50, 50, 30), 10);    // Warm White
    for(int i=0; i<3; i++) {                        // Helpful debug indication flashes led on Arduino board twice
      digitalWrite(ledPin,HIGH);
      delay(200);
      digitalWrite(ledPin,LOW);
      delay(200);
    }
 }

 void bottomup() {
    Serial.println ("detected bottom");          // Helpful debug message
    colourWipeUp(strip.Color(50, 50, 30), 10);   // Warm White
    for(int i=0; i<3; i++) {                     // Helpful debug indication flashes led on Arduino board twice
      digitalWrite(ledPin,HIGH);
      delay(200);
      digitalWrite(ledPin,LOW);
      delay(200);
    }
  }

 // Fill the dots one after the other with a color
 void colourWipeDown(uint32_t c, uint8_t wait) {
   for(uint16_t i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      strip.show();
      delay(wait);
  }
 }

 // Fill the dots one after the other with a color
 void colourWipeUp(uint32_t c, uint8_t wait) {
   for(uint16_t i=strip.numPixels(); i < -1; i--) {
      strip.setPixelColor(i, c);
      strip.show();
      delay(wait);
  }
 }

 // Play the Waterfall effect
 void waterfall(){
    for(int i= 347; i>-1; i--) {            // Shift the RGB colours down in the colourArray[]
        colourArray[i+3]=colourArray[i];
        }
      colourArray[0] = random(0,20);        // Genearate the red component of the 1st LED at the top of the stairs
      colourArray[1] = random(0,40);        // Genearate the green component of the 1st LED at the top of the stairs
      colourArray[2] = random(10,70);       // Genearate the blue component of the 1st LED at the top of the stairs

      for (int k=0; k<351; k=k+3)   {       // Set and send the colours to the strip
       uint32_t c = strip.Color(colourArray[k],colourArray[k+1],colourArray[k+2]);
       strip.setPixelColor(((k+3)/3)-1,c);
       }

      strip.show();      // and display the result
      delay(35);         // delay to simulate running water
 }

 // Play the LED fade out
 void fade(){
 for (int j = 0; j <70; j++) {
   for(int i=350; i>-1; i--) {
     colourArray[i]=colourArray[i]-1;      // reduce intensity of light by 1
     if (colourArray[i] <= 0 ) colourArray[i] = 0;
   }
   for (int k=0; k<351; k=k+3)   {
     uint32_t c = strip.Color(colourArray[k],colourArray[k+1],colourArray[k+2]);
     strip.setPixelColor(((k+3)/3)-1,c);
   }
  strip.show();
  delay(60);
  }
 breathe = 0;
 change = 1;
 }

Added a link to the Instructable website.  Please comment if not correct.

Is there a specific reason, why you use an int array for the LED color values, instead of the CRGB typed array, that is used in all the NeoPixel examples?

This line in the code:
 int colourArray[350];      // An array to hold RGB values

...contains 3 values for each LED.  But 350 / 3 is 116.67.  This value should likely have been 117 * 3 = 351 for the original code.  And for the posted code using 188 LEDs this likely should be 188 * 3 = 546.
This same problem of indexing into the colourArray repeats several more times in the code where the array is cleared out, assigned random values and used to control the LEDs.  Normally, well written code uses "#define" directive to set such values once at the beginning of the code allowing the compiler to make adjustments when compiling / uploading the Arduino sketch.
The "#define" used for Arduino sketches is the same as used in C programming.  (As Arduino sketches are actually C programs.) Normally, defines are found at the top of a file.  Defines are a way of substituting an meaningful name for something a bit hard to understand at first.  We can even use a bit of math to keep errors down as the compiler will solve it for us before uploading the code:
#define LED_NUMBER_OF (3*188)

Later in the code we can use the define:
int colourArray[LED_NUMBER_OF];      // An array to hold RGB values

Still later in the code we can use the define again:
for (int i=0 ;i < LED_NUMBER_OF; i++)  { // initilise the colourArray to zero
  colourArray[i]=0;
}

Thanks st2000, I've adjusted the code as you suggested will I need to do the same for the waterfall section?

Probably.  The quick (and maybe good enough) approach is to search for the number 350 and decide if what you want can be achieved by substituting 546 or the define LED_NUMBER_OF of you went that route.

I've just tried the edited code but now the LED's won't work at all?? I'm sure its something I've done wrong.
#include <Adafruit_NeoPixel.h>

#define PIN 3

#define LED_NUMBER_OF (3*188)

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(188, PIN, NEO_GRB + NEO_KHZ800);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel.  Avoid connecting
// on a live circuit...if you must, connect GND first.

// Set up Variables
 unsigned long timeOut=60000; // timestamp to remember when the PIR was triggered.
 int downUp = 0;              // variable to rememer the direction of travel up or down the stairs
 int alarmPinTop = 5;        // PIR at the top of the stairs
 int alarmPinBottom =7;      // PIR at the bottom of the stairs
 int alarmValueTop = LOW;    // Variable to hold the PIR status
 int alarmValueBottom = LOW; // Variable to hold the PIR status
 int ledPin = 13;           // LED on the arduino board flashes when PIR activated
 int LDRSensor = A0;        // Light dependant resistor
 int LDRValue = 0;          // Variable to hold the LDR value
 int colourArray[LED_NUMBER_OF];      // An array to hold RGB values
 int change = 1;            // used in 'breathing' the LED's
 int breathe = 0;           // used in 'breathing' the LED's

void setup() {
   strip.begin();
   strip.show(); // Initialize all pixels to 'off'
   Serial.begin (9600);  // only requred for debugging
   pinMode(ledPin, OUTPUT);  // initilise the onboard pin 13 LED as an indicator
   pinMode(alarmPinTop, INPUT_PULLUP);     // for PIR at top of stairs initialise the input pin and use the internal restistor
   pinMode(alarmPinBottom, INPUT_PULLUP);  // for PIR at bottom of stairs initialise the input pin and use the internal restistor
   delay (100); // it takes the sensor 2 seconds to scan the area around it before it can
   //detect infrared presence.
   for (int i=0 ;i < LED_NUMBER_OF; i++)  { // initilise the colourArray to zero
   colourArray[i]=0;
   }
}

void loop() {

  LDRValue = analogRead(LDRSensor);
  Serial.println(LDRValue);

  if (timeOut+57000 < millis()) {        // idle state - 'breathe' the top and bottom LED to show program is looping

     breathe = breathe + change;
     strip.setPixelColor(0,0,0,breathe);
     strip.setPixelColor(187,0,0,breathe);
     strip.show();
     if (breathe == 100 || breathe == 0) change = -change;      // breathe the LED from 0 = off to 100 = fairly bright
     if (breathe == 100 || breathe == 0) delay (300);           // Pause at beginning and end of each breath
     delay(25);
  }

  if (LDRValue > 1010) {        // only switch on LED's at night when LDR senses low light conditions - you may have to change the number for your circumstances!

    alarmValueTop = digitalRead(alarmPinTop);        // Constantly poll the PIR at the top of the stairs
    alarmValueBottom = digitalRead(alarmPinBottom);  // Constantly poll the PIR at the bottom of the stairs

    if (alarmValueTop == HIGH && downUp != 2)  {      // the 2nd term allows timeOut to be contantly reset if one lingers at the top of the stairs before decending but will not allow the bottom PIR to reset timeOut as you decend past it.
      timeOut=millis();  // Timestamp when the PIR is triggered.  The LED cycle wil then start.
      downUp = 1;
      topdown();         // lights up the strip from top down
    }

    if (alarmValueBottom == HIGH && downUp != 1)  {    // the 2nd term allows timeOut to be contantly reset if one lingers at the bottom of the stairs before decending but will not allow the top PIR to reset timeOut as you decend past it.
      timeOut=millis();    // Timestamp when the PIR is triggered.  The LED cycle wil then start.
      downUp = 2;
      bottomup();         // lights up the strip from bottom up
    }
    if (timeOut+10000 < millis() && timeOut+15000 < millis()) {    //switch off LED's in the direction of travel.
       if (downUp == 1) {
          colourWipeDown(strip.Color(0, 0, 0), 50); // Off
       }
       if (downUp == 2)  {
        colourWipeUp(strip.Color(0, 0, 0), 50);   // Off
       }
      downUp = 0;
      //   for (int i=0 ;i < 350; i++)  {          // Depending on your preference you may want to include this loop to clear out the colourArray
      //    colourArray[i]=0;
      // }
    }

    if (timeOut+15000 < millis() && timeOut+54999 > millis()) waterfall();    // Waterfall effect to play between these times after a PIR trigger.

    if (timeOut+55000 < millis() && timeOut+56999 > millis()) fade();   // Fade/switch off LED's
  }
}

 void topdown() {
    Serial.println ("detected top");                // Helpful debug message
    colourWipeDown(strip.Color(50, 50, 30), 10);    // Warm White
    for(int i=0; i<3; i++) {                        // Helpful debug indication flashes led on Arduino board twice
      digitalWrite(ledPin,HIGH);
      delay(200);
      digitalWrite(ledPin,LOW);
      delay(200);
    }
 }

 void bottomup() {
    Serial.println ("detected bottom");          // Helpful debug message
    colourWipeUp(strip.Color(50, 50, 30), 10);   // Warm White
    for(int i=0; i<3; i++) {                     // Helpful debug indication flashes led on Arduino board twice
      digitalWrite(ledPin,HIGH);
      delay(200);
      digitalWrite(ledPin,LOW);
      delay(200);
    }
  }

 // Fill the dots one after the other with a color
 void colourWipeDown(uint32_t c, uint8_t wait) {
   for(uint16_t i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      strip.show();
      delay(wait);
  }
 }

 // Fill the dots one after the other with a color
 void colourWipeUp(uint32_t c, uint8_t wait) {
   for(uint16_t i=strip.numPixels(); i < -1; i--) {
      strip.setPixelColor(i, c);
      strip.show();
      delay(wait);
  }
 }

 // Play the Waterfall effect
 void waterfall(){
    for(int i= 350; i>-1; i--) {            // Shift the RGB colours down in the colourArray[]
        colourArray[i+3]=colourArray[i];
        }
      colourArray[0] = random(0,20);        // Genearate the red component of the 1st LED at the top of the stairs
      colourArray[1] = random(0,40);        // Genearate the green component of the 1st LED at the top of the stairs
      colourArray[2] = random(10,70);       // Genearate the blue component of the 1st LED at the top of the stairs

      for (int k=0; k<350; k=k+3)   {       // Set and send the colours to the strip
       uint32_t c = strip.Color(colourArray[k],colourArray[k+1],colourArray[k+2]);
       strip.setPixelColor(((k+3)/3)-1,c);
       }

      strip.show();      // and display the result
      delay(35);         // delay to simulate running water
 }

 // Play the LED fade out
 void fade(){
 for (int j = 0; j <70; j++) {
   for(int i=350; i>-1; i--) {
     colourArray[i]=colourArray[i]-1;      // reduce intensity of light by 1
     if (colourArray[i] <= 0 ) colourArray[i] = 0;
   }
   for (int k=0; k<351; k=k+3)   {
     uint32_t c = strip.Color(colourArray[k],colourArray[k+1],colourArray[k+2]);
     strip.setPixelColor(((k+3)/3)-1,c);
   }
  strip.show();
  delay(60);
  }
 breathe = 0;
 change = 1;
 }
~~~~~~

Likely you needed to use the LED_NUMBER_OF define where ever you access the colourArray array.  I see you changed 350 to 351 in some places.  Perhaps if you tried using  LED_NUMBER_OF instead of 351.  Also, note there is one line of code where you need to use (LED_NUMBER_OF - 3) because you add 3 to the index of the FOR loop inside the loop.  And it is bad to access locations past the end of any array!

Try not to re-post your question as an answer. Remember that stack exchange / stack overflow web sites are trying to become a list of searchable questions and answers. This will make it really confusing for people with similar issues.

if your program is working can you do 2 things?  1. Delete this answer and if you need to edit your question should you wish to add additional information to make the question better.  2. If an answer is correct (that is, if the answer help fix the issue in the question), please mark it correct so that others can see what worked for you.  Thanks.


text:
ARDUINO + SIM808 POST ERROR 400 BAD REQUEST
Please, I need help with debugging communications through a SIM808 Device I'm using alongside an Arduino Uno R3 as a prototype for a tracking device. The sketch is provided below.
#include <DFRobot_sim808.h>
#include <SoftwareSerial.h>

#define mydelay 10000
DFRobot_SIM808 sim808(&Serial);
char http_cmd[200] = "POST /api/tracker/ HTTP/1.1\r\nContent-Type: application/json\r\nContent-Length: 72\r\nHost: haulr.herokuapp.com\r\n\r\n{ \"trackerId\": \"1111\",\"weight\": ";
char mybuffer[145];
int count = 142;
long current = 0;
String longitude, latitude;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.begin(9600);

//  //******** Initialize sim808 module *************
  while(!sim808.init()) {
      delay(1000);
      Serial.print("Sim808 init error\r\n");
  }
  delay(3000);
  Serial.println(sizeof(http_cmd));

  //*********** Attempt DHCP *******************
  while(!sim808.join(F("cmnet"))) {
      Serial.println("Sim808 join network error");
      delay(2000);
  }

  //************ Successful DHCP ****************
  Serial.print("IP Address is ");
  Serial.println(sim808.getIPAddress());
    //************* Turn on the GPS power************
  if( sim808.attachGPS())
      Serial.println("Open the GPS power success");
  else
      Serial.println("Open the GPS power failure");
  current = millis();
}

bool mylocation(){
  bool control = LOW;
  long prevfix = millis();
  Serial.println("im here");
  while(millis() - prevfix < 3000){
    if (1 > 0){
      Serial.println("got a fix");
      latitude = String(sim808.GPSdata.lat,6);
      longitude = String(sim808.GPSdata.lon,6);
      control = HIGH;
      break;
    }
  }
  if(control){
    delay(1000);
     sim808.detachGPS();
  }
  return control;
}

void loop() {

  // put your main code here, to run repeatedly:
  if (millis() - current > mydelay){
  sim808.attachGPS();
  bool getloc = mylocation();
  if (getloc){
    float weight = 10;
    if (weight <= 0) weight = 0.00;
    latitude = (String) weight + ",\"location\": \"" + latitude + "," + longitude + "\" }";
    int cnt = count;
    for (int i = 0; i <= latitude.length(); i++){
     http_cmd[cnt++] = latitude[i];
    }
    postData();
  }
  current = millis();
 }
}
void postData(){
  delay(1000);
  if (!sim808.is_connected()){
  label:
  //*********** Establish a TCP connection ************
  if(!sim808.connect(TCP,"haulr.herokuapp.com", 80)) {
      Serial.println("Connect error");
      goto label;
  }else{
      Serial.println("Connect haulr.herokuapp.com success");
  }
 }

  //*********** Send a POST request *****************
  Serial.println("waiting to fetch...");
  sim808.send(http_cmd, sizeof(http_cmd) - 1);
  while (true) {
      int ret = sim808.recv(mybuffer, sizeof(mybuffer)-1);
      if (ret <= 0){
          Serial.println("fetch over...");
          break;
      }
      mybuffer[ret] = '\0';
      Serial.print("Recv: ");
      Serial.print(ret);
      Serial.print(" bytes: ");
      Serial.println(mybuffer);
      break;
  }

  //************* Close TCP or UDP connections **********
  sim808.close();

  //*** Disconnect wireless connection, Close Moving Scene *******
  sim808.disconnect();
}

After uploading the sketch, I got varying responses from the SIM808. After posting the data, I checked the database for updates and got none. I have used POST MAN severally to update the database but every other update (data) sent from the device is not stored. Kindly find the snippets of the responses received below. This is the only bit left at this stage of the prototyping phase and my team needs me to resolve this very quickly.
AT
AT+CFUN=1
AT+CPIN?
182
AT+CSTT="cmnet","",""
AT+CIICR
AT+CIFSR
IP Address is 10.31.234.248
AT+CGNSPWR=1
AT+CGNSTST=1
Open the GPS power success
AT+CGNSPWR=1
AT+CGNSTST=1
im here
got a fix
AT+CGNSPWR=0
AT+CIPSTATUS
AT+CIPSTART="TCP","haulr.herokuapp.com",80
Connect haulr.herokuapp.com success
waiting to fetch...
AT+CIPSEND=181
POST /api/tracker/ HTTP/1.1
Content-Type: application/json
Content-Length: 70
Host: haulr.herokuapp.com

{ "trackerId": "1111","weight": 10.00,"location": "2.511895,7.161656" } Recv: 144 bytes: HTTP/1.1 400 Bad Request
Server: Cowboy
Connection: keep-alive
X-Powered-By: Express
Content-Security-Policy: default-src 'self'
X-Content-
AT+CIPSTATUS
AT+CIPSHUT
AT+CGNSPWR=1
AT+CGNSTST=1
im here
got a fix
AT+CGNSPWR=0
AT+CIPSTATUS
AT+CIPSTART="TCP","haulr.herokuapp.com",80
Connect haulr.herokuapp.com success
waiting to fetch...
AT+CIPSEND=181
POST /api/tracker/ HTTP/1.1
Content-Type: application/json
Content-Length: 70
Host: haulr.herokuapp.com

{ "trackerId": "1111","weight": 10.00,"location": "2.511895,7.161656" } fetch over...
AT+CIPSTATUS
AT+CIPSHUT
AT+CGNSPWR=1
AT+CGNSTST=1
im here
got a fix
AT+CGNSPWR=0
AT+CIPSTATUS
AT+CIPSTART="TCP","haulr.herokuapp.com",80
Connect haulr.herokuapp.com success
waiting to fetch...
AT+CIPSEND=181
POST /api/tracker/ HTTP/1.1
Content-Type: application/json
Content-Length: 70
Host: haulr.herokuapp.com

{ "trackerId": "1111","weight": 10.00,"location": "2.511895,7.161656" } Recv: 144 bytes: HTTP/1.1 400 Bad Request
Server: Cowboy
Connection: keep-alive
X-Powered-By: Express
Content-Security-Policy: default-src 'self'
X-Content-
AT+CIPSTATUS
AT+CIPSHUT
AT+CGNSPWR=1
AT+CGNSTST=1
im here
got a fix
AT+CGNSPWR=0
AT+CIPSTATUS
AT+CIPSTART="TCP","haulr.herokuapp.com",80
Connect haulr.herokuapp.com success
waiting to fetch...
AT+CIPSEND=181
POST /api/tracker/ HTTP/1.1
Content-Type: application/json
Content-Length: 70
Host: haulr.herokuapp.com

{ "trackerId": "1111","weight": 10.00,"location": "2.511895,7.161656" } Recv: 144 bytes: HTTP/1.1 400 Bad Request
Server: Cowboy
Connection: keep-alive
X-Powered-By: Express
Content-Security-Policy: default-src 'self'
X-Content-
AT+CIPSTATUS
AT+CIPSHUT

While troubleshooting, I later observed that three of the sent posts actually received responses stated as "Bad Request"  alongside some other headers. I don't know what the issue could be. Please, kindly advise me on what steps I need to take. Thanks.

The HyperText Transfer Protocol (HTTP) 400 Bad Request response status code indicates that the server cannot or will not process the request due to something that is perceived to be a client error .  You might posting the data in wrong format or your request format is wrong, only those cases you get 400 as status.

I have tried checking the format of the post request. I have also run it by some of my colleagues. We cannot pick out any error from it yet. Is there anything in that post request that could flag off an error? Thanks in advance for your response??

had you tried wit postman to send post request to same server with same data format?

Yes, I tried with postman. It worked quite well but I couldn't get it to work through my arduino. I eventually changed the content type to Content-Type: application/x-www-form-urlencoded. Then I sent the data in a non-json format. This worked well with the arduino and I'm sticking with this method of solving the problem and a lot of others. Thanks a lot.


text:
Grid based maze - robot stops at every square
I need a little bit of help.
I'm working on a school project where a robot with 3 ultrasonic sensors needs to go through grid based maze (5x5) and then draw its map.
But I got stuck. I'm trying to let the robot stop close to the center of a square, let it ping the position of obstacles, write out the positions and then let it choose the next direction where to go.
I tried it with the ollowing code, but without any success.
(main part is in loop function)
#include <AFMotor.h>
#include <elapsedMillis.h>
#include <NewPing.h>
#include <MPU6050_tockn.h>
#include <Wire.h>

#define SONAR_NUM 3
#define TRIGGER_PIN 45
#define ECHO_PIN 44
#define L_TRIG_PIN 36
#define L_ECHO_PIN 37
#define R_TRIG_PIN 30
#define R_ECHO_PIN 31
#define MAX_DISTANCE 200
#define eps 5.0
#define PING_INTERVAL 250

unsigned long pingTimer[SONAR_NUM];
unsigned int cm[SONAR_NUM];
uint8_t currentSensor = 0;

MPU6050 mpu6050(Wire);
AF_DCMotor motorL(3);
AF_DCMotor motorR(4);

NewPing sonar[SONAR_NUM] = {
  NewPing( R_TRIG_PIN, R_ECHO_PIN, MAX_DISTANCE ),
  NewPing( L_TRIG_PIN, L_ECHO_PIN, MAX_DISTANCE ),
  NewPing( TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE  )
};

long timer = 0;
bool WallRight, WallLeft, WallFront,WallBack,
     Turned180, TurnedLeft, TurnedRight;
int Distance = 0, modulo;
// Direction 1: front, 2: right, 3: back, 4: left
int Direction = 2;
int x = 0;
int y = 0;
int dx = 1;
int dy = 0;
float Angle, NewAngle;
long TimerFront = 0;
long StopTimer = 0;

struct Array {
  bool Left;
  bool Right;
  bool Front;
  bool Back;
  int StrucDirection;
};

Array Map[5][5];

void setup()
{
  Serial.begin(115200);
  Wire.begin();

  mpu6050.begin();
  mpu6050.calcGyroOffsets(true);

  motorL.setSpeed(85);
  motorR.setSpeed(80);

  pingTimer[0] = millis() + 75;
  for ( uint8_t i = 1; i < SONAR_NUM; i++ )
  {
    // Set the starting time for each sensor.
    pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
  }

  Map[0][0].Left = true;
  Map[0][0].Right = true;
  Map[0][0].Front = false;
  Map[0][0].Back = true;
  Map[0][0].StrucDirection = 2;
}

void loop()
{
  // Loop through all the sensors.
  for (uint8_t i = 0; i < SONAR_NUM; i++)
  {
    // Is it this sensor's time to ping?
    if (millis() >= pingTimer[i])
    {
      // Set next time this sensor will be pinged.
      pingTimer[i] += PING_INTERVAL * SONAR_NUM;

      // Make sure previous timer is canceled before
      // starting a new ping (insurance).
      sonar[currentSensor].timer_stop();

      // Sensor being accessed.
      currentSensor = i;
      // Make distance zero in case there's no ping echo for this sensor.
      cm[currentSensor] = 0;
      // Do the ping (processing continues,
      // interrupt will call echoCheck to look for echo).
      sonar[currentSensor].ping_timer(echoCheck);
    }
  }

  if ( ( modulo >= 7 ) && ( modulo <= 9 ) ||
       ( cm[2] < 7 && cm[2] > 0 ) )
  {
    if( millis() - StopTimer >= 1000 )
    {
      motorL.run(RELEASE);
      motorR.run(RELEASE);
      //Serial.println(dx);
      //Serial.println(dy);
      if( x + dx < 5 && x + dx >= 0 && y + dy < 5 && y + dy >= 0 )
      {
        x = x + dx;
        y = y + dy;
      }

      Obstacles();
    }
    DecideWhereNext();
    modulo = 0;
  }
}

void TurnLeft()
{
  for (uint8_t i = 0; i < SONAR_NUM; i++)
    pingTimer[i] = -1;

  mpu6050.update();
  motorL.setSpeed(150);
  motorR.setSpeed(145);
  Angle = mpu6050.getAngleZ();
  NewAngle = Angle + 86.0;
  //Serial.println(Angle);
  //Serial.println(NewAngle);

  while(abs(Angle - NewAngle) > eps)
  {
    if( millis() - timer > 50 )
    {
        mpu6050.update();
        Angle = mpu6050.getAngleZ();
        //Serial.println(Angle);
        timer = millis();
    }
    motorR.run(FORWARD);
    motorL.run(BACKWARD);

  }

  motorL.run(RELEASE);
  motorR.run(RELEASE);
  TurnedLeft = true;

  if(dy == 1)
  {
    dx=-1;
    dy=0;
    Direction = 4;
  }
  else if ( dy == -1 )
  {
    dx=1;
    dy=0;
    Direction = 2;
  }
  else if( dx == 1 )
  {
    dx=0;
    dy=1;
    Direction = 1;
  }
  else
  {
    dx=0;
    dy=-1;
    Direction = 3;
   }

   pingTimer[0] = millis();
   for (uint8_t i = 1; i < SONAR_NUM; i++)
     pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
}

void TurnRight()
{
  for (uint8_t i = 0; i < SONAR_NUM; i++)
    pingTimer[i] = -1;

  mpu6050.update();
  motorL.setSpeed(165);
  motorR.setSpeed(170);
  Angle = mpu6050.getAngleZ();
  NewAngle = Angle - 84.0;
  //Serial.println(Angle);
  //Serial.println(NewAngle);

  while( abs( Angle - NewAngle ) > eps )
  {
    if( millis() - timer > 50 )
    {
      mpu6050.update();
      Angle = mpu6050.getAngleZ();
      //Serial.println(Angle);
      timer = millis();
    }
    motorR.run(BACKWARD);
    motorL.run(FORWARD);
  }

  motorL.run(RELEASE);
  motorR.run(RELEASE);

  if( dy == 1 )
  {
    dx = 1;
    dy = 0;
    Direction = 2;
  }
  else if( dy == -1 )
  {
    dx = -1;
    dy = 0;
    Direction = 4;
  }
  else if( dx == -1 )
  {
    dx = 0;
    dy = 1;
    Direction = 1;
  }
  else
  {
    dx = 0;
    dy = -1;
    Direction = 3;
  }

  pingTimer[0] = millis();

  for (uint8_t i = 1; i < SONAR_NUM; i++)
    pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;

}

void Turn180()
{
  for (uint8_t i = 0; i < SONAR_NUM; i++)
    pingTimer[i] = -1;
  mpu6050.update();
  motorR.setSpeed(158);
  motorL.setSpeed(174);
  Angle = mpu6050.getAngleZ();
  NewAngle = Angle + 173.0;
  //Serial.println(Angle);
  //Serial.println(NewAngle);

  while(abs(Angle - NewAngle) > eps)
  {
    if( millis() - timer > 50 )
    {
        mpu6050.update();
        Angle = mpu6050.getAngleZ();
        //Serial.println(Angle);
        timer = millis();
    }

    motorR.run(FORWARD);
    motorL.run(BACKWARD);

  }

  motorL.run(RELEASE);
  motorR.run(RELEASE);

  if (dy == 1)
  {
    dx = 0;
    dy = -1;
    Direction = 3;
  }
  else if (dy == -1)
  {
    dx = 0;
    dy = 1;
    Direction = 1;
  }
  else if (dx == 1)
  {
    dx = -1;
    dy = 0;
    Direction = 4;
  }
  else if (dx == -1)
  {
    dx = 1;
    dy = 0;
    Direction = 2;
  }

  pingTimer[0] = millis();

  for (uint8_t i = 1; i < SONAR_NUM; i++)
    pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
}

void Forward()
{
  motorL.setSpeed(92);
  motorR.setSpeed(85);

  motorL.run(FORWARD);
  motorR.run(FORWARD);
}

void Obstacles()
{
  if (WallLeft)
  {
    Map[x][y].Left = true;
  }
  else
  {
    Map[x][y].Left = false;
  }

  if (WallRight)
  {
    Map[x][y].Right = true;
  }
  else
  {
    Map[x][y].Right = false;
  }

  if (WallFront)
  {
    Map[x][y].Front = true;
    Map[x][y].Back = false;
  }
  else
  {
    Map[x][y].Front = false;
    Map[x][y].Back = false;
  }

  Map[x][y].StrucDirection = Direction;

  Serial.print(" x:");
  Serial.print(x);
  Serial.print(" y:");
  Serial.print(y);
  Serial.print(" ");
  Serial.print(Map[x][y].Left);
  Serial.print(" ");
  Serial.print(Map[x][y].Right);
  Serial.print(" ");
  Serial.print(Map[x][y].Front);
  Serial.print(" ");
  Serial.print(Map[x][y].Back);
  Serial.print(" ");
  Serial.print(Map[x][y].StrucDirection);
  Serial.print(" ");
}

void echoCheck()
{
  if ( sonar[currentSensor].check_timer() )
  {
    cm[currentSensor] = sonar[currentSensor].ping_result / US_ROUNDTRIP_CM;

    pingResult( currentSensor );
  }
}

void pingResult( uint8_t sensor )
{
  modulo = cm[2] % 30;
  //Serial.print("Pravy: ");
  //Serial.println(cm[1]);
  //Serial.print("Predni: ");
  //Serial.println(cm[2]);

  if (cm[0] > 13)
  {
    WallLeft = false;
    //Serial.println("Vlevo neni prekazka");
  }
  else if (cm[0] <= 13)
  {
    WallLeft = true;
    //Serial.println("Vlevo je prekazka");
  }

  if(cm[1] > 13)
  {
    WallRight = false;
    //Serial.println(cm[1]);
    //Serial.println("Vpravo neni prekazka");
  }
  else if (cm[1] <= 13){
    WallRight = true;
    //Serial.println(cm[1]);
    //Serial.println("Vpravo je prekazka");
  }

  if(cm[2] > 13)
  {
    WallFront = false;
    WallBack = false;
  }
  else if (cm[2] <= 13)
  {
    WallFront = true;
  }

}

void DecideWhereNext()
{

  if(!Map[x][y].Front && Map[x][y].Right )
  {
    Serial.println("Forward");
    Forward();

  }
  else if(!Map[x][y].Front && !Map[x][y].Left && Map[x][y].Right)
  {
    Serial.println("Forward");
    Forward();
  }
  else if(!Map[x][y].Front && !Map[x][y].Right)
  {
    Serial.println("Right");
    TurnRight();
    Forward();

  }
  else if(Map[x][y].Front && Map[x][y].Right && !Map[x][y].Left)
  {
    TurnLeft();
    Serial.println("Left");
    Forward();
  }
  else if (Map[x][y].Front && Map[x][y].Right && !Map[x][y].Left)
  {
    Turn180();
    Serial.println("Turning 180");
    Forward();
  }

}

I'm using the NewPing library also and I tried to stop the pings of the sensors while the robot is turning with the following code:
for (uint8_t i = 0; i < SONAR_NUM; i++)
  pingTimer[i] = -1;

and start pings again with:
pingTimer[0] = millis();
for (uint8_t i = 1; i < SONAR_NUM; i++)
  pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;

as it was documented here.
I did not manage to start the pings again, so if anyone would be so kind and helped me, I would be very grateful.

what does this mean? I tried to stop the sensors ............. this is a very poor description of the observed behavior without any success .... please describe what actually happens

please add information to your question ... please do not use comments


text:
Need function to convert bool array to int- why doesnt this work?
Hey I wrote this function to convert an bool array to int:
(Math Lob included):
bool b_array[5];

int convertToInt(start_index,stop_index){
    int run=0;
    int result=0;
    for(int id=start_index;id<=stop_index;id++){
        result+=b_array[id] * pow(2.0,run);
        run++;
    }
    return result;
}

but it doesnt this work?
Thanks and kind regards
Nic

"Does not work" is a poor problem description. Explain what it actually does and what you expected it to do. Provide a minimal but complete test sketch, that shows the problem

You seem to want to convert an array of bools into the respective integer value, so e.g. { false, true, true, false} into  0b0110 = 6? Then you should use better casting, so (int)b_array[id] and (int)pow(2.0,run). Though it's a weird way to do it, since bitshifting would be more appropriate (result += b_array[id] ? (1 << run) : 0) . Also be aware of the numerical limits of your 16-bit signed int.

The pow function returns a float.  Floats are inherently inaccurate.  The index to the array has to be an int.  When you do powers of 2 with pow you don’t actually get 4.  You get 3.9999999 something.  So when that gets truncated it turns into 3 and not the 4 that you want.  Use bit shifting for integer powers of 2 and you won’t have this problem.

Thank you Guys a lot! It worked like a charm but I could not have made it without you!

Assuming little-endian bools (least significant bool first), you should use simple bit-shifting, not floating point power calculations:
for(int id=start_index;id<=stop_index;id++){
    result |= b_array[id] ? (1 << run) : 0;
    run++;
}

The ternary operation (b_array[id] ? (1 << run) : 0) means:

If b_array[id] is true,  then

Or result with 1 left-shifted run times and store in result

otherwise

Or result with 0 and store the result (no-operation).

You can simplify this in C++ because bool value promoted to an integer is 0 or 1. So (b_array[id] << run) can be used. In C there is no bool data type, so something like ((b_array[id] !=0) << run) should be used. And i like for example result = (result<<1) | b_array[id]; more (it can be result = result*2 + b_array[id] too)

Thank you for your Solution and your explaination, it worked on first try like a charm! Thank you a lot, I could not have solved that without your help!


text:
DIfferent baud rates of 434 MHZ transceiver
What are the different baud rates that I can set for 434 MHZ Transmitter? (I am using Arduino UNO and RadioHead lib to change the baud rates)

does the transmitter actually have baud rate settings?

If your 434MHz transmitter actually uses UART, you would have to look into the datasheet. If it is just a part of the RadioHead library (it seems so for me), have you searched it's documentation?


text:
Disable interrupts when doing critical things?
I've got a few functions like this that log, or do more critical things like get/save configuration variables.
/**
   Write weather data to csv
   commit: datetime,minHumidity,maxHumidity,minTemperature,maxTemperature,rainfall,irrigationRan
*/
void writeWeatherData() {
  noInterrupts();
  DBG_OUTPUT.println(F("[WEATHER DATA] Attempting to save weather data..."));
  bool writeHeader = SPIFFS.exists("/weather_data.csv") ? false : true;
  File file = SPIFFS.open("/weather_data.csv", "a");
  if (!file) {
    addPrintError("[WEATHER DATA] There was an error opening weather_data.csv for writing.");
    interrupts();
    return;
  }
  String data = "";
  if (writeHeader) {
    data += "datetime,minHumidity,maxHumidity,minTemperature,maxTemperature,rainfall,irrigationRan\r\n";
  }
  DateTime now = rtc.now();
  char buf[] = "MM/DD/YY hh:mm:ss";
  String t = now.toString(buf);
  float rainfall = getRainfall();
  data += t + "," + minHumidity + "," + maxHumidity + "," + minTemperature + "," + maxTemperature + "," + rainfall + "," + irrigationRan + "\r\n";
  if (file.print(data)) {
    DBG_OUTPUT.println(F("[WEATHER DATA] File was written."));
  } else {
    addPrintError("[WEATHER DATA] File write failed.");
  }
  file.close();
  DBG_OUTPUT.println(F("[WEATHER DATA] Task completed."));
  interrupts();
}

I surround  code with noInterrupts and interrupts however I am not sure if it is required. Assume that an interrupt is triggered at the exact moment when the above function is saving something, what exactly happens if I didn't have noInterrupts .etc.?

It depends upon the priority. whenever the interrupts comes mcu put the current processing task address in stack and goes to service the interrupt, after servicing the interrupt it goes back to the address where it left. If you don't want that task to be suspended or on hold for some moment, you can disable the interrupts during task started and enable when task ended.

if it is needed, then the library would take care

in the core of the SPIFFS implementation is the closed source ESP SDK call spi_flash_write and according to the reference it disables interrupts while writing to flash.

Interrupts happen all the time and code works just fine without locking them out. It doesn't matter if it's at the exact moment that a function is saving something - a properly written interrupt handler will save any necessary state so that whatever was interrupted can continue without problems. If it doesn't, the software will crash hard.
You should lock out interrupts as little as possible. Interrupts are used for critical timing functions and for network and other communications. Locking them out will cause these functions to be unreliable and may disrupt network connections.
The only time you should disable interrupts is when a data structure that an interrupt handler needs to use is in an inconsistent state. If an interrupt handler needs to use a shared data structure, disable interrupts before beginning to modify it outside of the interrupt handler, and re-enable them when you're done. Make sure it's as brief as possible.
Interrupt handlers should do as little as possible. They definitely should not call SPIFFS, should not call the real time clock, should not allocate or instantiate objects and should not do i/o operations. And you should not be disabling interrupts around calls to SPIFFS in hopes of making it safe for your interrupt handler to also call SPIFFS.
Take this as an example: suppose you want to use SPIFFS in both an interrupt handler and outside the interrupt handler. So you think you'll be clever and disable interrupts before you call SPIFFS outside the interrupt handler. Do you know exactly how SPIFFS works? Do you know whether SPIFFS uses any other functions that you might need to disable interrupts for in other parts of your code so that the interrupt handler won't disrupt them? Do you know for certain that SPIFFS doesn't allocate memory temporarily? Imagine that it does - now you also need to find every place in your code that might allocate memory and lock out interrupts around it, too. And maybe SPIFFS doesn't allocate memory - but do you know that SPIFFS in the future will never allocate memory?
You can't make assumptions about exactly how modules that you call are implemented, or how they'll be implemented in the future.
Unless you seriously know what you're doing, on microcontrollers like Arduinos, the ESP8266 and the ESP32, the best thing an interrupt handler can do is just set a flag to indicate that the interrupt occurred, and let code in the loop() check for the flag. The flag should most likely just be a simple Boolean variable declared as volatile so that the C compiler is aware that its value may suddenly change:
volatile boolean interrupt_flag = false;

It's safe to set that interrupt_flag to true inside the interrupt handler and it's safe to check the value in loop(), reset it to false and do whatever work was needed. Don't do more than this unless you know what you're doing.

to be clear: i am not using spiffs in the interrupt handler. the interrupt handler merely increments a counter in my case (on rainfall). i was just concerned if data would be corrupted or cause a crash if an interrupt triggered during some housekeeping operations I do with spiffs. you are saying i should be fine leaving out the noInterrupts .etc.?

"just set a flag to indicate that the interrupt occurred, and let code in the loop() check for the flag." - Though then you don't need the ISR at all, since the MCU already has an interrupt flag build into it's register. You could also poll that flag.

Excellent answer. Just a comment on “a properly written interrupt handler will save any necessary state”: unless written in assembly, the code for saving and restoring the state is written by the compiler, and you can pretty much trust it to do it right.

@Alex Yes, you should not disable interrupts while you're doing housekeeping operations. It's important not to disable interrupts. If this were a problem, almost none of the Arduino code out there would work right.

@chrisl true! Although I think most people who know that are safe to do more in an interrupt handler than set a flag :)

@EdgarBonet good point, with the hardware doing some of the work too,

John Romkey provided you an excellent answer. I am adding this just to
provide another perspective, hopefully complementary.
Interrupts are meant to handle the most time-critical tasks. Those tasks
that cannot wait for the next loop() iteration, such as counting a
pulse from an encoder, or getting a byte out of the UART receive buffer.
If you delay them too much, they may miss their deadline, resulting in
unreliable operation of the whole program (counter missing pulses, UART
missing bytes...).
Sometimes you have a piece of code that cannot afford being interrupted.
Maybe it is extremely time-critical, like the generation in software of
a pulse that is exactly 0.5 µs wide. More commonly it will be
reading data from memory that is being modified by an interrupt handler,
and you don't want that data to be modified in the middle of the read
operation. Such pieces of code are called critical sections, and you
keep them safe in between noInterrupts() and interrupts(). If an
interrupt request fires while the program is running a critical section,
the request is put on hold and serviced only when the critical section
is done. This adds some latency to the interrupt which, if
excessive, can lead to the interrupt missing its deadline. This is the
reason critical sections should be kept as short as possible.
You have been told that interrupt handlers should be kept as short as
possible, but I am not sure you know why it is so. The fundamental
reason is that interrupt handlers are themselves critical sections.
While a handler is running, other interrupts are blocked. On some
architectures (notably not AVR, I don't know about the ESP), only
interrupts of lower priority are blocked, but it is still an issue. The
rationale for keeping those handlers short applies equally to any
critical section.
Now, just to provide an example of the sort of bad things that can
happen if you block interrupts unnecessarily, consider this piece of
code:
noInterrupts();
Serial.println("Inside critical section.");
interrupts();

What this does is put the string "Inside critical section." in a
software buffer. Not a huge task you may say. Actually pushing the bytes
out to the UART is the job of an interrupt handler, triggered by the
UART when it is ready to accept a new byte. But then what happens if
there is not enough free space in the buffer for the string? In this
case, Serial.println() waits in a busy loop. It waits for the
interrupt to move bytes out of the buffer and make space for the new
string. But wait, we have just disabled interrupts... See the problem?
This is the reason it is generally advised to never Serial.print()
inside an interrupt handler. The same applies to any critical section.
Edit: As Juraj points out in a comment, the HardwareSerial code
now implements a workaround against this problem: if it
detects it has to wait with interrupts disabled, it takes care of
calling the interrupt handler itself. This is a (relatively) late
addition to the HardwareSerial code. Their authors presumably
witnessed too many beginners doing debug prints from interrupt handlers
and being bitten by this issue. Note that it is a workaround, not a
solution: it will often make the critical section last for an
unreasonably long time.
I wouldn't rely on similar APIs, or even on other cores, systematically
implementing this kind of safeguards though: some library authors just
trust the user to not do silly things.

the write() of hardware Serial checks if interrupts are enabled and if not, it calls the sending function directly

@Juraj: You are right. I edited the answer.

These are all great points, thank you for posting them... I wish I'd included them in my post :)


text:
Adafruit_LSM303 tilt compensated compass
I am having troubles with tilt compensating my compass.
I am using the LSM303DLHC accelerometer/compass in combination together with the Adafruit_LSM303_U.h.
I was able to get my compass to the right direction withthis little snippet:
  float heading = (atan2(event.magnetic.y,event.magnetic.x) * 180) / Pi;

I also was able to get my roll and tilt angle with converting my X and Y of my accelerometer to angles:
   headingNew = asin(eventA.acceleration.x/10);
   float tilt = headingNew*180/PI/90*100;
   headingNew = asin(eventA.acceleration.y/10);
   float roll = headingNew*180/PI/90*100;

Now I need to compensate my angle to get a new x and y for inside my heading calculation but the problem is that I can't seem to get the right functions.
Online I found the functions below from a large tutorial about the sensor but this gives me completely wrong values.
    //Xh = event.magnetic.x*cos(tilt)+event.magnetic.z*sin(tilt);
    //Yh = event.magnetic.x*sin(roll)*sin(tilt)+event.magnetic.y*cos(roll)-event.magnetic.z*sin(roll)*cos(tilt);

or in the code itself:
   Xh = event.magnetic.x*(eventA.acceleration.z/10)+event.magnetic.z*(eventA.acceleration.x/10);
   Yh = event.magnetic.x*(eventA.acceleration.y/10)*(eventA.acceleration.x/10)+event.magnetic.y*(eventA.acceleration.z/10)-event.magnetic.z*(eventA.acceleration.y/10)*(eventA.acceleration.z/10);

I actually get the right angle on a flat surface. But it is even more inaccurate at an angle as the normal heading.
Does anybody have any experience with this sensor? Already a big thanks for the help.

Via this Youtube movie I found a different library and made this code:
#include <SPI.h>
#include <Wire.h>
#include <LSM303.h>
const int centreX  = 160;
const int centreY  = 120;
const int diameter = 100;
#define STMPE_CS 8
#define TFT_CS 10
#define TFT_DC 9

int last_dx, last_dy, dx, dy;
LSM303 compass;
void setup(){
Serial.begin(9600);
Serial.println("meters Test"); Serial.println("");
Wire.begin();
compass.init();
compass.enableDefault();

compass.m_min = (LSM303::vector<int16_t>){-602, -704, -511}; //values from
cailbration.
compass.m_max = (LSM303::vector<int16_t>){+557, +436, +529}; //values from
cailbration.
last_dx = centreX;
last_dy = centreY;
}
void loop() {
compass.read();
double angle;
float heading = compass.heading();

angle= heading; //use heading from compass
dx = (diameter * cos((angle-90)*3.14/180)) + centreX;    // calculate X position
dy = (diameter * sin((angle-90)*3.14/180)) + centreY;    // calculate Y position
last_dx = dx;
last_dy = dy;
Serial.print("angle:"); Serial.println(angle);
Serial.println("tilt:"); Serial.println(compass.a.x);
delay(25);
}

Now everything works. Sometimes you just need to choose your battles.

can you explain those value const int centreX = 160;
const int centreY = 120;
const int diameter = 100;

Those values are to help the Unity application that takes in the data from the device over serial connection. For example when our installation gets turned I can just change these values instead of rebuilding the "desktop application"

The sin() and cos() functions expect their arguments to be in
radians. If you feed them with anything else, be it degrees, percent
slope, or whatever, expect the result to be just crap.

Edit: The OP changed the question, invalidating my answer. So here
comes a new answer...
You have mistaken eventA.acceleration.y for cos(tilt),
eventA.acceleration.x for sin(tilt), and so on. They are not the
same. You may think they are the same up to some multiplicative factor,
and that's right. However, the factor doesn't cancel out as soon as you
do computations like sin(roll)*sin(tilt). Don't rush your math: if you
want to transform known-good formulas to more practical ones, check every
step of the transformation carefully.

Actually for the sinus of the tilt I use my Accelerometer.x, for the cosinus of tilt the accelerometer.y.
Also for the sin of the roll I use the accelerometer.Y.
These are values from 0 to 1 that are the same as the cos/sin of a unit circle

@Roel: Re “for the cosinus of tilt [I use] the accelerometer.y”: I can't see that in the code you posted. If you are asking a question about a different piece of code, then please edit the question and make sure the code you show is the one that matches your question.

I edited the question to show you how the code really looks like in my project.

I just want to know what Is wrong with the final function because I am not able to get the right result.

@Roel: What's wrong: it uses eventA.acceleration.y instead of cos(tilt), etc. Solution: use the formula as published, with the angles in radians.

I changed it in my code and in the question. It didn't help me out. cos(tilt) = eventA.accel.z now. Didn't help me out

Reviewed everything. If you could check again.
I actually get the right angle on a flat surface. But it is even more inaccurate at an angle as the normal heading.


text:
Any source code for connecting a tinyshield to another tinyshield?
I recently purchase 2 tinycircuit smart watch. I am wondering if anyone knows if there is any source code for me to reference on how do I connect one tinyshield to another tinyshield. I understand that a tinyshield is both a master and slave. I am trying to connect 2 tinyshield to each other such that I could transmit data between those two tinyshield.
Currently, when I upload the code into two tinyshield, the receiving tinyshield can't seem to be receving any thing, while the sender tinyshield is sending over data
Sender code
#include <SoftwareSerial.h>

SoftwareSerial mySerial(12, 11); // RX, TX

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  while (!Serial) {
    Serial.print("connecting"); // wait for serial port to connect. Needed for native USB port only
    }
    mySerial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  int vert = 200;
  int LDRReading = 100;
  delay(1000);
  Serial.print("LDR : ");
  Serial.print(LDRReading);
  delay(1000);
  Serial.print(" acc: ");
  Serial.println(vert);
  sendData(LDRReading, vert);
}

void sendData(int ldr, int accel)
{
    mySerial.write(((ldr >> 7) & 0x7F) | 0x80); // Upper 7 bytes and first bit
    mySerial.write(ldr & 0x7F); // Lower 7 bytes
    mySerial.write((accel >> 7) & 0x7F); // Upper 7 bytes
    mySerial.write(accel & 0x7F); // Lower 7 bytes
}

Receiver Code
#include <SoftwareSerial.h>
#include <SPI.h>

SoftwareSerial mySerial(12, 11); // RX, TX

void setup() {
  // put your setup code here, to run once:
 // initialize serial communication:
  Serial.begin(9600);
  while (!Serial) {
    }
    mySerial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  int result=0,acc=0;
if (getDataFromSerial(&result, &acc))
{
    // use accel and ldr
}
  if(result!=0&&acc!=0){
    Serial.print(result);
    Serial.print(acc);
  }

}

boolean getDataFromSerial(int *p_ldr, int *p_accel)
{
    boolean foundData = false;

    while ((!foundData) && (mySerial.available() >= 4))
    {
        if (!(mySerial.peek() & 0x80))
        { // If the first byte in the buffer is not a valid start, discard it
            mySerial.read();
            continue;
        }

        *p_ldr = mySerial.read() & 0x7F;
        *p_ldr = ((*p_ldr) << 7) | (mySerial.read() & 0x7F);
        if ((*p_ldr) & 0x2000) (*p_ldr) |= 0xC000; // This is the sign extension

        *p_accel = mySerial.read() & 0x7F;
        *p_accel = ((*p_accel) << 7) | (mySerial.read() & 0x7F);
        if ((*p_accel) & 0x2000) (*p_accel) |= 0xC000; // This is the sign extension

        foundData = true;
        }
         return foundData;
    }

That depends on the shields, that you are using. As I understood from the Tinycircuits product page the modules need different communication methods. Some use Serial, some SPI and others I2C. Please give us more details and what you have tried so far.

I have tried connecting the tinyshield to tinyshield via serial to serial.

Please put all new information into your question by editing it. We are trying to build a coherent Q&A database to help others. 2. We still need more information. Are you trying to connect 2 master shields (those with the Atmega328p on them), or different shields? And what have you tried so far? There are tons of Serial code out there and the chip is the same as in the Arduino Uno and Nano, so you can reuse many of them.

My apology, I have edited my question and included my codes for what I have try.

while (!Serial)  Serial.print("Who's writing this ?"); looks a bit silly (or like a philosophical paradoxon) to me :)

Besides connecting Rx-Tx and Tx-Rx you have to connect both GND too. (Just in case)

Have you tried to simply immediately send all data received from Software Serial over Serial? That would show, if the data actually get's read. Currently you are doing a lot with the data, before actually sending it, including discarding data. You should first look, if the correct data get's received correctly


text:
What pins can be used for chip select (CS, CC) on the Arduino nano every?
I’ve checked the nano’s tech specs but I can’t seem to find any information regarding it. I’ve tried setting it to pin 26 (digital output)

the Nano Every doesn't have pin 26

The following answer assumes the Arduino is the master.
You can use any pin for that (at least any GPIO pin).
Multiple SPI devices can be connected to a SPI peripheral on an Arduino (in principle).
Every SPI device should have their own CS/CC pin, and is mandatory when you use multiple SPI devices.
For this reason, there is no single pin the SPI can define for being used as CS/CC pin. However, it should give a GND or VCC value, thus a CS/CC pin should typically be configured as a digital input pin (as master) for each slave.
(See remark of KIIV too); as slave the CS/CC pin should be a digital output pin.
For the other pins (MOSI, MISO, CLK), the Arduino uses a fixed set of pins because all SPI devices will be connected to these pins.
So the CS pin is configurable, and the other spi pins are fixed.

I am not familiar with the chip on that board, but if it's like the other AVR based boards the "primary" CS pin must be set to output (pin 10 on Uno - no idea what it will be on that board off hand). Otherwise SPI won't work.

However don't forget about SS (select slave) pin on AVR based Arduinos. It must be set as output (or at least used as output). Otherwise low level on this pin causes switching SPI to slave mode. Even left unconnected (as an input) it can be source of weird deadlocks in noisy environment.

@Majenko I thought that pin 10 was only primary because of shields using that pin to make the layout easier. Afaik it always can be set to any (GPIO) pin.

@KIIV I mention this: thus a CS/CC pin should typically be configured as a digital output pin.... a nontypical situation could be to connect it to GND or VCC (forgot which exactly) in case of a single SPI device.

The SPI peripheral in the chip has two modes of operation: one is Master and the other Slave. Which mode is selected depends on the DDR setting of the primary CS pin. It's a stupid way of doing it, but that's what Atmel's designers chose to do...

@MichelKeijzers I though it's general name for signal. Anyways /SS is active low, so as an input it should be held to the Vcc. The SPI supports multi-master mode and this pin is used to archieve it (only possibility to disable it is use it as an output)

@Majenko Thanks for mentioning this (so far I always used the Arduino as master, I added it in my question).

@KIIV you are right, I should adapt it in my answer.

@Majenko this is not ATmega328 or 2560. it is 4809. it has a flag in control register for master/slave mode and the flag is set by the SPI library. the SS pin can be used as input with SPI master mode. The peripherals of the 4809 are more like the SAMD peripherals then classic ATmega MCU peripherals

Wow, there is a board called Arduino Nano Every. (I though it's just meant like "on every pin?"). Anyways ability of /SS input pin to change mode from master to slave stays, but at least it can be disabled by setting SSD bit in SPIn.CTRLB register. That depends on pretty much on SPI library.

@KIIV, https://github.com/arduino/ArduinoCore-megaavr/blob/d2d1a2a7bc4654b907427cfb8d1003134fa6b340/libraries/SPI/src/SPI.cpp#L52

"However, it should give a GND or VCC value, thus a CS/CC pin should typically be configured as a digital input pin (as master) for each slave. (See remark of KIIV too); as slave the CS/CC pin should be a digital output pin." I don't understand this. CS pins are outputs.


text:
Problem with NodeMcu interrupt
I am Using Arduino IDE to program NODEMCU. I am expecting LED should remain ON for 4 sec. But it turns OFF in less than 2 sec. Please can anyone explain me why this happening? Also I noticed that if serial monitor is used, led ON timming changes with baudrate. I don't know why this is happening.
#include <ESP8266WiFi.h>
#define LED D1    // external LED is connected to pin D2
uint8_t GPIO_pin = D2;
void ICACHE_RAM_ATTR IntCallback();

void setup(){
  pinMode(D1,OUTPUT);
  attachInterrupt(digitalPinToInterrupt(GPIO_pin),IntCallback,CHANGE);
}
void loop(){
  digitalWrite(LED,LOW);      // Turn off LED to indicated Interrupt routine ended
  delay(1000);               // Without this delay, LED just blinks too weakly for milliseconds
}

void ICACHE_RAM_ATTR IntCallback(){
 digitalWrite(LED,HIGH);  // Turn LED ON to indicate Interrupt Routine started
 delay(4000);             // Delay in order to keep LED ON
}

Calling delay() in an interrupt is really a bad thing to do. You should wait in the loop, not in an ISR

@chrisl ok thanks..I will follow that..


text:
Why are embedded C codes are ending with "while(1)"?
I always see while(1); at the end of the C codes such as:
#include <stdio.h>

int main(void)
{

    //Some code here...

    while(1);

}

If I'm not wrong that it always exists, what is the function of that?
edit:
#include <stdio.h>

int main(void)
{

     while(1);
    //Some code here...

}

; is empty command. it is the nothing repeated  with while (1)

Well, to be pedantic, you are not allowed to have such cycles in a C or C++ program. In C and C++ an infinite cycle is required to have observable behavior (input/output, atomic access, volatile access etc.). If an infinite cycle does not have any such behavior (e.g. an empty cycle), the behavior of your code is undefined. In practice compilers may (and will) completely discard such cycles from the code, meaning that the program will not stop there. The only reason it "works" in AVR-GCC is that it is somewhat of an idiom in embedded programming, so they are allowed as an exception.

It's because in non-embedded systems, when main() finishes it returns to the operating system and the program is removed from memory. In embedded systems there's no operating system to return to, and the program can't be removed from memory.  So... what do you do when the program is finished?  Simple: you do nothing. Forever.  And that's what while(1); does.
Some compilers and C libraries automatically add while(1); in the exit() routine, but not all do - so it's better to do it explicitly than rely on something that may or may not be there.

Its very confusing syntax-wise as well. The "while" is used with curly brackets. But here at the end there is while(1);. How can we articulate this to understand how it functions on the code?

while, like if, can be used with curly brackets. It doesn't have to be. while(something) dosomething(); and while(something) { dosomething(); } are the same. You only need the brackets if you want to do more than one thing.

Does that mean(for forever loop) while(1) can be on the top of the code instead of at the end?

You can use it anywhere you like. You also sometimes see for (;;); which means the same thing... "for ever..."

To be more specific. Please see my edit. I added another code to my question. Are these two codes will act the same way?

The while(1) will do nothing forever. The key here is: forever. It won't ever stop doing nothing. Any code after it will never be executed, because it's still doing nothing.

while(1);

should actually be read as
while(true)
{
  // No statements
}

// Statements following here will never be executed

The result is: while the condition is true, it performs no statements. Since the condition true is always true, it keeps performing the statements within the { and }, which are no statements, resulting that no statement is executed but it will also not executing statements after the while.

The "while" is normally used with curly brackets. But here at the end there is while(1);. How can we articulate this to understand how it functions on the code?

Majenko already answered this, in about similar words: while (true)  where x can be a single statement like while (true) a = 4; (thus a = 4; is the statement). Or it can be a compound (multiple statements) in the form of while (true) { a = 4; b = 5; }. In the case of your question a single (but empty) statement is used: while (true) /* empty statement */ ;

Can while(1) be on the top of the code instead of at the end? Would it work same way? I dont get why they put it at very end instead of at very beginning.

It can be anywhere in the code, however, note that code after such while statement, will not be performed anymore as the MCU keeps executing … nothing.

You wrote "the code after such while statement, will not be performed anymore ". If the code after while(1)  will not be executed so how come putting while(1); at the beginning will let the following code to be looped forever?

@Genzo I meant after the complete while statement... the statements inside the brackets (while (…) { … }) all belong to the while statement; the while statement ends after the ; (in while (1);) or after the } (in while (1) {…}). Statements after the ; or } will not be executed.

To be more specific. Please see my edit. I added another code to my question. Are these two codes will act the same way?

No, they are not the same. The first executes , and then waits indefinitely. The second waits indefinitely, and then executes  (which is never).

They will not perform the same way: in the first example, first the statements are executed (some code here), and the MCU keeps doing nothing (while), in the second example, the MCU starts doing nothing (while), never reaching the statements (some code here).

The line while(1) in a C program creates an infinite loop- this is a loop that never stops executing. It executes over and over and over again, unless the program is intentionally stopped or there is some condition under this loop that gets met that takes the program out of this infinite loop.
Let's take the following C program.
include
void main()
{
printf("Hello World");
while(1);
}
This program prints the words "Hello World" to the standard output, which is most likely a serial port.
After it prints it, it goes to execute the next line, while(1). This line makes the microcontroller sit and wait, forever or until the microcontroller is reset.


text:
integer overflow in expression [-Woverflow] - TinyCircuit
I have a tiny circuit Bluetooth shield and I was testing out the sample code that was provided by tinycircuit. However, when I tried uploading the sample code into the board, I kept having the following error. How can I solve this error?

this is the piece of code where there error seems to be happening.
#define  ADV_INTERVAL_MIN_MS  50
#define  ADV_INTERVAL_MAX_MS  100

void setConnectable(void)
{
  tBleStatus ret;

  const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME, 'B', 'l', 'u', 'e', 'N', 'R', 'G'};

  hci_le_set_scan_resp_data(0, NULL);
  PRINTF("General Discoverable Mode.\n");

  ret = aci_gap_set_discoverable(ADV_IND,
                                 (ADV_INTERVAL_MIN_MS * 1000) / 625, (ADV_INTERVAL_MAX_MS * 1000) / 625,
                                 STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE,
                                 sizeof(local_name), local_name, 0, NULL, 0, 0);

  if (ret != BLE_STATUS_SUCCESS)
    PRINTF("%d\n", (uint8_t)ret);

}

What is ADV_INTERVAL_MIN_MS ?

50 * 1000 > 32768. 100 * 1000 > 32768. It shouldn't matter, but best force it to a long by appending L to your defined numbers.

You can specify the type of a number using suffixes such as L, LL,
UL and such. If you don't specify the type this way, all integers that
are small enough to fit in an int will be of type int. When you
write
ADV_INTERVAL_MIN_MS * 1000

it gets expanded by the preprocessor to
50 * 1000

Since both arguments are of type int, the compiler will use this type
to compute the result. However, the result is 50,000, and on 16-bit
systems the largest number that can fit in an int is 32,767, thus the
overflow.
As suggested by Majenko, the simple solution is to add the L suffix
(for long) to either operand. The compiler will then do the
arithmetics using the long data type.

Sorry uhm, what do you mean either operand ? I'm a little new on this.

The operands are 50 and 1000. Append the “L” suffix to either (or both) of them.


text:
Baudrate is set to 9600 automatically even if specifying a different value
You initialize the serial communication via USB with
Serial.begin(baudrate);

where baudrate is a long specifying the number of symbols you want to send over the connection per second. You can put pretty much any number in there, but not every number makes sense.
One thing that I found odd though is that I can't seem to actually use a different baudrate than 9600. The sketch compiles and uploads just fine, but if I check the actual speed of the serial port via
setserial -ag port

where port is the port of my Teensy 4.0 board (that command is something you can use in the terminal of Linux) or with
Serial.baud();

directly in the sketch it always says 9600. I suspect that this is caused by something inside the code behind Serial.begin() since I can manually set the baudrate via the terminal in Linux using
stty speed baudrate < port > port

where (again) baudrate is the speed I want to use and port is the port of my board (checking it with the first terminal command: it works). But when restarting the program on the board the baudrate reverts to 9600.
Does anyone know why this is and how to fix this?

The whole concept of Baud Rate with USB communication is completely meaningless.  There is no such thing as "baud rate" over USB.
What there is, and what you are confusing with "baud rate" is a configuration item which the host can send to the device which is a "I would like you to communicate with other devices at this speed" configuration item.
This is intended for use with USB to UART adaptors where it is used to configure the baud rate of a physical UART interface for downstream communication.
When you set the baud rate in your code it is ignored, since it has no meaning.
When you set the baud rate on your computer it sends it as this configuration value, which you can then retrieve, should you have an interest in that value, using the Serial.baud() function.

Of course there is a baudrate over USB. There is one for every communication. Do you mean to say that the Arduino IDE cannot change it?

@LukasFun No, there is no baud rate. There is a data rate, but that is largely unrelated to the actual rate of communication between the host and any one device, since it is a packet-based protocol.

So... how do you control the data rate of the USB connection then, I guess? And why would that rate not matter?

You don't control the data rate. The data rate is defined by the class of the interface and device. USB 1 ("Full Speed") is 12Mbps. USB 2 ("High Speed") is 480Mbps. USB 3 ("Super Speed") is 5Gbps. The chosen speed is the highest that both the device (Arduino) and host (computer) can work together at.

That data rate is divided amongst all devices on the bus.

Oh, and your device never sends data. It enqueues data, and it's the responsibility of the host to come and collect that data.

So, that means, that on USB native Arduino's the baudrate for communication over USB does not have any effect?

Correct. The parameter given to Serial.begin(...) is completely ignored.

Sorry for coming back at this again. While the communication rate of the USB port per se may be fixed, this does not mean that the serial port is actually doing what I want (communicate with maximum speed). That's because the serial port used for this communication is only emulated via the USB port. And the connection of that emulated port should be customizable. It is, in fact, as I specified in my question but is reset every time the controller runs a sketch. Is there any way to change the speed of the connection? I actually tested the speed and it was about 60000 Bits/s. Quite slow.

@LukasFun The port actually runs at the highest speed it can. It's not a fixed speed, but sends data at as fast a rate as the USB channel allows. The speed "resets" because every time the sketch runs the CDC/ACM port gets destroyed and recreated. It's effectively a completely new device, so it gets the system default settings. But since that "baud rate" has no meaning, changing it is irrelevant.

The "baud rate" is sometimes used to make the device do different things - for instance changing the baud rate to 1200 can cause the Arduino to reset into the bootloader for programming. I use 300 baud on a device I sell to enter a special lowlevel programming protocol mode.

The speed you obtain depends on many factors - what else is on the same USB bus, how powerful the target device is (how fast it can process the USB packets as they arrive), etc.

To put it another way: forget that it's an Arduino you're using and imagine it's an FT232 adaptor. When you set the baud rate you aren't setting the baud rate of the USB connection. You're informing the FT232 of the baud rate you would like it to communicate with whatever it is connected to at.

are you thinking of this purely in terms of USB? surely the serial (ie: RS232) communication itself that the USB generates must be at some particular baud rate to be able to communicate correctly with devices. the serial communication cannot be faster than the device expects or it will not be received properly.

The problem may be in flow control, as LukasFun suggested. Obviously, a low speed RS232 device will not be able to handle a continuous data stream at 1.5 Mbps
A quick look at this paper may help.
https://www.usconverters.com/index.php?main_page=page&id=49&chapter=0