text:
Help with getting Sensor Average using Arrays
First of all, let me be clear: I'm a total noob, I have close to zero programming experience and I know i'm out of my league, but I want to learn and understand.
Here's the issue. The following code has been made to control heat pads using 4 relays that turn off/on depending on the temperature that 4 lm35 Temp sensors pick up. Because these sensors can be jumpy sometimes, I want to get the average temperature from, let's say, 50 readings, and make the code check THAT data instead of the raw temp reading.
I have the code for the arduino (I wrote some code and guys over other forums took it and modified it to make it shorter (and that kind of lost me, but the code works)
and then I searched smoothing data and got a piece of code that does exactly what I want: make an array, calculate the average temp, and keep deleting and adding new data.
I tried to join both codes together and I got all different kind of errors, lol
So here I am.
The Code that works without average data is this one:
const byte tempPin[] = {A1, A2, A3, A4};
const byte relayPin[] = {6, 7, 8, 9};

// hysteresis = upperLimit - lowerLimit
const byte lowerLimit = 24;
const byte upperLimit = 31;

float tempC[4];
word reading[4];

word printInterval = 1000; // 1 second
unsigned long printCheck = 0, lastPrintTime = 0;

void setup()
{
  analogReference(INTERNAL);
  Serial.begin(115200);
  for (int i = 0; i < 4; i++) {
    pinMode(relayPin[i], INPUT_PULLUP);
    pinMode(relayPin[i], OUTPUT); // defaults HIGH, relay OFF
  }
}

void loop()
{
  // readings and control
  for (int i = 0; i < 4; i++) {
    reading[i] = analogRead(tempPin[i]);
    tempC[i] = reading[i] / 9.31;

    if (tempC[i] < lowerLimit) {
      digitalWrite(relayPin[i], LOW);   //relay OFF
    }
    else if (tempC[i] > upperLimit) {
      digitalWrite(relayPin[i], HIGH);  // relay ON
    }
  }
  printCheck = millis() - lastPrintTime;
  if (printCheck >= printInterval) {
    for (int i = 0; i < 4; i++) {
      Serial.print("tempC");
      Serial.print(i + 1);
      Serial.print(" ");
      Serial.println(tempC[i]);
    }
    Serial.println();
    lastPrintTime = millis(); // reset print timer
  }
}

The average code I got from Arduino Learning center is this one:
/*

  Smoothing

  Reads repeatedly from an analog input, calculating a running average
  and printing it to the computer.  Keeps ten readings in an array and
  continually averages them.

  The circuit:
    * Analog sensor (potentiometer will do) attached to analog input 0

  Created 22 April 2007
  By David A. Mellis  <dam@mellis.org>
  modified 9 Apr 2012
  by Tom Igoe
  http://www.arduino.cc/en/Tutorial/Smoothing

  This example code is in the public domain.

*/

// Define the number of samples to keep track of.  The higher the number,
// the more the readings will be smoothed, but the slower the output will
// respond to the input.  Using a constant rather than a normal variable lets
// use this value to determine the size of the readings array.
const int numReadings = 10;

int readings[numReadings];      // the readings from the analog input
int readIndex = 0;              // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average

int inputPin = A0;

void setup() {
  // initialize serial communication with computer:
  Serial.begin(9600);
  // initialize all the readings to 0:
  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    readings[thisReading] = 0;
  }
}

void loop() {
  // subtract the last reading:
  total = total - readings[readIndex];
  // read from the sensor:
  readings[readIndex] = analogRead(inputPin);
  // add the reading to the total:
  total = total + readings[readIndex];
  // advance to the next position in the array:
  readIndex = readIndex + 1;

  // if we're at the end of the array...
  if (readIndex >= numReadings) {
    // ...wrap around to the beginning:
    readIndex = 0;
  }

  // calculate the average:
  average = total / numReadings;
  // send it to the computer as ASCII digits
  Serial.println(average);
  delay(1);        // delay in between reads for stability
}

The monster I created joining both codes is this one:
const byte tempPin[] = {A1, A2, A3, A4};
const byte relayPin[] = {6, 7, 8, 9};

// hysteresis = upperLimit - lowerLimit
const byte lowerLimit = 24;
const byte upperLimit = 31;

float tempC[4];
word reading[4];

const int numReadings = 50;
int readings[numReadings];
int readIndex = 0;
int total = 0;
float average[4];

word printInterval = 1000; // 1 second
unsigned long printCheck = 0, lastPrintTime = 0;

void setup()
{
  analogReference(INTERNAL);
  Serial.begin(115200);
  for (int i = 0; i < 4; i++) {
    pinMode(relayPin[i], INPUT_PULLUP);
    pinMode(relayPin[i], OUTPUT); // defaults HIGH, relay OFF
  }
  for (int thisReading = 0; thisReading < numReadings; thisReading++){
    readings[thisReading] = 0;
  }
}

void loop()
{
  // readings and control
  for (int i = 0; i < 4; i++) {
    reading[i] = analogRead(tempPin[i]);
    tempC[i] = reading[i] / 9.31;
    total[i] = total[i] - readings[readIndex];
    readings[readIndex] = tempC[i]
    total[i] = total[i] + readings[readIndex]
    readIndex[i] = readIndex[i] + 1 ;
    if (readIntex[i] >= numReadings) {
      readIndex = 0;
    }
    average[i] = total[i] / numReadings;

    if (average[i] < lowerLimit) {
      digitalWrite(relayPin[i], LOW);   //relay OFF
    }
    else if (average[i] > upperLimit) {
      digitalWrite(relayPin[i], HIGH);  // relay ON
    }
  }
  printCheck = millis() - lastPrintTime;
  if (printCheck >= printInterval) {
    for (int i = 0; i < 4; i++) {
      Serial.print("tempC");
      Serial.print(i + 1);
      Serial.print(" ");
      Serial.println(tempC[i]);
    }
    Serial.println();
    lastPrintTime = millis(); // reset print timer
  }
}

These are the errors that I got:
Arduino: 1.6.8 (Windows 7), Board: "Arduino/Genuino Uno"

\temprelayfinal2.ino: In function 'void loop()':

temprelayfinal2:40: error: invalid types 'int[int]' for array subscript

     total[i] = total[i] - readings[readIndex];

            ^

temprelayfinal2:40: error: invalid types 'int[int]' for array subscript

     total[i] = total[i] - readings[readIndex];

                       ^

temprelayfinal2:42: error: expected ';' before 'total'

     total[i] = total[i] + readings[readIndex]

     ^

temprelayfinal2:44: error: 'readIntex' was not declared in this scope

     if (readIntex[i] >= numReadings) {

         ^

temprelayfinal2:47: error: invalid types 'int[int]' for array subscript

     average[i] = total[i] / numReadings;

                         ^

exit status 1
invalid types 'int[int]' for array subscript

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

I typically use something like avgTemp = (9*avgTemp + 1*reading)/10;.

It looks like you might need to handle a two-dimensional readings[4][50] array to keep 50 samples of 4 different measurements.   Gerben's, solution is an "Exponentially Weighted Moving Average" that is an excellent solution with minimum memory and bookkeeping requirements.  You remember only the 4 averages, and adjust them a little bit with each new reading.   For something corresponding to the 50-sample history, you might want a weights like {49/50 ,1/50}

For efficiency reasons, I like to make the time constant a power of two times the sampling period. E.g. avg += (reading - avg) >> 6;, for τ = 64.

Woah, that's excelent thinking although I don't quite understand some things:
Why use Exponentially Weighted Moving Average instead of Simple Moving Average?
And I don't get the code Gerben used. Why multiply the var by 9 and add it to 1*reading?

“Why use Exponentially Weighted Moving Average instead of Simple Moving Average?” Because the former is actually simpler to implement than the latter. It also requires less memory and is faster to compute. “I don't get the code Gerben used.” It's pretty straight forward once you understand the math.

Ok I think I get it. One question though. What gives the weight its value?

I was also wondering what gives the weight its value and I found the answer here: https://youtu.be/NxTFlzBjS-4?t=275 In a nutshell: the .9 weight is comparable to averaging over the past 10 values, if you used .98 instead, you would be averaging approximately over the past 50 values.

total[i] = total[i] - readings[readIndex];

total is of type int. That is, it is a scalar integer. You cannot index into it, total[i] doesn't make sense. That is why the compiler is complaining.

I see. So, how can I make subdivisions of the var total for each sensor/relay set?

You could make total an array (if I understand what you're asking).

Using the exponential moving average filter suggested by Gerben, things
become quite simpler:
const byte tempPin[] = {A1, A2, A3, A4};
const byte relayPin[] = {6, 7, 8, 9};

// hysteresis = upperLimit - lowerLimit
const byte lowerLimit = 24;
const byte upperLimit = 31;

const int numReadings = 64;
const word printInterval = 1000; // 1 second

float tempC[4];
unsigned long lastPrintTime = 0;

void setup()
{
  analogReference(INTERNAL);
  Serial.begin(115200);
  for (int i = 0; i < 4; i++) {
    digitalWrite(relayPin[i], HIGH);
    pinMode(relayPin[i], OUTPUT);
  }
}

void loop()
{
  // readings and control
  for (int i = 0; i < 4; i++) {
    float raw_temp = analogRead(tempPin[i]) / 9.31;
    tempC[i] += (raw_temp - tempC[i]) / numReadings;  // filter
    if (tempC[i] < lowerLimit) {
      digitalWrite(relayPin[i], LOW);   //relay OFF
    }
    else if (tempC[i] > upperLimit) {
      digitalWrite(relayPin[i], HIGH);  // relay ON
    }
  }
  if (millis() - lastPrintTime >= printInterval) {
    for (int i = 0; i < 4; i++) {
      Serial.print("tempC");
      Serial.print(i + 1);
      Serial.print(" ");
      Serial.println(tempC[i]);
    }
    Serial.println();
    lastPrintTime = millis(); // reset print timer
  }
}

I wonder whether this code could be (very slightly) improved by initializing tempC[i] with the first raw_temp reading? Wouldn't this significantly increase the accuracy of the first readings (i.e. tempC[i])? In many use cases, this will not matter practically but in some it might, especially if numReadings and/or printInterval is high. So if you agree, what would be the most elegant way to implement this?

@Christoph: Initializing tempC[i] the way you suggest would indeed improve the first readings, at the cost of slightly increased complexity. The most elegant implementation would probably be a “filter” class that handles the initialization itself when it gets the first reading. The simplest would be to explicitly initialize the array in setup().

Cool! I was wondering exactly that: is it "allowed" to already take a first sensor reading in setup()? So if it is, it sounds like it's the simplest solution (instead of adding a flag-variable or even a class). I realize that "simplest" is not always the same as "most elegant". Thanks!


text:
Variable scope error
guys.
I'm writing here because I cannot find an obvious error, so I'm stuck. Could you please help me?
Here's the code:
int arrayAAA[] = {6, 8, 10, 12};
int arrayBBB[] = {9, 15, 27, 41};

const int arrayAAALength = sizeof(arrayAAA)/sizeof(int);
const int arrayBBBLength = sizeof(arrayBBB)/sizeof(int);

int newArrayLength = 0;

void setup() {

    Serial.begin(9600);

}

void loop() {

  String dir = "AAA";

  if (dir == "AAA"){

      //Copy existing array to the new one...
      newArrayLength = arrayAAALength;              //Get the size of source array
      int newArray[newArrayLength];                 //Make the new array of the same size
      memcpy(newArray, arrayAAA, sizeof(arrayAAA)); //Copy content of the source array to the new one

      /*
      for (int i = 0; i < newArrayLength; i++){
          Serial.print(newArray[i]); //Here everything works just fine...
          Serial.print("   ");
      }
       */
  }

  for (int i = 0; i < newArrayLength; i++){
      Serial.print(newArray[i]); //But here I see this error: 'newArray' was not declared in this scope
      Serial.print("   ");
  }

  Serial.println();
  Serial.println();

}

What I'm trying to do is to copy the array to a new one, but depending on the circumstances I need to take different source arrays (AAA or BBB).
The problem is in checking the values of an newly crreated array:
'newArray' was not declared in this scope

if I try to check its valus outside of if statment.
It seems my stupid mistake, but I can't find it.

After a careful study of C/C++ documentation, I finally managed to use pointers in Arduino :)
So, the final code became like this:
int arrayAAA[] = {6, 8, 10, 12};
int arrayBBB[] = {9, 15, 27, 41};

//Create a pointer, which will point to any of your arrays of your choice
int *newArray;

const int arrayAAALength = sizeof(arrayAAA)/sizeof(int);
const int arrayBBBLength = sizeof(arrayBBB)/sizeof(int);

void setup() {

    Serial.begin(9600);

    //Uses the address of arrayAAA (i.e. inherits the content of arrayAAA).
    //&: points to address of a chosen array.
    //[0]: is a must to grab all values!
    newArray = &arrayAAA[0];

    Serial.print("arrayAAA:");
    for (int i = 0; i < arrayAAALength; i++){
        Serial.print("   ");
        Serial.print(arrayAAA[i]);
    }
    Serial.println();

    Serial.print("newArray:");
    for (int i = 0; i < arrayAAALength; i++){
        Serial.print("   ");
        Serial.print(newArray[i]);
    }
    Serial.println();
}

void loop(){
    //Left empty
}

And it works perfectly, just what I expected!

The clue is in the indenting:
  if (dir == "AAA"){

      //Copy existing array to the new one...
      newArrayLength = arrayAAALength;              //Get the size of source array
      int newArray[newArrayLength];                 //Make the new array of the same size <<<==== DEFINED IN THE SCOPE OF "IF"
      memcpy(newArray, arrayAAA, sizeof(arrayAAA)); //Copy content of the source array to the new one

      /*
      for (int i = 0; i < newArrayLength; i++){
          Serial.print(newArray[i]); //Here everything works just fine...
          Serial.print("   ");
      }
       */
  }

  for (int i = 0; i < newArrayLength; i++){
      Serial.print(newArray[i]); //But here I see this error: 'newArray' was not declared in this scope <<=== USED IN THE SCOPE OF "FOR"
      Serial.print("   ");
  }

As you can see by the indenting the definition of newArray is in a different block of code which you come right out of before you use it.
You must define newArray at a scope that is outside where you use it.
From that code you don't actually need to copy the contents of one array into another - you can just point to the array you want to use with a pointer.  Alternatively, if you do need to clone the array contents (for some other purpose we don't know of) then you should pre-create an array that is big enough to hold either of your other arrays.
int newArray[max(arrayAAALength, arrayBBBLength)];

Yes, I'd like to point to another array. This would be much more effective. But how can I do it right? I tried to use this code: int *newArray = &arrayAAA, but it leads to another error: invalid types 'int[int]' for array subscript.

It's a very bad idea to create arrays on the stack in the way you describe. If you want a run-time-sized array, use std::vector. If you must have an array, use unique_ptr<int[]>, which will take care of deallocating the space when the variable gets out of scope. Adding examples as an answer so I can format them properly

(as to why it's a bad idea: it usually adversely affects caching, and may blow your stack, which is a real concern in some memory-constrained systems, or in massively multithreaded environments where you really want to use the smallest stack frame possible. While the arduino isn't such an environment, habits you acquire here may transfer to other jobs, and then you'll be trying to find really insidious bugs which could have been prevented by proper code hygiene.).

@JayEye Sorry, but your thinking is wrong there. On a memory constrained system like the Arduino it is far better to use the stack than the heap. The stack is a LIFO system so all allocation / deallocation is linear. Using the heap leads to fragmentation, and on a system that has no ability to do heap defragmentation even slight amounts of fragmentation can lead to big problems further down the line as the heap grows out of control. You don't get that with the stack. And with no frame swapping, since there is no OS or threads or anything like that, you don't get any performance hit ...

... by having a large frame. Yes, it is possible to smash your stack into the heap, but it's easier to avoid than the tangled mess of swiss cheese that the heap would become from growing up into the stack. In general dynamic allocation on a small MCU is frowned upon. Also many MCU compilers don't even have STL available for use - simply because it is too heavyweight and causes too many heap problems for reliable use. Yes, your comments are perfectly valid in other environments and other situations, but not for tiny MCUs like the Arduino.

Made corrections per @Majenko's comment
The following will not work on real Arduinos, but it did work for me on the ESP8266 and the Teensy3, which are what I use mostly, and the only ones I tested the code for: https://github.com/jayeye/jardino/tree/master/esp8266/ase25017
#include <vector>
  ...
  size_t vector_size = 42;
  std::vector<int> foo(vector_size);  // foo is a vector of 42 integers

Another correction: Exceptions do not work even on the aforementioned platforms, so do not access the vector with .at(n)
If you must have an array, use a unique_ptr with an array allocator:
#include <memory>
  ...
  size_t vector_size = 42;
  std::unique_ptr<int[]> arr(new int[vector_size]);

When arr goes out of scope, the array will be automatically freed.
You can always use malloc(), but you'll have to remember to free() it, and that's always a source of bugs.

That can't work on an Arduino. There is no STL, and hence no vector. Also... If you want to get an exception - what is an exception? There are no exceptions. You are thinking PC programming, not MCU programming. The two are vastly different and take completely different mindsets.

Two lessons here: test on the most common platform (I had tested the code on the esp8266, which is what I had handy at the moment), and don't make assertions without testing them (about exceptions -- I never use them, they are forbidden by the Google style guide, and for good reason, but I tried to be too smart here and failed :) )

also, what's this "PC programming". I don't program PCs, I program large linux clusters :)

source: Stack Exchange

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

sort: votes


text:
How to get data from 9DOF razor IMU directly to arduino mega
My final project goal is to make Brushless gimbal for drones using only Arduino MEGA 2560 and 9DOF IMU for control. On Instructables I found two excellent tutorials. Both are different than mine in selected components.
I use the following components:
Arduino MEGA2560
Motors - Quanum 2208 Precision Brushless Gimbal Motor ( httpx://goo.gl/RDBvJL)
Motor Driver - H bridge L298n (httpx://goo.gl/A4ZQi5)
9DOF Razor IMU (httpx://goo.gl/myg9oj )
I'm stuck with 9DOF Razor IMU. Surfing on the internet I found a great tutorial and  github repository (httpx://goo.gl/jh2pfU). This tutorial is excellent and AHRS works great with the FTDI Basic Breakout 3.3V. They gave me a good starting point, but my goal is use only Arduino MEGA2560 and sensors.
I want to connect the Arduino and 9DOF IMU directly and use the accelerometer data (Yaw, Pitch, Roll) for directly control the engines. On the website of the manufacturer Sparkfun (httpx://goo.gl/myg9oj ) I can’t find any datasheet exclusively for 9DOF IMU that could help me to connect Arduino and IMU. There are only datasheet of sensors that are on IMU ( ITG-3200 (MEMS triple-axis gyro), ADXL345 (triple-axis accelerometer), and HMC5883L (triple-axis magnetometer)  which are useless for me.
That's why I decided to use code from this site ( httpx://goo.gl/zOnYjN ) and he works great. I connected everything as is in tutorial and  Arduino SerialMonitor show me the desired values YPR. Values load very quickly directly from IMU and printed on SerialMonitor.
Values on SerialMonitor looks like this:
YPR=72.13,1.74,-16.38
YPR=72.14,1.72,-16.39
YPR=72.12,1.71,-16.39
YPR=72.13,1.71,-16.37
YPR=72.13,1.70,-16.40 …
HELP ME
This is my first solo Arduino project and I have a lot of questions about it.
How could I parse the data that appears on SerialMonitor to get new variables eg. Yaw = 72.12, Pitch = 1.74, Roll = -16.39?
Is it possible to do that?
Does anyone have any experience with 9DOF razor IMU and maybe know  better way to collect information from the accelerometer 9DOF razor IMU?
I want to achieve three separate variables which i will use to control the brushless motor. I think this should be an easier method as it is just comma separated numbers but then again i am new to arduino serial communication so i would appreciate any help with this. Even if it's only how to parse and extract the values.

I am stuck in the same situation as yours and i have referred a lot of tutorials but couldn't come to a proper solution. I also want the #YPR values to be read from the IMU.
As you have mentioned you found a code which helped you achieve the same, the link you have attached for that program seems to not be working. if you can guide me to that program it would be a big help. Thanks in Advance !

sscanf should be enough. There is also other options, String class for example with substring method.
Take a look at the example:
#include <stdio.h>

char myString[] = "#YPR=72.13,1.74,-16.38";

void setup() {
  // put your setup code here, to run once:
  float yaw = 0;
  float pitch = 0;
  float roll = 0;

  sscanf(myString, "#YPR=%f,%f,%f", &yaw, &pitch, &roll);
  Serial.println(yaw);
  Serial.println(pitch);
  Serial.println(roll);
}

void loop() {

}

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


text:
Why was the Due retired?
Looking at the Sparkfun comparison, it seems that the Due is by far the fastest of the Arduinos and has I/O capabilities similar to the Mega. So why was it retired with no obvious successor?

I had assumed it was either because it wasn't successful, or to allow Intel to differentiate their products more easily.

It's a quite expensive and clumsy board. It also runs on 3.3V. It's also not based on the ATMega328(P) and may thus be incompatible with some libraries (that rely on low-level hardware).
Arduino's are (mostly) for hobbyists, which require reasonably priced, not too big board, which they can use for anything. Most tutorials are based on the Uno and a few on Mega, thus someone looking to buy an Arduino, will most likely choose one of them.

I'd say the 3.3V thing matters the most because most shields require 5V.

I bought a Due thinking it was the best thing ever.  I cringed at the $50 (at the time) cost.  But I bought it anyway.  I actually think it's a great board.  But, within a short amount of time I was finding many libs that would not work with it.  I think most people realized that if you need something more advanced that UNO, and have $50 to spend, there are much better options out there.  Not that I know what they are...I'm just thinking that is why you don't see the DUE mentioned as much.  Shame really.  I think it has potential.  A Teensy3.x could be a good alternative for the DUE.

The Due is (was) a great board ! 32 bits bus, 86Mhz, same price as the Mega... Badly, the Arduino Drivers never worked well for the Due. If you want to program it, ASF was a better alternative

"Why was the Due retired?" - It is quite interesting that Arduino.CC never explained that. One would think, that a professional company or organisation places a notice in advance with at least a short explanation as to why.
Most of the Arduinos, that have been available on both projects (CC and ORG) have suddenly and without further notice or explanation been retired on CC (the exceptions being Uno and Mega 2560, the cash-cows), but are still alive on ORG.
It would seem, that either the "divorce" is proceeding or that the copyright case at the US court is not going as smoothly as Banzi hoped. Well, he could repeatedly "bend the truth" by claiming Arduino being completely his idea and design in front of the press (that never bothered to check the obvious facts), but laying such a claim at court is borderline criminal. (see also: arduinohistory.github.io and make your own opinion)
CC has still the biggest chunk of the overall community and also serves as the central nexus for developers. But it seems there is a lot of movement... some people move to Wiring (from which the Arduino IDE was forked), others to 3rd Party sites and yet others try out different  and newly emerging products (eg. Adafruits MCUs and Pi or the Renesas GR series).
ORG on the other hand seems to become the bigger (Arduino branded) hardware supplier and developer. CC has apparently out-sourced this to Intel and tries to live of royalties and "certification" fees (which is the central point where Banzi and Martino started to heavily and openly disagree).
"Why was the Due retired?" - Unless CC doesn't give an explanation, there is no real answer. A lack of interest is certainly not the reason.

Because, basically (in my opinion, anyway) it was rubbish.
Yes, it has grunt. Yes, it has IO, but the chips themselves are pretty rancid.
There are far better options than the SAM3X from other manufacturers.
Also, since all the in-fighting began between the two Arduino factions (.org / .cc) the majority of actual progress and innovation has been by third parties (Intel mostly).

Tiva comes to mind (if only they made LaunchPads compatible with shields [if only shields used a sane pin arrangement]).

I use the pic32 based chipKIT boards most.

@IgnacioVazquez-Abrams, I don't get the idea behind shields. It's rather impossible to allow multiple shields to be stacked, since you know they'll take up the same pins at some point? IMHO, they could've better gone with some "standard connectors" like UEXT (olimex) or Grove (Seeed).
-Majenko How's the IDE/Compiler(s) of microchip nowadays? And what actually makes the difference with AVR's SAM3X and others?

@Paul The IDE is the same as Arduino. You can install the chipKIT core into the Arduino IDE. You also have UECIDE, of course. The benefit of using PIC32 over the others is you get much better support from me :) Seriously, though, the PIC32 uses MIPS whereas most others bow down to the might of ARM. MIPS, MHz-for-MHz is actually slightly more efficient. Or it certainly has been historically. That's why 90% of home wireless routers use it. And now with 200MHz PIC32MZ chips with FPUs they really do fly along.

@Majenko, Hmm, I've worked with a PIC18F and IDE+compiler from Microchip. But for large objects I had to change memory banks in the linker file or something. And if you had a "non-paid" version of the compiler, they said it would be "less optimized". But the PIC32 series seems promising. I've also looked at ARM based boards, (teensy3.2) which I think are very nice as well. Not sure how they compare, but I'm looking something that's easy to learn (lot's of resources online and less struggle with oddities).

@Paul Software-wise the Teensy is probably the easiest. PJRC has put in a lot of work making it work really well and have good compatible libraries for it. The PIC32 boards (chipKIT) though have better hardware support - standard Arduino footprints, lots and lots of IO, built in Ethernet or WiFi on some models, etc. The Teensy is one product done very well, but doesn't always fit everyone's needs. chipKIT has far more to choose from, but the software is sometimes a little lacking, though it is improving all the time. Also I am available for hire to create new chipKIT boards ;)

The PIC32 chipKIT compiler is the open-source portions (i.e., GCC) of XC32. Freely available. Full C++, etc. The main difference is it uses newlib instead of Microchip's own C library.  Whoop-de-doo ;)

@Majenko Built-in ethernet is something that'll come in very handy ;). And indeed seems that it's much better "supported" as the PIC18F's. I was thinking of the difference between ARM and PIC32, but I guess it doesn't really matter that much per se. Ideally, I should get into both :x
It's good to work with something more "professional" as Arduino, but prototyping/building with DIP package (328P) is just so much easier/cheaper :) (But we shouldn't be chatting in this comment section (though it's more interesting as the original question xD)

@Paul There are PIC32s in DIP format believe it or not - the PIC32MX1xx/2xx chips are available in 28 pin DIP ideal for breadboard use.

@Majenko: Your review is doubtful and partial (in fact totally useless for me). Not all use the Arduino IDE with this great board. For example, I'm was successful when programming directly in raw C (register level) using Atmel Studio with my Engineering students. An excellent resource to study the ARM Cortex-M3 architecture. I believe that the most advanced users lose by removing this board, while  keeping Arduino Zero board (based on Cortex-M0, Von Neumann). At the end, the problem was price and few knew how to program its valuable internal peripherals. Long live to my DUE boards!

It's not a review, it's an opinion. The entire question is about opinion. That is why the question is closed. My opinion is that the Sam3x chips are vile.

@Majenko could you please elaborate? I know it's old but I'd be genuinely interested why you say that. It seems like it'd be better than say a Mega2560 in every way (except arguably voltage).


text:
Modbus Protocol RTU
I have simple code working on Serial Communication asn below. With Same data i would impliment Modbus protocol> I have Used Modbus library for arduino earlier which works fine with 9600 baudrate and wont work with higher baudrates.And also have restriction In library ,They directly storing values into Buffers SO i cant able to fig out weather request send proper or improper.
I never Worked on EMbeded c Chip level code.Is there any way to Implement without library for arduino
In below code I would Like Serial value into register and when function called i could read value. Similarly the function CODE for Modbus should be implemented.
I am looking for simple c code or implement c code Where i can perform the operation this way.
I am trying to Send modbus Request
I found CRC error calculation like in one of forum
 unsigned int crc_fn(unsigned char *dpacket,unsigned int len)    // CRC 16 Function(Error calculation)
    {
        unsigned int crc = 0xffff,poly = 0xa001;
        unsigned char i=0,j=0;

        for(i=0;i<len;i++)
        {
            crc^= dpacket[i];
            for(j=0;j<8;j++)
            {
                if(crc & 0x01)
                {
                    crc >>= 1;
                    crc ^= poly;
                }
                else
                crc >>= 1;
            }
        }
        return (crc);
    }

I would like to See my code in arduino Like this With CRC check
void Serial_access(void)
{
    unsigned char i=0,len=0,ser_data[60],crc_data[60],j=0;
    unsigned int crc1=0,crc2=0;
    crc1 = crc_fn(&rxbuf[0],6);
    _delay_ms(100);
    if((rxbuf[6] == (unsigned char)(crc1))&&(rxbuf[7] == (unsigned char)(crc1>>8)))
    {
        if(rxbuf[0]==DEVICE_ID)
        {
            if(rxbuf[1] == Function_code)
            {
                if((rxbuf[5]>=1)&&(rxbuf[5]<30))
                {
                    //Address = ((unsigned int)(rxbuf[2]<<8)+((unsigned int)(rxbuf[3])));
                    len = (rxbuf[5]*2);
                    _delay_ms(10);
                    ser_data[0] = 0;
                    ser_data[1] = 0;
                    ser_data[2] = 0;
                    ser_data[3] = 0;
                    ser_data[4] = 0;
                    ser_data[5] = 0;
                    ser_data[6] = 0;
                    ser_data[7] = 0;
                    ser_data[8] = 0;
                    ser_data[9] = 0;
                    ser_data[10] = 0;
                    ser_data[11] = 0;
                    ser_data[12] = 0;
                    ser_data[13] = 0;
                    ser_data[14] = 0;
                    ser_data[15] = 0;
                    ser_data[16] = 0;
                    ser_data[17] = 0;
                    ser_data[18] = 0;
                    ser_data[19] = 0;
                    ser_data[20] = 0;
                    ser_data[21] = 0;
                    ser_data[22] = 0;
                    ser_data[23] = 0;
                    ser_data[24] = 0;
                    ser_data[25] = 0;
                    ser_data[26] = 0;
                    ser_data[27] = 0;
                    ser_data[28] = 0;
                    ser_data[29] = 0;
                    ser_data[30] = 0;
                    ser_data[31] = 0;
                    ser_data[32] = 0;
                    ser_data[33] = 0;
                    ser_data[34] = 0;
                    ser_data[35] = 0;
                    ser_data[36] = 0;
                    ser_data[37] = 0;
                    ser_data[38] = 0;
                    ser_data[39] = 0;
                    ser_data[40] = 0;
                    ser_data[41] = 0;
                    ser_data[42] = 0;
                    ser_data[43] = 0;
                    ser_data[44] = 0;
                    ser_data[45] = 0;
                    ser_data[46] = 0;
                    ser_data[47] = 0;
                    ser_data[48] = 0;
                    ser_data[49] = 0;
                    ser_data[50] = 0;
                    ser_data[51] = 0;
                    ser_data[52] = 0;
                    ser_data[53] = 0;
                    ser_data[54] = 0;
                    ser_data[55] = 0;
                    ser_data[56] = 0;
                    ser_data[57] = 0;
                    ser_data[58] = 0;

                    crc_data[0] = DEVICE_ID;
                    crc_data[1] = Function_code;
                    crc_data[2] = len;

                    j=3;
                    for(i=0;i<len;i++)
                    {
                        crc_data[j++] = ser_data[i];
                    }
                    crc2 = crc_fn(&crc_data[0],(len+3));
                    _delay_ms(100);
                    serial_send(DEVICE_ID);
                    serial_send(Function_code);
                    serial_send(len);
                    for(i=0;i<len;i++)
                    {
                        serial_send(ser_data[i]);
                    }
                    _delay_ms(10);
                    serial_send((unsigned char)(crc2));
                    serial_send((unsigned char)(crc2>>8));
                }
            }
        }
    }
    index = 0;
    for(i=0;i<16;i++)
        rxbuf[i] = 0;
    rec_flag = 0;
    check_flag = 1;
}

Here code written in C++, How can we convert these to C
int8_t Modbus::query( modbus_t telegram ) {
  uint8_t u8regsno, u8bytesno;
  if (u8id != 0) return -2;
  if (u8state != COM_IDLE) return -1;

  if ((telegram.u8id == 0) || (telegram.u8id > 247)) return -3;

  au16regs = telegram.au16reg;

  // telegram header
  au8Buffer[ ID ]         = telegram.u8id;
  au8Buffer[ FUNC ]       = telegram.u8fct;
  au8Buffer[ ADD_HI ]     = highByte(telegram.u16RegAdd );
  au8Buffer[ ADD_LO ]     = lowByte( telegram.u16RegAdd );

  switch ( telegram.u8fct ) {
  case MB_FC_READ_COILS:
  case MB_FC_READ_DISCRETE_INPUT:
  case MB_FC_READ_REGISTERS:
  case MB_FC_READ_INPUT_REGISTER:
    au8Buffer[ NB_HI ]      = highByte(telegram.u16CoilsNo );
    au8Buffer[ NB_LO ]      = lowByte( telegram.u16CoilsNo );
    u8BufferSize = 6;
    break;
  case MB_FC_WRITE_COIL:
    au8Buffer[ NB_HI ]      = ((au16regs[0] > 0) ? 0xff : 0);
    au8Buffer[ NB_LO ]      = 0;
    u8BufferSize = 6;
    break;
  case MB_FC_WRITE_REGISTER:
    au8Buffer[ NB_HI ]      = highByte(au16regs[0]);
    au8Buffer[ NB_LO ]      = lowByte(au16regs[0]);
    u8BufferSize = 6;
    break;
  case MB_FC_WRITE_MULTIPLE_COILS:
    u8regsno = telegram.u16CoilsNo / 16;
    u8bytesno = u8regsno * 2;
    if ((telegram.u16CoilsNo % 16) != 0) {
      u8bytesno++;
      u8regsno++;
    }

    au8Buffer[ NB_HI ]      = highByte(telegram.u16CoilsNo );
    au8Buffer[ NB_LO ]      = lowByte( telegram.u16CoilsNo );
    au8Buffer[ NB_LO + 1 ]    = u8bytesno;
    u8BufferSize = 7;

    u8regsno = u8bytesno = 0; // now auxiliary registers
    for (uint16_t i = 0; i < telegram.u16CoilsNo; i++) {

    }
    break;

  case MB_FC_WRITE_MULTIPLE_REGISTERS:
    au8Buffer[ NB_HI ]      = highByte(telegram.u16CoilsNo );
    au8Buffer[ NB_LO ]      = lowByte( telegram.u16CoilsNo );
    au8Buffer[ NB_LO + 1 ]    = (uint8_t) ( telegram.u16CoilsNo * 2 );
    u8BufferSize = 7;

    for (uint16_t i = 0; i < telegram.u16CoilsNo; i++) {
      au8Buffer[ u8BufferSize ] = highByte( au16regs[ i ] );
      u8BufferSize++;
      au8Buffer[ u8BufferSize ] = lowByte( au16regs[ i ] );
      u8BufferSize++;
    }
    break;
  }

  sendTxBuffer();
  u8state = COM_WAITING;
  return 0;
}

int8_t Modbus::poll() {
  // check if there is any incoming frame
  uint8_t u8current = port->available();

  if (millis() > u32timeOut) {
    u8state = COM_IDLE;
    u16errCnt++;
    return 0;
  }

  if (u8current == 0) return 0;

  // check T35 after frame end or still no frame end
  if (u8current != u8lastRec) {
    u8lastRec = u8current;
    u32time = millis() + T35;
    return 0;
  }
  if (millis() < u32time) return 0;

  // transfer Serial buffer frame to auBuffer
  u8lastRec = 0;
  int8_t i8state = getRxBuffer();
  if (i8state < 7) {
    u8state = COM_IDLE;
    u16errCnt++;
    return i8state;
  }

  // validate message: id, CRC, FCT, exception
  uint8_t u8exception = validateAnswer();
  if (u8exception != 0) {
    u8state = COM_IDLE;
    return u8exception;
  }

  // process answer
  switch ( au8Buffer[ FUNC ] ) {
  case MB_FC_READ_COILS:
  case MB_FC_READ_DISCRETE_INPUT:
    // call get_FC1 to transfer the incoming message to au16regs buffer
   // get_FC1( );
    break;
  case MB_FC_READ_INPUT_REGISTER:
  case MB_FC_READ_REGISTERS :
    // call get_FC3 to transfer the incoming message to au16regs buffer
    get_FC3( );
    break;
  case MB_FC_WRITE_COIL:
  case MB_FC_WRITE_REGISTER :
  case MB_FC_WRITE_MULTIPLE_COILS:
  case MB_FC_WRITE_MULTIPLE_REGISTERS :
    // nothing to do
    break;
  default:
    break;
  }
  u8state = COM_IDLE;
  return u8BufferSize;
}

int8_t Modbus::poll( uint16_t *regs, uint8_t u8size ) {

  au16regs = regs;
  u8regsize = u8size;

  // check if there is any incoming frame
  uint8_t u8current = port->available();
  if (u8current == 0) return 0;

  // check T35 after frame end or still no frame end
  if (u8current != u8lastRec) {
    u8lastRec = u8current;
    u32time = millis() + T35;
    return 0;
  }
  if (millis() < u32time) return 0;

  u8lastRec = 0;
  int8_t i8state = getRxBuffer();
  if (i8state < 7) return i8state;

  // check slave id
  if (au8Buffer[ ID ] != u8id) return 0;

  // validate message: CRC, FCT, address and size
  uint8_t u8exception = validateRequest();
  if (u8exception > 0) {
    if (u8exception != NO_REPLY) {
      buildException( u8exception );
      sendTxBuffer();
    }
    return u8exception;
  }

  u32timeOut = millis() + long(u16timeOut);

  // process message
  switch ( au8Buffer[ FUNC ] ) {
  case MB_FC_READ_COILS:
  case MB_FC_READ_DISCRETE_INPUT:
    return process_FC1( regs, u8size );
    break;
  case MB_FC_READ_INPUT_REGISTER:
  case MB_FC_READ_REGISTERS :
    return process_FC3( regs, u8size );
    break;
  case MB_FC_WRITE_COIL:
    return process_FC5( regs, u8size );
    break;
  case MB_FC_WRITE_REGISTER :
    return process_FC6( regs, u8size );
    break;
  case MB_FC_WRITE_MULTIPLE_COILS:
    return process_FC15( regs, u8size );
    break;
  case MB_FC_WRITE_MULTIPLE_REGISTERS :
    return process_FC16( regs, u8size );
    break;
  default:
    break;
  }
}

void Modbus::init(uint8_t u8id, uint8_t u8serno, uint8_t u8txenpin) {
  this->u8id = u8id;
  this->u8serno = (u8serno > 3) ? 0 : u8serno;
  this->u8txenpin = u8txenpin;
  this->u16timeOut = 1000;// intially set for 1000
}

int8_t Modbus::getRxBuffer() {
  boolean bBuffOverflow = false;

  if (u8txenpin > 1) digitalWrite( u8txenpin, LOW );

  u8BufferSize = 0;
  while ( port->available() ) {
    au8Buffer[ u8BufferSize ] = port->read();
    u8BufferSize ++;

    if (u8BufferSize >= MAX_BUFFER) bBuffOverflow = true;
  }
  u16InCnt++;

  if (bBuffOverflow) {
    u16errCnt++;
    return ERR_BUFF_OVERFLOW;
  }
  u32timeOut=500;
   // u32timeOut = millis() + (unsigned long) u16timeOut;
  return u8BufferSize;
}

void Modbus::sendTxBuffer() {
  uint8_t i = 0;

  // append CRC to message
  uint16_t u16crc = calcCRC( u8BufferSize );
  au8Buffer[ u8BufferSize ] = u16crc >> 8;
  u8BufferSize++;
  au8Buffer[ u8BufferSize ] = u16crc & 0x00ff;
  u8BufferSize++;

  // set RS485 transceiver to transmit mode
  if (u8txenpin > 1) {
    switch ( u8serno ) {
#if defined(UBRR1H)
    case 1:
      UCSR1A = UCSR1A | (1 << TXC1);
      break;
#endif

#if defined(UBRR2H)
    case 2:
      UCSR2A = UCSR2A | (1 << TXC2);
      break;
#endif

#if defined(UBRR3H)
    case 3:
      UCSR3A = UCSR3A | (1 << TXC3);
      break;
#endif
    case 0:
    default:
      UCSR0A = UCSR0A | (1 << TXC0);
      break;
    }
    digitalWrite( u8txenpin, HIGH );
  }

  // transfer buffer to serial line
  port->write( au8Buffer, u8BufferSize );

  // keep RS485 transceiver in transmit mode as long as sending
  if (u8txenpin > 1) {
    switch ( u8serno ) {
#if defined(UBRR1H)
    case 1:
      while (!(UCSR1A & (1 << TXC1)));
      break;
#endif

#if defined(UBRR2H)
    case 2:
      while (!(UCSR2A & (1 << TXC2)));
      break;
#endif

#if defined(UBRR3H)
    case 3:
      while (!(UCSR3A & (1 << TXC3)));
      break;
#endif
    case 0:
    default:
      while (!(UCSR0A & (1 << TXC0)));
      break;
    }

    // return RS485 transceiver to receive mode
    digitalWrite( u8txenpin, LOW );
  }
  port->flush();
  u8BufferSize = 0;

  // set time-out for master
//  u32timeOut = millis() + (unsigned long) u16timeOut;
 u32timeOut=500;
  // increase message counter
  u16OutCnt++;
}

uint16_t Modbus::calcCRC(uint8_t u8length) {
  unsigned int temp, temp2, flag;
  temp = 0xFFFF;
  for (unsigned char i = 0; i < u8length; i++) {
    temp = temp ^ au8Buffer[i];
    for (unsigned char j = 1; j <= 8; j++) {
      flag = temp & 0x0001;
      temp >>= 1;
      if (flag)
        temp ^= 0xA001;
    }
  }
  // Reverse byte order.
  temp2 = temp >> 8;
  temp = (temp << 8) | temp2;
  temp &= 0xFFFF;
  // the returned value is already swapped
  // crcLo byte is first & crcHi byte is last
  return temp;
}

uint8_t Modbus::validateRequest() {
  // check message crc vs calculated crc
  uint16_t u16MsgCRC =
    ((au8Buffer[u8BufferSize - 2] << 8)
    | au8Buffer[u8BufferSize - 1]); // combine the crc Low & High bytes
  if ( calcCRC( u8BufferSize - 2 ) != u16MsgCRC ) {
    u16errCnt ++;
    return NO_REPLY;
  }

  // check fct code
  boolean isSupported = false;
  for (uint8_t i = 0; i < sizeof( fctsupported ); i++) {
    if (fctsupported[i] == au8Buffer[FUNC]) {
      isSupported = 1;
      break;
    }
  }
  if (!isSupported) {
    u16errCnt ++;
    return EXC_FUNC_CODE;
  }

  // check start address & nb range
 // uint16_t u16regs = 4000;
 uint16_t u16regs = 0;
  uint8_t u8regs;
  switch ( au8Buffer[ FUNC ] ) {
  case MB_FC_READ_COILS:
  case MB_FC_READ_DISCRETE_INPUT:
  case MB_FC_WRITE_MULTIPLE_COILS:
    u16regs = word( au8Buffer[ ADD_HI ], au8Buffer[ ADD_LO ]) / 16;
    u16regs += word( au8Buffer[ NB_HI ], au8Buffer[ NB_LO ]) / 16;
    u8regs = (uint8_t) u16regs;
    if (u8regs > u8regsize) return EXC_ADDR_RANGE;
    break;
  case MB_FC_WRITE_COIL:
    u16regs = word( au8Buffer[ ADD_HI ], au8Buffer[ ADD_LO ]) / 16;
    u8regs = (uint8_t) u16regs;
    if (u8regs > u8regsize) return EXC_ADDR_RANGE;
    break;
  case MB_FC_WRITE_REGISTER :
    u16regs = word( au8Buffer[ ADD_HI ], au8Buffer[ ADD_LO ]);
    u8regs = (uint8_t) u16regs;
    if (u8regs > u8regsize) return EXC_ADDR_RANGE;
    break;
  case MB_FC_READ_REGISTERS :
  case MB_FC_READ_INPUT_REGISTER :
  case MB_FC_WRITE_MULTIPLE_REGISTERS :
    u16regs = word( au8Buffer[ ADD_HI ], au8Buffer[ ADD_LO ]);
    u16regs += word( au8Buffer[ NB_HI ], au8Buffer[ NB_LO ]);
    u8regs = (uint8_t) u16regs;
    if (u8regs > u8regsize) return EXC_ADDR_RANGE;
    break;
  }
  return 0; // OK, no exception code thrown
}

uint8_t Modbus::validateAnswer() {
  // check message crc vs calculated crc
  uint16_t u16MsgCRC =
    ((au8Buffer[u8BufferSize - 2] << 8)
    | au8Buffer[u8BufferSize - 1]); // combine the crc Low & High bytes
  if ( calcCRC( u8BufferSize - 2 ) != u16MsgCRC ) {
    u16errCnt ++;
    return NO_REPLY;
  }

  // check exception
  if ((au8Buffer[ FUNC ] & 0x80) != 0) {
    u16errCnt ++;
    return ERR_EXCEPTION;
  }

  // check fct code
  boolean isSupported = false;
  for (uint8_t i = 0; i < sizeof( fctsupported ); i++) {
    if (fctsupported[i] == au8Buffer[FUNC]) {
      isSupported = 1;
      break;
    }
  }
  if (!isSupported) {
    u16errCnt ++;
    return EXC_FUNC_CODE;
  }

  return 0; // OK, no exception code thrown
}

void Modbus::buildException( uint8_t u8exception ) {
  uint8_t u8func = au8Buffer[ FUNC ];  // get the original FUNC code

  au8Buffer[ ID ]      = u8id;
  au8Buffer[ FUNC ]    = u8func + 0x80;
  au8Buffer[ 2 ]       = u8exception;
  u8BufferSize         = EXCEPTION_SIZE;
}

The functionality Check
void Modbus::get_FC3() {
  uint8_t u8byte, i;
  u8byte = 3;

  for (i = 0; i < au8Buffer[ 2 ] / 2; i++) {
    au16regs[ i ] = word(
    au8Buffer[ u8byte ],
    au8Buffer[ u8byte + 1 ]);
    u8byte += 2;
  }
}

int8_t Modbus::process_FC1( uint16_t *regs, uint8_t u8size ) {
  uint8_t u8currentRegister, u8currentBit, u8bytesno, u8bitsno;
  uint8_t u8CopyBufferSize;
  uint16_t u16currentCoil, u16coil;

  // get the first and last coil from the message
  uint16_t u16StartCoil = word( au8Buffer[ ADD_HI ], au8Buffer[ ADD_LO ] );
  uint16_t u16Coilno = word( au8Buffer[ NB_HI ], au8Buffer[ NB_LO ] );

  // put the number of bytes in the outcoming message
  u8bytesno = (uint8_t) (u16Coilno / 8);
  if (u16Coilno % 8 != 0) u8bytesno ++;
  au8Buffer[ ADD_HI ]  = u8bytesno;
  u8BufferSize         = ADD_LO;

  // read each coil from the register map and put its value inside the outcoming message
  u8bitsno = 0;

  for (u16currentCoil = 0; u16currentCoil < u16Coilno; u16currentCoil++) {
    u16coil = u16StartCoil + u16currentCoil;
    u8currentRegister = (uint8_t) (u16coil / 16);
    u8currentBit = (uint8_t) (u16coil % 16);

    bitWrite(
    au8Buffer[ u8BufferSize ],
    u8bitsno,
    bitRead( regs[ u8currentRegister ], u8currentBit ) );
    u8bitsno ++;

    if (u8bitsno > 7) {
      u8bitsno = 0;
      u8BufferSize++;
    }
  }

  // send outcoming message
  if (u16Coilno % 8 != 0) u8BufferSize ++;
  u8CopyBufferSize = u8BufferSize +2;
  sendTxBuffer();
  return u8CopyBufferSize;
}

int8_t Modbus::process_FC3( uint16_t *regs, uint8_t u8size ) {

  uint8_t u8StartAdd = word( au8Buffer[ ADD_HI ], au8Buffer[ ADD_LO ] );
  uint8_t u8regsno = word( au8Buffer[ NB_HI ], au8Buffer[ NB_LO ] );
  uint8_t u8CopyBufferSize;
  uint8_t i;

  au8Buffer[ 2 ]       = u8regsno * 2;
  u8BufferSize         = 3;

  for (i = u8StartAdd; i < u8StartAdd + u8regsno; i++) {
    au8Buffer[ u8BufferSize ] = highByte(regs[i]);
    u8BufferSize++;
    au8Buffer[ u8BufferSize ] = lowByte(regs[i]);
    u8BufferSize++;
  }
  u8CopyBufferSize = u8BufferSize +2;
  sendTxBuffer();

  return u8CopyBufferSize;
}

int8_t Modbus::process_FC5( uint16_t *regs, uint8_t u8size ) {
  uint8_t u8currentRegister, u8currentBit;
  uint8_t u8CopyBufferSize;
  uint16_t u16coil = word( au8Buffer[ ADD_HI ], au8Buffer[ ADD_LO ] );

  // point to the register and its bit
  u8currentRegister = (uint8_t) (u16coil / 16);
  u8currentBit = (uint8_t) (u16coil % 16);

  // write to coil
  bitWrite(
  regs[ u8currentRegister ],
  u8currentBit,
  au8Buffer[ NB_HI ] == 0xff );

  // send answer to master
  u8BufferSize = 6;
  u8CopyBufferSize = u8BufferSize +2;
  sendTxBuffer();

  return u8CopyBufferSize;

}

int8_t Modbus::process_FC6( uint16_t *regs, uint8_t u8size ) {

  uint8_t u8add = word( au8Buffer[ ADD_HI ], au8Buffer[ ADD_LO ] );
  uint8_t u8CopyBufferSize;
  uint16_t u16val = word( au8Buffer[ NB_HI ], au8Buffer[ NB_LO ] );

  regs[ u8add ] = u16val;

  // keep the same header
  u8BufferSize         = RESPONSE_SIZE;

  u8CopyBufferSize = u8BufferSize +2;
  sendTxBuffer();

  return u8CopyBufferSize;
}

int8_t Modbus::process_FC15( uint16_t *regs, uint8_t u8size ) {
  uint8_t u8currentRegister, u8currentBit, u8frameByte, u8bitsno;
  uint8_t u8CopyBufferSize;
  uint16_t u16currentCoil, u16coil;
  boolean bTemp;

  // get the first and last coil from the message
  uint16_t u16StartCoil = word( au8Buffer[ ADD_HI ], au8Buffer[ ADD_LO ] );
  uint16_t u16Coilno = word( au8Buffer[ NB_HI ], au8Buffer[ NB_LO ] );

  // read each coil from the register map and put its value inside the outcoming message
  u8bitsno = 0;
  u8frameByte = 7;
  for (u16currentCoil = 0; u16currentCoil < u16Coilno; u16currentCoil++) {

    u16coil = u16StartCoil + u16currentCoil;
    u8currentRegister = (uint8_t) (u16coil / 16);
    u8currentBit = (uint8_t) (u16coil % 16);

    bTemp = bitRead(
    au8Buffer[ u8frameByte ],
    u8bitsno );

    bitWrite(
    regs[ u8currentRegister ],
    u8currentBit,
    bTemp );

    u8bitsno ++;

    if (u8bitsno > 7) {
      u8bitsno = 0;
      u8frameByte++;
    }
  }

  // send outcoming message
  // it's just a copy of the incomping frame until 6th byte
  u8BufferSize         = 6;
  u8CopyBufferSize = u8BufferSize +2;
  sendTxBuffer();
  return u8CopyBufferSize;
}

int8_t Modbus::process_FC16( uint16_t *regs, uint8_t u8size ) {
  uint8_t u8func = au8Buffer[ FUNC ];  // get the original FUNC code
  uint8_t u8StartAdd = au8Buffer[ ADD_HI ] << 8 | au8Buffer[ ADD_LO ];
  uint8_t u8regsno = au8Buffer[ NB_HI ] << 8 | au8Buffer[ NB_LO ];
  uint8_t u8CopyBufferSize;
  uint8_t i;
  uint16_t temp;

  // build header
  au8Buffer[ NB_HI ]   = 0;
  au8Buffer[ NB_LO ]   = u8regsno;
  u8BufferSize         = RESPONSE_SIZE;

  // write registers
  for (i = 0; i < u8regsno; i++) {
    temp = word(
    au8Buffer[ (BYTE_CNT + 1) + i * 2 ],
    au8Buffer[ (BYTE_CNT + 2) + i * 2 ]);

    regs[ u8StartAdd + i ] = temp;
  }
  u8CopyBufferSize = u8BufferSize +2;
  sendTxBuffer();

  return u8CopyBufferSize;
}

several suggestions:  1) separate the code to write to the modbus from the code to read the modbus 2) use something like select() or poll() after writing to the modbus, then call the function to read the modbus. 3) modbus does not initiate communication, it only responds to commands (there are several different commands and your code does not allow for each command having variations in the format. )  4) the length of each command and response message can (and usually is) different.  5) do not send useless bytes (all those zeros).  5) (cont)

all modbus communication is a) command/request b) response.  Your code is not allowing for that

suggest setting up each command/request from separate functions and each of those separate functions call a serial write function, then select() then a serial read function.  During the read, need to check the device id to determine if response is to be ignored or not. Then check the response type to determine what to do (it may be an error response) then check the length to determine how many bytes still to read,  then read the data bytes and CRC, Then check the CRC to determine the validity of the message.

@user3629249 is there any example code written in C , to get send command and get response.The above code written in Embedded c . is there already code written for Atmega 328 or modbus functions.

The newly posted edit, the C++ code, can be changed to C by replacing all the Modbus:: sequences with modbus_.   I did not note any other items that are specific to C++, however, the C++ code is assuming several definitions and structs are already setup, and available.

the use of the type: boolean means you will need the statement: #include <stdbool.h>

for ease of readability of the C++ code, 1) suggest the width of an indent be 4 spaces rather than just 2 spaces 2) separate the code blocks (for, if, else, while, do...while, switch, case, default) via a blank line.  3) the file name extension needs to be changed from cpp to c

@user3629249 Is there any code already written in C for mODBUS RTU

this may be of some help: http://cboard.cprogramming.com/networking-device-communication/149507-modbus-rtu-c-programming.html for some code and here is the home web site for modbus: http://www.modbus.org/tech.php and here us some more sample code: http://control.com/thread/1301963718


text:
Reading a .csv file element wise
I'm fairly new to arduino programming and C/C++. I would like to read a .csv file element wise, and send each element via. a nRF24L01 tranceiver to a raspberry pi. Right now I'm able to read the .csv file with Serial.write(<file>.read()). I was wondering if there's a way to read each element one at a time, if so how would i do that?
My thoughts (Pseudo code-ish):
loop through every element in .csv file {
    save the current element to X.
    send X to raspberry pi (I already have a function for sending)
}

I hope someone can help. Thanks in advance.

Take a look at this post. Since the file is csv, you can construct a similar approach using a sscanf on each line you read.

Are all your CSV values all numeric, or do you have textual data in there as well?

The read() method works character-wise, not element-wise. Then you
have to rethink your algorithm to loop over characters:

store each character in a buffer
send the whole buffer (i.e. a single element) when you see a delimiter

Example:
const size_t BUFFER_SZ = ...;
char buffer[BUFFER_SZ];
size_t pos = 0;    // current write position in buffer
int c;

// While we can read a character:
while ((c = <file>.read()) != -1) {

    // If we get a delimiter, then we have a complete element.
    if (c == ',' || c == '\n') {
        buffer[pos] = '\0';         // terminate the string
        raspberry.println(buffer);  // send to the RPi
        pos = 0;                    // ready for next element
    }

    // Otherwise, store the character in the buffer.
    else if (pos < BUFFER_SZ-1) {
        buffer[pos++] = c;
    }
}

Here the buffer is sent as a string. If you want to parse it into a
number, you can use sscanf.
This code assumes Unix text-file conventions, i.e. each line of the file
(including the last one) being terminated by an LF character. You may
have to adapt if your file is different.


text:
Change range of IR programatically
I am building a IR-based laser tag system. The basics are working fine. One feature, that I want to have, is different weapon modes with different ranges.
How can I change the range of an IR transmitter with as little hardware as possible, or at best, completely in software?

Just guessing, but if you are using IR LEDs as transmitters, the only way I see to alter range is by altering the amount of current applied to the IR LEDs, and PWM would not be a solution in this particular case. However I wouldn't say this is an accurate way to get different ranges, if (again) as I guess you would like to get differences in range of tenths of meters, or even meters. more or less the same accuracy you get when your TV remote's batteries are getting discharged and you must get up from your sofa a given distance...

Roberto's suggestion can only work if the beam diverges significantly. A laser beam is practically cylindrical at close distances, and you will not get enough attenuation for this idea to work. You should instead use lightsaber technology to make the beam stop at a fixed distance.

It's not a laser, sorry for the confusion. That's only the name of the game. All it is is an IR LED behind a lens.

The problem with altering the current is that I have the IR LED behind a transistor that allows for the full current to go through, so I can't even use two pins with different resistors. From what I gather from the datasheet of an infrared receiver, it looses a lot of responsivity if the frequency of the signal does not match the frequency of the receiver exactly. Would that work? So e.g. if I want full range, I use 38 khz, while if I want half range, I use 36khz.

@Dakkaron You should be able to easily test that. Using an led without a resistor isn't advisable, unless the voltage of the batteries is lower than the forward voltage of the diode (or a bit above, since you are only pulsing the led). I think you could use PWM, but you'd have to use a frequency that's way above 38khz.

I am using a resistor, I just meant, I cannot use two different ports with different resistors, because there is the transistor behind that. Off course I have a resistor between transistor, LED and VCC. Using PWM on a much higher frequency also makes sense, thank you. I will try that.

@EdgarBonet Please describe this lightsaber technology to us.

@Dakkaron - you could simply use two transistors, each with its own current limit resistor.  Chose the values correctly and you can actually get three modes - one, the other, or both.

Consider using a Sharp Distance Sensor in addition to your shoot / confirm-hit inferred LED & receiver.
This Sharp distance sensor is specified to detect objects that reflect IR light from 100 cm-500 cm.

How can I change the range of an IR transmitter with as little
  hardware as possible, or at best, completely in software?

I believe the sensors produce an analog output that can feed into an Arduino's ADC.  So software (by itself) can be used to adjust the threshold distance.
Similar devices I have used have a narrow sensing field.  They only reported the distance to objects directly in front of them.  Also, I found they were effected by defective (burning out?) florescent light sources.  We assumed failing florescent light sources produced IR radiation similar in frequency as used by the sensor's IR emitter.  Also, the analog output is slightly stair stepped in the unit we tested.  I say this in case you were expecting to use increase relative accuracy of several readings if not precision of any given reading.

No, the receivers are digital which product an all-or-nothing output.  Also the entire receive systems apparently already exist and are not being modified by the asker.

Perhaps there are several different types of Sharp Distance Sensors.  The Sharp Distance Sensors we used produced a voltage that was proportional to the distance.  However, we could not use them as they actually change the voltage in small desecrate steps.

Instead of modifying the TX power, why not make the receiver read the light level. You just need to transmit some data, like the weapon ID.
If it works you could send more information, including how stable the weapon that hit the target was, during the shoot, using an accelerometer.

My devices have to be compatible to the guns I already have. Those are a proprietary system, so I have no control over them. Also the receivers I use on my devices are integrated IR receiver circuits (something like this: http://www.vishay.com/docs/82491/tsop382.pdf) and they only report the demodulated data, not the light level.

@Dakkaron, note the AGC block in the specification sheet you linked to above.  There is no way to determine the AGC setting from the outside world.  No way to tell how strong the source is.  No way to tell how far away it is. So you need to either supplement your setup with the Sharp Distance measurement device (my 1st answer) or utilize a power varying secondary signal source  as a reference (my 2nd answer).

Let us assume you are using an ordinary inferred LED and a type of inferred detector used in remote control entertainment equipment.
Inferred LED modulation is simple and is well documented on the web.
The inferred receiver is a complex device.  It contains, among other features, an Automated Gain Control (AGC) circuit and a Phase Locked Loop (PLL) circuit.  The AGC adjusts the gain and makes it impossible to gauge the power of one IR source relative to another. The PLL "locks onto" the signal.
Consider using and adjusting the power of a secondary inferred LED transmitter transmitting at the same time as the primary LED transmitter is being received. The secondary inferred LED transmitter is local to the inferred LED receiver and transmits a unique code.  The primary inferred LED transmitter is part of the opponent's equipment and transmits a unique code.  Slowly reduce the power of the secondary inferred LED source until the code switches from the secondary source to the primary source.  The power used by the secondary inferred LED when the switch occurs should be proportional to the distance to the primary inferred LED.
In the above scenario we have used the AGC to "hide" the primary source until we reduced the power of the secondary source to just below that of the primary source.  And we used the PLL to "lock onto" the strongest signal.


text:
Gas Sensors with Arduino + Interfacing Circuit
I am intended to use Gas Sensors (MQ series) on protoboard so I connect it to Arduino and perform analogue read.
I would like to request if possible to get the interfacing circuit (resistors, amplification.. etc.) or if there are schematics available.
Also, when I read the data digitized into 10bits ADC value, how can I convert it into units (ppm)?
Thank you so much in advance.

I would suggest checking out one of the gas sensors that comes with a breakout board. I've found the pins don't quite match the spacing of a protoboard and make it a little difficult to set up. Seeed Studio sells some of the sensors with a breakout board and has some nice examples of how to convert the values to PPM.
http://www.seeedstudio.com/wiki/Grove_-_Gas_Sensor(MQ5)

Thanks @kbuck3
Those SeedStudio sensors are ready to be connected but I believe they need special board as shield for the Arduino. or can we connect them directly if you used them before? Thank you.

The "special board" they have in the screenshots is just a shield that makes it easy to use the connector cable. You should be able to just use some female-to-male wires and connect the sensor to your protoboard or Arduino.

You can connect the directly to the Arduino +5, Gnd and Signal.
I don't know of any calibration data for the sensors that I have.  I suppose you could take the maximum concentration the sensor can measure and divide this by 1024, but I don't know if the value returned is linear or logarithmic.
The data sheet does have some info on, but this page may be more helpful
http://forum.arduino.cc/index.php?topic=230945.0
Oh and don't forget the warm up time on the sensors!


text:
initial power output in the digital io pins of an Arduino controller
I am a newbie..  I am integrating Arduino controller with Matlab
I have connected my arduino DUE board in COM7. And I have also connected a DC Motor in one of the digital output pins (D3)
So when I just execute the matlab built in arduino function to initialise or establish a connection my motor runs for a second and then stops. I dont want my motor to run initially. Is there a solution or an alternative to do this.
a = arduino('COM7', 'Due');

Thanks in advance.

How have you connected your motor?

@Majenko I have just connected the motor to the output lines of the Arduino Motor Shield directly (using an external power source).

It sounds like there is a problem with the Matlab function, but I guess you can't fix that.  So here is my sledge hammer approach, put a PNP transistor in the supply line to the motor shield and control it from a digital port on the Arduino.  The digital pin will start up high and this will block the power to the motor, when Matlab sends the digital lines to low, power will flow, but you will have control.  You will need to ask someone about what transistor (and other bits) to use to achieve this, but there my theory.  Hope it works.


text:
Multiple VL6180X distance sensors interactive problem
I am trying to use a VL6180X distance sensor and an Arduino Uno board for individual sensor doing individual distance sensing. This sensor follows the I2C protocol. Since for the same type of sensor, the I2C protocol says that they would all have the same address, I am thinking about using the chip enable pin (GPIO00) on the sensor chip to toggle sensor when doing the distance measuring.
I am able to update the address of the sensor group now. But I think to obtain individual results from different sensors on the Arduino serial monitor, right now I can only do one time setup sensor thing (like I couldn't update and toggle around different sensors). Once I started to do that, the results from the serial monitor were wrong. Any advice how I can continue to toggle around the sensor and make them work using the GPIO00 pin?
The code I'm using is:
#include <Wire.h>
#include <VL6180X.h>
#define Address1 0x20
#define Address2 0x22
#define Address3 0x24

VL6180X sensor;

int pin2 = 2;
int pin3 = 3;
int pin4 = 4;

void setup() {
  Serial.begin(9600);
  Wire.begin();
  pinMode(pin2,OUTPUT);
  pinMode(pin3,OUTPUT);
  pinMode(pin4,OUTPUT);
  digitalWrite(pin2,HIGH);
  digitalWrite(pin3,HIGH);
  digitalWrite(pin4,HIGH);
  sensor.init();
  sensor.configureDefault();
  sensor.writeReg(VL6180X::SYSRANGE__MAX_CONVERGENCE_TIME, 30);
  sensor.writeReg16Bit(VL6180X::SYSALS__INTEGRATION_PERIOD, 50);
  sensor.writeReg16Bit(VL6180X::INTERLEAVED_MODE__ENABLE,0);
  sensor.setTimeout(500);
  sensor.stopContinuous();
  delay(300);
  sensor.startInterleavedContinuous(100);
}

void loop() {
  hello2();
  delay(1000);
}

void hello1(){
  sensor.setAddress(0x29);
  Serial.println(sensor.readReg(0x212),HEX);
  sensor.setAddress(Address1);
  sensor.writeReg(0x212,Address1);
  Serial.println(sensor.readReg(0x212),HEX);
  Serial.println();
  digitalWrite(pin2,HIGH);
  digitalWrite(pin3,LOW);
  digitalWrite(pin4,LOW);
  Serial.print("Ambient 1: ");
  Serial.print(sensor.readAmbientContinuous());
  if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); }
  Serial.print("\tRange 1: ");
  Serial.print(sensor.readRangeContinuousMillimeters());
  if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); }
  Serial.println();
  sensor.writeReg(0x212,0x52);
  digitalWrite(pin2,HIGH);
  digitalWrite(pin3,HIGH);
  digitalWrite(pin4,HIGH);
}

void hello2(){
  sensor.setAddress(0x52);
  Serial.println(sensor.readReg(0x212),HEX);
  sensor.setAddress(Address2);
  sensor.writeReg(0x212,Address2);
  Serial.println(sensor.readReg(0x212),HEX);
  Serial.println();
  digitalWrite(pin2,LOW);
  digitalWrite(pin3,HIGH);
  digitalWrite(pin4,LOW);
  Serial.print("Ambient 2: ");
  Serial.print(sensor.readAmbientContinuous());
  if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); }
  Serial.print("\tRange 2: ");
  Serial.print(sensor.readRangeContinuousMillimeters());
  if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); }
  Serial.println();
  sensor.writeReg(0x212,0x52);
}

void hello3(){
  sensor.setAddress(0x52);
  Serial.println(sensor.readReg(0x212),HEX);
  sensor.setAddress(Address3);
  sensor.writeReg(0x212,Address3);
  Serial.println(sensor.readReg(0x212),HEX);
  Serial.println();
  digitalWrite(pin2,LOW);
  digitalWrite(pin3,LOW);
  digitalWrite(pin4,HIGH);
  Serial.print("Ambient 3: ");
  Serial.print(sensor.readAmbientContinuous());
  if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); }
  Serial.print("\tRange 3: ");
  Serial.print(sensor.readRangeContinuousMillimeters());
  if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); }
  Serial.println();
  sensor.writeReg(0x212,0x52);
}

Any help would be appreciated!

I'm trying to do the same thing. Did you get it to work by chance?

There are ICs that expand the I2C bus allowing you to have multiple devices with the same ID on (can't remember what they are called at the mo).

You can use an I2C multiplexer (TCA9548A). One I2C input can be output to one of the eight I2C outputs.
It has 8 configurable addresses, so you can connect 64 I2C devices with the same address by using 8 multiplexer chips.

You are using only one VL6180 object and then changing its address repeatedly. In your setup(), since all the sensors are enabled and have the same address, you're sending init commands to all of them; I'm not sure what will happen (multiple ACK/NACKs?), but it's probably not a good thing. Your hello() functions actually changes the address of all the sensors (twice?), if the commands even work, and then enables only one to read from. A host of undefined problems is expected.
To fix this, you have to do all the config and address changes in setup():

Before setup(), create 3 VL6180 objects: sensor1, sensor2, sensor3
In setup(), enable ONLY ONE sensor, and call all the sensor initialization commands on one of the objects you created (sensor1, maybe), as usual. Then call setAddress() on that sensor object to change its address to a unique one. This object is now tied to the physical sensor which has been enabled; all future operations related to that sensor, must be done on this object.
Then, disable this first sensor, and enable another and repeat the same steps as before on another object (sensor2), making sure to make each sensor's address unique. This way, you configure only one sensor at a time.
After configuring all three, you can now use their respective objects to get readings in loop().

I believe, if I have read this Multiple VL6180x in a design right, then you can change the I2C addresses of the sensors.  You need to hold all the sensors in reset then send it the change ID message.  I'm not sure if it is permanent or you have to do it each power up.
Does that help?

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


text:
I need more memory!
I am trying to make a RBB Arduino based project and I only need 3 pins. In the future I may use one to two more. I wanted to use an ATtiny85 however my code is 13,270 bytes and it would not fit. So I decided to use an ATtiny84 but it also would not fit, it will fit on an ATmega328p but I do not want to use one because i want to keep the project relatively small and I for sure do not need that many pins. Does anyone know of a chip that has a lot of memory but not many pins, or some other solution. Thank you, any help is appreciated.

Have you tried Atmel's parametric search tool yet?

AFAIK, 8 KiB of flash is the most you can have on an AVR in a DIP
package with less than 28 pins. If you do not mind soldering
surface-mount parts, the 328P is available in TQFP and VQFN packages,
significantly smaller than the DIP version.
Otherwise you could try to optimize your program to fit in 8 KiB.
The Arduino libraries are often inefficient size-wise, and in many
instances you can save quite a lot by rewriting the parts that you need
on top of just avr-libc. Note that
this libc is always linked to your program by the Arduino IDE.

Ok, I tried to optimize my code but could not get it much smaller. I guess my best option is to use a TQFP version, I didn't think about that. Thank you.

There are a few ways to optimize your code and reduce the size. Have a look on this document from Atmel. I've used some tips to reduce the size of my bootloader once.
http://www.atmel.com/images/doc8453.pdf
For the AVR family I'm not familiar with any option. You could use a small QFN package for the atmega328p as well... You might find some small ARM with much more memory and small size.


text:
SparkFun EL Sequencer does not work
I have connected to EL wire, 12v EL Inverter to SparkFun EL Sequencer but it does not work (no battery is connected). The connections are the same like in Hookup Guide (https://cdn.sparkfun.com/assets/learn_tutorials/3/6/9/ELSequencerHookUp_bb.png). Furthermore, there is no light indicating that it works but I hear a noise/whistle from the Inverter.
Do I have to program the EL Sequencer or does it automatically turn the EL wire on?

It looks like Sparkfun probably only put the bootloader on the board. The tutorial is written in a way that suggests the need to flash the board.
Also the board does not imediatly work with the 12V inverter. If you have the battery you should attach it and see the PWR LED turn on.
The inverter only provides voltage to the EL wire and not the Microcontroller, power to the microcontroller is provided by way of a regulator(U2), not the LM317 the last quote from the one comment shows how you can connect to the 12V inverter.
What you should do instead of having to go the route of all the wiring is to connect both the battery to BATT IN and the inverter, but ensuring that the microcontroller is programmed before hand.

Arduino Code
Once you have all of your hardware hooked up properly, it’s time to
  program your Sequencer to run the EL Wire display as you want. You
  will need to download the Arduino code in order to follow along with
  the example.
You can also download the most up-to-date code from the EL Sequencer
  GitHub repository.
We will be working with the “SparkFun_EL_Example.ino” example. If you
  need a review on how to upload Arduino code to your board or using the
  Arduino IDE, please check our tutorial here. Also, if you are unsure
  about installing the FTDI drivers, please check out this tutorial.

Also from one of the Tech support notes:

Using 12V to Power Both the EL Inverter & Microcontroller
If you are using a 12V wall adapter to power the 12V Inverter, you
  would still need to provide power to the microcontroller side. One
  solution with your 12V wall adapter to provide power to the 12V
  inverter and Atmega328P is to get a barrel jack adapter to 2 pin JST
  adapter [ https://www.sparkfun.com/products/8734 ], thus connecting
  the 12V wall adapter to the “BATT IN.” This is assuming that your wall
  adapter is using a center positive barrel jack.
From there you can connect the 2 pin JST labeled “DC Out” to the 12V
  inverter’s input voltage. To connect, I recommend using the male DC
  barrel jack adapter [ https://www.sparkfun.com/products/10287 ] and a
  2pin JSt jumper wire [ https://www.sparkfun.com/products/8670 or
  https://www.sparkfun.com/products/8671 ]. You will need to wire strip
  the cable to be able to connect it to the screw terminals.
Lastly, you would need to add a solder jumper to SJ1 so that you
  bypass the voltage regulator between your external power (“BATT IN”)
  to provide power to the inverter’s “DC OUT”. This will provide power
  to your 12V inverter’s input.

Warning: if SJ1 is closed, inverter will see 5V with FTDI plugged in and switch at USB


text:
Why connect arduino with Rasberry pi?
I have a question about connecting a Arduino with Raspberry Pi.
What is the benefit of connecting the two?

Thanks a lot. Thats some great answers :-) Do any of you know any good resources where I can learn about connecting the two?

Interfacing hardware is easier with the Arduino: more available I/O pins
capable of sourcing and sinking more current, 5 V I/O, analog
inputs, very predictable timings, etc. The Raspberry, on the other hand,
is a real computer with a real OS, has a lot more computing power
and memory, has Internet connectivity, can easily run “standard” web
servers like Apache or nginx... or mostly any Linux software for that
matter.
Some projects can benefit from using both. E.g. if you want to make a
web interface for some low-level hardware sensors.

Why add an Raspberry Pi to an Arduino?
There are some things that simply are beyond the possibilities of Arduino. The first thing that would cross my mind is video processing, HDMI output, decent sound etc.
A Raspberry Pi can be used to add some features to your project aswell. If you make an Arduino controlled robotic arm, you could add an "user interface" to it, using a Raspberry Pi.
Why add an Arduino to an Raspberry Pi?
Some may argue that the Raspberry Pi is much more capable as an Arduino, in every form.
Though, the strengths of Arduino are:

Ease of use. (For GPIO on Raspberry Pi you'll likely need to install something, to make it work with your favorite programming language.)
Real time / deterministic timing, this is one of the best things of Arduino. Given that an Arduino has no "operating system" that can induce random (tiny) delays in your program (other than the millis()/micros() interrupts).

Why do any of this? You could choose an Arduino OR Raspberry Pi
One thing you might not think about is, that by joining an Arduino and a Raspberry Pi, you're joining two important parts of Embedded Systems. Which you can learn a lot from.
Microcontrollers and Single-board computers. This really has a good educational effect. Since you'll not limit yourself to one device or "way of thinking".
Moreover, the interfacing between two devices is often important and will bring some extra problems. (And solving them gives extra knowledge/experience)

I prefer to use arduino type boards as data acquisition units then transfer the data to an actual computer (or raspberry pi) in most of my projects. Arduinos are, in my experience, much more tolerant of fault and accidental crossed circuits than the R pi.  Thus is especially true of the ruggedized or industrial arduino versions.

Good point! One could say that accidently blowing up your Arduino is much cheaper than blowing up a raspberry pi

And it is much easier to destroy a Pi than it is an arduino... Although I love the fact that I often have to add a 0.2V schottky diode in fw bias to control a little MOSFET... just to prevent the cr?p from dying because of a little spike.

authors: وليد مبارك عيد


text:
Row-column scanning to control an 8x8 LED matrix
https://www.arduino.cc/en/Tutorial/RowColumnScanning
This code really confused me because I don't know if the pixels[x][y] is HIGH or LOW in void refreshScreen().
As you look at the code, pixels[x][y] is HIGH and then LOW in void setup(), and then pixels[x][y] is HIGH again in void loop(). Could anyone explain this to me, please？

The pixels array in initialized to all HIGH in setup(). Then one element of the pixel array is set to LOW in readSensors()  which turns on one LED.
The tricky bit is you have to remember to turn off the previous LED. That is why in readSensors() there is the line where an element of pixels is set HIGH while the pixels' array pointers are still pointing at the former (already lit) LED.

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


text:
how do I power my motor shield without an arduino uno?
I want to power my motor shield without my UNO. I have connected the +ve and -ve terminals resulting in lighting up of the LED.
Is there any way to control the motors in this arrangement from the Arduino?

Welcome!
I'm not sure I understand what you are asking because what you are trying to do doesn't make much sense.
The motors connected to the motor shield are controlled by the output pins of the Arduino that the motor shield is plugged in to.
You could run jumper leads from an separate Arduino into your unplugged motor shield, but that's just extending what you already have.  You really do need some form of controller, not necessary a microprocessor, otherwise how can you go forwards and backwards?
Is the problem you have put the Arduino into a plastic case and you can't plug the motor shield in any more?  If so get a set of long male to female connectors (they look like the Arduino connectors) and use them as extensions.
Is the problem you have a different format of board and can't plug it in? If so use the wires method to form the correct connections.
I hope that answers your question, if not please try and explain what I'm misunderstanding.

Thanks a lot for that answer and yes my problem actually is I cant plug in the motor shield directly. so i wanted to know is it necessary to connect all the pins or only some of them will do the work

Right - Order some connectors something like (http://www.hobbytronics.co.uk/arduino-header-10pin?utm_source=google&utm_medium=googleshopping&utm_campaign=googlebase&gclid=CJym0NK4nc0CFeIp0wodDAoKMQ) you need two different lengths.  OR connect ribbon cables/wires from the Arduino to the Shield and that should sort it out.

Which all pins should i connect ??

Only some of them do the work but you would need to look it up in your datasheet for the shield because they can be different.  You also have to remember to connect the grounds together on your two supplies (only -ve not +ve!!) otherwise things won't work.  Whats the shield make and model?

I have a motor shield with L293D micro-controller

Thanks a lot I will check out the datasheet and try to figure out. Thanks a lot

Since you have not revealed exactly WHICH motor shield you are asking about, nobody can answer your question. It depends on exactly how YOUR motor shield is designed.  It does not benefit you to withhold the identity of the board you are asking about. It makes it impossible for us to help you.

I have a motor shield by DK electronics


text:
How to remove SD card safely
I’m constructing an arduino based sytem that uses a SD card and I’m looking for a way to safely remove the card from the system during operation. One way would probably be to turn of the arduino before removal of the SD card, but that is not acceptable in this context.
The library I’m using:
https://www.arduino.cc/en/Reference/SD
Is it possible to safely remove the SD card during operation? If no, how can I minimize the risk of damage to the SD card while inserting and removing it?

The physical construction of the card and socket are designed such that power to the card is cycled properly when the card is inserted and removed. The only thing the firmware has to do is to stop writing to the card before it is removed.
Unexpected removal can cause a problem in "larger" systems (e.g. cellphones or PCs) because they may have structures open on the card that are not yet complete, but small embedded systems typically do not have the capability to do so and so once all writes are completed the card can be removed.
Detection of non-presence of a card is another issue though, and the firmware will have to be designed to not fail in such a situation.

In my early days of computing, the computer used to turn on a led when writing to cassette tape or floppy disk. If you wanted to remove the tape or disk, you had to wait for the led to turn off.
I think that could be your easiest solution.

An SDCard is very much like a hard disk drive.  Both in how it is made and how it is treated by the host.  As such there are critical times where interrupting the communication to the SDCard can cause corruption.
To avoid problems it is advisable to finish all transaction before removing the SDCard.  In a perfect situation all data will be flushed from the host's buffers (cache) and the files being accessed closed.  So research the flush() and the close() function calls in the library you are using.
In order to accomplish the above, it is obvious the host device needs to be told the SDCard is about to be removed.  In most cases this is accomplished using a switch (human interface) and some code to flush and close any open files.
All this said, often people pull SDCards with out any obvious problems.  This is likely because SDCard transactions are fast and completed in fractions of a second.  Also pulling an SDCard when periodically reading a file is far safer then when writing to a file or altering any information on the SDCard (for example the name of a file).  If you can suffer the possibility of corruption, it may be that the added effort is not worth it.  However if you stand lose a great deal, I would advise you to do some research into the best ways to avoid SDCard corruption.

authors: Дмитрий Журавкин


text:
Can you access the EEPROM of an ATtiny with Arduino Code?
I'm attempting to reduce the amount of RAM being used by my program by writing some values to the EEPROM of my micro controller. I'm currently programming on the ATtiny85 which has 512 Bytes of EEPROM. According to the documentation this is how you write to EEPROM:
#include <EEPROM.h>

void setup() {
  EEPROM.write(0, 1);
  EEPROM.write(1, 0);
  EEPROM.write(2, 3);
  EEPROM.write(3, 2);
  EEPROM.write(4, 1);

}

For some reason this isn't working for me and I can't seem to find the error. Am I programming this wrong or can the EEPROM of the ATtiny simply NOT be accessed with Arduino Code?
Here is the Datasheet: http://www.atmel.com/Images/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet-Summary.pdf
Here is the second sketch I'm using to test the EEPROM:
    #include <EEPROM.h>

void setup() {
  EEPROM.write(0, 1);
  EEPROM.write(1, 0);
  EEPROM.write(2, A3);
  EEPROM.write(3, A2);
  EEPROM.write(4, A1);

byte CLK = EEPROM.read(0);

}

void loop() {

  if(CLK == 1)
  {
    for(int i = 0; i < 3; i++)
    {
    digitalWrite(0, HIGH);
    delay(1000);
    digitalWrite(0, LOW);
    delay(1000);
    }
    exit(0);
  }
  else
  {
    for(int i = 0; i < 100; i++)
    {
    digitalWrite(0, HIGH);
    delay(1000);
    digitalWrite(0, LOW);
    delay(1000);
    }
    exit(0);
  }

  exit(0);

}

I wish I had the ATTiny you have with 512MB of EEPROM, it must be a new one. Please have a look at this http://arduino.stackexchange.com/help/how-to-ask

What is wrong with my question?

an ATTiny has 512 bytes of EEPROM and you also asked a similar question earlier. You need to add what you have tried to retrieve those values and how you know they have been retrieved properly. The eeprom values have been written to properly in the above 'snippet'. And that's the problem you have not given all your code.

I didn't write the other EEPROM question. I saw that it was unanswered and decided to ask my own. Also, my question is about the ability of the ATtiny EEPROM to be programmed with Arduino. Like I said, my code was working fine until I switched the value with EEPROM.read(0) which caused the code to just stop working.

the ATTiny can be used with the EEPROM library from the arduino ide it is basically a wrapper of the avr/eeprom.h. What also might kill your first cell in EEPROM is repeatedly reading it in the loop. That kills EEPROM cells, they have limited read write cycles. Also why do you have exit(0)

Thank you, that's some great information. Follow up question: If I write on sketch with the write commands can I then access those values using another sketch? In other words can I split my program up the way I just did in my question?

please would you stop changing the code in the question.

Sorry, I tried to improve it based on your feedback. However, I understand what you're trying to say so thank you I think I can figure it out from here.

okay. I am editing my answer with a bit more stuff please have a look at it.

Move the definition of byte CLK = 0; outside void setup and then do this in void setup:  CLK = EEPROM.read(0);

Problem is that if I set the value of CLK inside the function method I can't access it in any of the other functions.

Here is the second sketch I'm using to test the EEPROM: - no it isn't because that doesn't compile:
sketch_jun22a:16: error: 'CLK' was not declared in this scope

The Arduino EEPROM library is compatible with the ATTiny range of AVR microcontrollers as the library itself is built on the standard Atmel AVR avr/eeprom.h 'library' so it is compatible with all the AVR microcontrollers.
The EEPROM also doesn't take to being written or read to often as EEPROM can wear very quickly. Reading though does not cause much damage though.
Also note that using exit(0); will stop the ATTiny from doing anything else after it is called so I hope your intention is to only run the loop once, if not this would account for either not seeing anything or it only ever running the blinking cycle once.
To answer your follow up question. Yes you can run one sketch to set you values in EEPROM and then use another sketch to read those. That us usually the point of EEPROM it is a memory type that "keeps its value while there is no power".
Also you need to make sure the ATTiny is set to preserve EEPROM during upload with the ISP, this is done with the fuse settings. You need to look for a tutorial on fuse calculators for the AVRs. To set the EESAVE you need to set the High fuse to 0xD7, you can change this in the boards.txt file. Here is a fuse calculator.
If the code that is on your question at the moment is being used you won't be seeing anything as it needs the pins to be set with pinMode. That's a note for others that see this.
Next what you can do is run a basic test code which blinks the LED without anything else going on.
Basically:
void setup(){

 pinMode(0, OUTPUT);

}

void loop(){

 digitalWrite(0, HIGH);
 delay(1000);
 digitalWrite(0, LOW);
 delay(1000);

}

Below is the code you have written, it works I have it running in front of me.
I have commented it and changed a few things to make it work as intended, although the intention is not clear.
#include <EEPROM.h>

byte CLK = 0; //This is a global variable with an initial value

void setup() {
  // put your setup code here, to run once:

  EEPROM.write(0, 1); //set the pin to D1
  delay(5);

  //read from EEPROM address 0
  //this sets the value of the global variable CLK
  CLK = EEPROM.read(0); //place this inside a function

  //just to give an example...
  byte PIN = CLK;   //PIN variable is a local variable

  pinMode(PIN ,OUTPUT); //using that local variable

}

void loop() {
  // put your main code here, to run repeatedly:

  // Note: the below if() will always be true as the value
  // of CLK is never change and shouldn't be changed as
  // it will change the pin number of the output

  if (CLK == 1) {
    for (int a = 0; a < 3; a++) {
      digitalWrite(CLK, HIGH);  //this uses the global variable
      delay(1000);
      digitalWrite(CLK, LOW);
      delay(1000);
    }
    //putting exit(0); will actually stop the program
    //remove it
//    exit(0);
  }
  else {
    for (int a = 0; a < 100; a++) {
      digitalWrite(0, HIGH);  //this has a predefined pin no.
      delay(500);
      digitalWrite(0, LOW);   //this has a predefined pin no.
      delay(500);
    }
    //putting exit(0); will actually stop the program
    //remove it
//    exit(0);
  }
}

Thanks, it works. My problem now is that I can only use EEPROM.write(); inside of a function and that prevents me from creating a global variable that all my function can use.

@IsabelAlphonse   ??. The EEPROM.write() is a function and has to be used within a function. I think you need to start with the basics TBH. What I also think you mean is the read part. I have edited my answer to include the code you have written that works.

@IsabelAlphonse  please can you mark one of the answers as accepted so that the StackExchange system doesn't bump it up in a few weeks and also to allow others to find it more easily when searching for the same problem.

Sorry, I forgot.

You said: "The EEPROM also doesn't take to being written or read to often as EEPROM can wear very quickly. "
Datasheet says:
Memory Flash Endurance: 10,000 Write/Erase Cycles,
EEPROM Endurance: 100,000 Write/Erase Cycles. So EEPROM can be written ten times more often than the flash memory.

@needfulthing The data sheet does say that (I stand to be corrected but I do believe it's per each address, hence improving life of eprom is done with wear-leveling), but when most people go crazy writing to one address of the eeprom it does wear quicker than you would wear out the flash. Most use it as more of a dynamic storage when the device is running, or for settings. While the flash may never reach the amount of read/erase cycles of the flash once made. I just bear the fact of it wearing in mind when making something.

@RSM Ah sure, absolutely true in that aspect.

When you upload a new sketch with the default settings, the EEPROM will be cleared.
"The -e option instructs avrdude to perform a chip-erase before programming; this is almost always necessary before programming the flash."
If you're using the Arduino IDE, the -e option is enabled by default. This is probably why it's not working for you.
See also the question Is there a way to preserve EEPROM contents in AVR Atmega when burning a new firmware to flash with avrdude?

Then my test code should be working at least. I write to the EEPROM in the setup method and set the CLK variable afterwards. But when I enter the loop() method I still can't get my light to blink.

Not sure if things have changed so significantly since the question was asked originally but I'll answer using the Atmel AVR libraries.
Don't assign the EEPROM value to a variable as then you are wasting precious SRAM again. EEPROM has unlimited read cycles.
I can't find any current references to EEPROM.read() as a Macro or function in the Arduino IDE. Instead there is the AVR EEPROM library which uses eeprom_read_byte() as shown below.
#include  <avr/eeprom.h>

// the setup routine runs once when you press reset:
void setup() {
/* The "131" value is used to prevent damaging excess EEPROM writes on every restart.
   If you want to try setting a different GPIO pin for LED blink change the test value in
   both the read and following write to EEPROM address 511 */

    if (eeprom_read_byte((uint8_t*)511) != 131) {
       eeprom_write_byte((uint8_t*)511,131);
// Store the GPIO pin number in EEPROM address 1
       eeprom_write_byte((uint8_t*)1,1);
    };
// initialize the digital pin as an output.
    pinMode(eeprom_read_byte((uint8_t*)1), OUTPUT); // LED pin value stored in EEPROM address 1
}

// the loop routine runs over and over again forever:

void loop() {
    digitalWrite(eeprom_read_byte((uint8_t*)1), HIGH);
    delay(1000);               // wait for a second
    digitalWrite(eeprom_read_byte((uint8_t*)1), LOW);

    delay(1000);               // wait for a second
}

For reference, Arduino has a EEPROM library as part of its ecosystem. https://www.arduino.cc/en/Reference/EEPROM

maybe the reference is there but in Arduino IDE 1.8.5 I am using here if I try and use #include <EEPROM.H> I get a compilation error which is why I posted the working source code I did. C:\Windows\Users1\Users\WINDOWS\AppData\Local\Temp\arduino_modified_sketch_177973\sketch_oct24a.ino:1:20: fatal error: EEPROM.h: No such file or directory

It is now very common to read from EEPROM in an ATTiny, particularly an OSCCAL value. It has also been the case for some embedded devices to perform a superfluous write and read back to external EEPROM during POST. Every boot.
> ---snip---
>     current tick:1 sec
>     EEPROM Init...
>     Write EE_TEST ==0x7cf u8EEData1=0xaa
>     Read EE_TEST ==0x7cf u8EEData1=0xaa
>     [EEPROM 24c16 found!]
>     EEPROM: Data valid
>     Restore Configuration from EEPROM to Device...
>     Show MY MAC Address(from 24c16): (0x00:92:58:01:45:4d)
>     _24c16_eeprom_word_read: EE_DHCPEN: (01)
> --- end snip ---

In addition, available cores include options to suppress EEPROM erase in programming, this is fuseable.
In ancient times AVRDUDE would write flash counts to the four bytes terminated by E2END. (the -y option).
You need to include the header.  You can check, peek and poke, the contents with a sketch or by using avrdude in terminal mode (-t) with "dump ee".
And yes, it is normal for Arduino work to have a dedicated temporary sketch to load EEPROM data.
So SRAM (or FLASH) does not matter, there is a lot of FLASH compared to EEPROM.
Keep it simple and test your results. Depending upon the library or core, it is best to avoid crossing page boundaries as addressing may wrap around to the beginning of the page due to 6 bit truncation as for I2C external EEPROM. Don't trust, verify.

Is that boot time write intended to be for planned obsolescence or just bad coding practice.  If you want to check for the function of storage you could leave a couple byte signature that you read out instead of stressing the EEPROM (internal or external) with regular pointless writes.

It was bad coding. I think it was just left in the script from development. Netgear if it helps.


text:
I2C multi sensors reading on Arduino
I have several sensors (Grove multichannel gas sensor, Air Pressure Sensor MPX4115A, Temperature and Humidity Sensor DHT11) where most of them uses I2C communication.
I wonder if it is possible to read all of them using the I2C communication on a single Arduino board?

It is possible to use multiple I²C devices, all is needed is for each one to have a different address and the ability to set up the wiring(the other answer points to wriring info).
Of the sensors you listed only one is an I2C device(Grove sensor).
The DHT11 uses a single digital wire to communicate and the air pressure sensor is an analog device. Although you do mention having several devices, the only thing you need to be sure of is if there are no address conflicts, i.e. there being two devices with the same address on the I²C bus.
If address conflicts are an issue most devices provide a way of changing that address, often there are solder jumpers on the board. This allows you to change a devices address to a unique one.

Should be easy enough.  Do you already know how to connect and communicate with one I2C device?  If so, connecting multiple should be simply a case of connecting them in parallel.
If you don't know how to communicate with a single I2C device, then...
For the Arduino software you can use Wire to talk to devices over I2C.
For the hardware, connect the I2C clock and data lines from the Arduino to the I2C devices.  More on that here.