body:
This may be an easy question, and if so im sorry, but i couldn't find out how to do this. I've programmed in python before and hoped that this would work, but it don't.

    int myArray1[] = {0, 2, 4, 5, 7, 9, 11};
    int myArray2[] = {0, 2, 3, 5, 7, 8, 10};
    int myArray3[] = {0, 3, 5, 6, 7, 10};

    int newArray[] = myArray2;

I wanted to only have to change one place in my code, which of the first three arrays i want my new array to take values from. Do anyone have any suggestions on how to do this?

title: Copy content of array

Answers: 1

body:
Make `newArray` be a pointer to whichever array you wish to work with.  For example:

    int myArray1[] = {0, 2, 4, 5, 7, 9, 11};
    int myArray2[] = {0, 2, 3, 5, 7, 8, 10};
    int myArray3[] = {0, 3, 5, 6, 7, 10};

    int *newArray = myArray2;

    // ... work with selected array, via newArray[] subscripting

Note, you may need to set an array-length variable at the same time as choosing the array.

For example:

    int *newArray = myArray2;
    int newSize = sizeof(myArray2)/sizeof myArray2[0];

    // ... work with selected array

    newArray = myArray3;
    newSize = sizeof(myArray3)/sizeof myArray3[0];
    // ... work with selected array

 Alternately, add an array-end marker at the end of each array (eg, a negative number), or more elegantly, make all the arrays the same length.

If you want to make a new copy of the original array, such that modifying the new array won't change the old, use (eg) `memcpy()`.  For example:

    int newArray[7];
    ...
    memcpy(newArray, myArray2, sizeof(myArray2));

Note that `memcpy()`'s size argument is given in bytes.  Also, if you need to declare `memcpy()` [I don't recall whether it's automatically declared in the Arduino environment], add `#include <string.h>` up front.


body: According to datasheet of MCP3021 A/D converter (Microchip, page 16) the MCP3021 can be accessed by proper address bits in control byte. In case of MCP3021 *5AT* the address is 101, in case of MCP3021 *4AT* the address is 100. Does than mean that to interface two MCP3021 diveces in one circuit one have to purchase two devices with *different* serial number, e.g. MCP3021 *5AT* and *4AT*?

title: Communication over I2C protocol with more than one A/D device

Answers: 1

body:
Yes, you need different devices for different addresses. Up to 8 addresses are possible:

> The first part
of the control byte consists of a 4-bit device code, which
is set to 1001 for the MCP3021. The device code is fol-
lowed by three address bits: A2, A1 and A0. The default
address bits are 101 (contact the Microchip factory for
additional address bit options).The address bits allow
up to eight MCP3021 devices on the same bus and are
used to determine which device is accessed

The number after the A in the part number indicates the address:

[![enter image description here][1]][1]

Off the shelf you get address 5. If you want other addresses you have to order them specially from Microchip.

The device sacrifices flexibility in favour of size. If you want multiple devices on the same bus and not have to order different parts specially then you generally end up with a bigger chip with more pins to allow you to manually configure the sub-address.

  [1]: https://i.stack.imgur.com/D1MIO.png


body:
I am unable to initialize a W5100 module using an Arduino Pro Mini. I try setting the MAC and IP addresses but read invalid values thereafter.

Here is the Arduino program along with the output:

    void setup() {
        uint8_t mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
        uint8_t local_ip[] = {192, 168, 1, 100};
        Ethernet.begin(mac, local_ip);
        printMacAddress(); // OUTPUT: FF:FF:FF:FF:FF:FF
        printIpAddress(); // OUTPUT: 255.255.255.255
    }

    void printMacAddress() {
        uint8_t mac[6];
        W5100.getMACAddress(mac);
        Serial.print(mac[0], HEX); Serial.print(":"); Serial.print(mac[1], HEX); Serial.print(":");
        Serial.print(mac[2], HEX); Serial.print(":"); Serial.print(mac[3], HEX); Serial.print(":");
        Serial.print(mac[4], HEX); Serial.print(":"); Serial.print(mac[5], HEX); Serial.println();
    }

    void printIpAddress() {
        IPAddress ip = Ethernet.localIP();
        Serial.println(ip);
    }

I read in some blog posts that the Arduino may initialize before the W5100 initialization is completed so others recommend manually resetting the W5100 after Arduino initialization.
So I connected the W5100 reset pin to the Arduino digital output 4 and reset the W5100 during setup using the following code.

    const int W5100_RESET_PIN = 4;
    pinMode(W5100_RESET_PIN, OUTPUT);
    digitalWrite(W5100_RESET_PIN, LOW); // Activate reset pin by asserting low
    delay(5); // Wait for 5 msec
    digitalWrite(W5100_RESET_PIN, HIGH); // Deactivate reset pin by asserting high
    delay(300); // Wait for W5100 to initialize[/code]

I observed the W5100 resetting because the module LEDs flashed off and back on each time I manually reset the Arduino. However this does not fix the W5100 mac/IP initialization issue.

**How should I troubleshoot this issue?**

Here are pictures of the assembly.
https://i.stack.imgur.com/cjnHE.jpg

Here is an overview of the W5100 module.
http://arduino-info.wikispaces.com/Ethernet

title: Unable to initialize W5100 using Arduino Pro Mini

Answers: 1

body:
<!-- language-all: lang-C++ -->

One of the Ethernet examples shows you should test the result of the `begin` function call, like this:

    // start the Ethernet connection:
      if (Ethernet.begin(mac) == 0) {
        Serial.println("Failed to configure Ethernet using DHCP");
        // try to congifure using IP address instead of DHCP:
        Ethernet.begin(mac, ip);
      }

Try displaying the return value from `begin` to see if that initialization succeeded.


body:
Adafruit carries a number of Bluetooth LE 4.0 modules in their store, notably the SPI (https://www.adafruit.com/products/2633) and UART (https://www.adafruit.com/product/2479) version. I have used the NRF24L01 module with ATtiny85 via SPI to transmit data in the past, and this uses 3 pins. I used the following setup to do so: https://www.hackster.io/arjun/nrf24l01-with-attiny85-3-pins-74a1f2.

My previous system consisted of ATtiny85s communicating with a receiver (Bluefruit Feather) via NRF24L01 radios. As the receiver got data, it sent it to an iPhone app that I wrote. Now, I would like to cut out this receiver and BLE straight to the iPhone, which supports multiple peripheral connections.

However, unlike the RF24 library, the Adafruit BLE SPI library needs the actual SPI library to compile correctly, which for some reason the RF24 library (this version: http://tmrh20.github.io/RF24/) doesn't. I don't quite get how the RF24 library can compile fine without the SPI library when targeting the ATtiny85 - Is there some way to get this to work similar to the RF24 library?

Alternatively, I think there is a way to do software UART on ATtiny85, which I know nothing about, so if there truly is no way to do SPI is UART possible?

I realize that this is a question best asked to Adafruit, which I have done, but I thought I'd post it here and see if anyone can help.

Thanks,
Alex

title: BLE SPI Module with ATtiny85

Answers: 1

body:
I find the ATTiny85 working well with software serial port. Serial UART (or in fact any of the protocols like I2C or SPI) are just bit banging - and you can do that pretty well in software. Of course, having a hardware support makes things easier and faster, but there is nothing badly wrong with a software uart either. Except that you have to continuously check if there is some data arrives.

I was using software serial on Adafruit Trinket (ATTiny85) in various projects to talk to a Bluetooth 2.1 module, and it worked pretty well.

Here
http://arduining.com/category/trinket-projects/ they use the same approach to talk to an ESP8266.

You may wish to look for the SoftwareSerial lib for Trinket, or in certain cases you may want to go for the SendOnlySoftwareSerial lib (send only, but smaller code footprint).

Also a hardware based serial lib is available:
https://blog.adafruit.com/2013/09/30/hardware-serial-library-for-the-trinket/


body:
With reference to the Arduino Uno, Mega2560, Leonardo and similar boards:

* How does serial communications work?
* How fast is serial?
* How do I connect between a sender and receiver?

*Please note: This is intended as a reference question.*

title: How does serial communications work on the Arduino?

Answers: 1

body:
Asynchronous serial (usually referred to as serial) communications is used to send bytes from one device to another. A device could be one or more of the following:

* Arduino
* PC
* GPS
* RFID card reader
* LCD display
* Modem
* Other

---

## Clock rate and sampling of data

Unlike SPI / USB / I2C serial communications does not have a clock signal. The sampling clock is an agreed-upon sample rate (known as the baud rate). Both sender and receiver must be configured to be using the same rate or the receiver will receive meaningless data (due to the bits not being sampled at the same rate that they were sent).

The transmission is [asynchronous](https://en.wikipedia.org/wiki/Asynchronous_communication) which basically means that bytes can be sent at any time, with varying gaps between them. This graphic illustrates a single byte being sent:

[![Serial comms - sending one byte][1]][1]

The graphic above shows the letter 'F' being transmitted. In ASCII this is 0x46 (in hex) or 0b01000110 (in binary). The *least* significant (low-order) bit is transmitted first, thus in the above graphic you see the bits arriving in the order: `01100010`.

The "idle" time between bytes is transmitted as continuous "1" bits (effectively, the transmit line is held high continuously).

To indicate the start of a byte, the *Start Bit* is always indicated by pulling the line low as shown on the graphic. Once the receiver sees the start bit, it waits for 1.5 times the sample time, and then samples the data bits. It waits 1.5 times so that it:

* Skips the start bit
* Samples half-way through the next bit

If the baud rate is 9600 baud, for example, then the sample rate will be `1/9600 = 0.00010416` seconds (104.16 µs).

Thus, at 9600 baud, after receiving a start bit the receiver waits for 156.25 µs, and then samples every 104.16 µs.

[![Start bit timing][2]][2]

The purpose of the *Stop Bit* is to ensure that there definitely is a 1-bit between each byte. Without the stop bit, if a byte ended in a zero, then it would be impossible for the hardware to tell the difference between that and the start bit of the next byte.

To produce the above output on an Uno you could write this code:

<!-- language-all: lang-C++ -->

    void setup()
      {
          Serial.begin(9600);
          Serial.print("F");
      }

    void loop ()
      {
      }

---

## Number of data bits

In order to save transmission time (in the olden days, heh) you were allowed to specify different numbers of data bits. The AtMega hardware supports data bits numbering from 5 to 9. Clearly the less data bits the less information you can send, but the faster it will be.

---

## Parity bits

You can optionally have a parity bit. This is calculated, if required, by counting the number of 1's in the character, and then making sure that this number is odd or even by setting the parity bit to 0 or 1 as required.

For example, for the letter "F" (or 0x46 or 0b01000110) you can see that there are 3 ones there (in 01000110). Thus we already have odd parity. So, the parity bit would be as follows:

* No parity: omitted
* Even parity: a 1 (3 + 1 is even)
* Odd parity: a 0 (3 + 0 is odd)

The parity bit, if present, appears after the last data bit but before the stop bit.

If the receiver does not get the correct parity bit, that is called a "parity error". It indicates that there is some problem. Possibly the sender and receiver are configured to use different baud (bit) rates, or there was noise on the line which turned a zero to a one or vice-versa.

Some early systems also used "mark" parity (where the parity bit was always 1 regardless of the data), or "space" parity (where the parity bit was always 0 regardless of the data).

---

## 9-bit transmission

Some communication equipment uses 9-bit data, so in these cases the parity bit is turned into the 9th bit. There are special techniques for sending this 9th bit (the registers are 8-bit registers so the 9th bit has to be put somewhere else).

---

## Number of stop bits

Early equipment tended to be somewhat slower electronically, so to give the receiver time to process the incoming byte, it was sometimes specified that the sender would send two stop bits. This basically adds more time where the data line is held high (one more bit time) before the next start bit can appear. This extra bit time gives the receiver time to process the last incoming byte.

If the receiver does not get a logical 1 when the stop bit is supposed to be, that is called a "framing error". It indicates that there is some problem. Quite possibly the sender and receiver are configured to use different baud (bit) rates.

---

## Notation

Commonly, serial communication is indicated by telling you the speed, number of data bits, type of parity, and number of stop bits, like this:

    9600/8-N-1

This is telling us:

* 9600 bits per second
* 8 data bits
* No parity (you might see instead: E=even, O=odd)
* 1 stop bit

It is important that the sender and receiver agree on the above, otherwise communication is unlikely to be successful.

---

## Pin-outs

The Arduino Uno has digital pins 0 and 1 available for hardware serial:

[![Arduino Uno serial pins][3]][3]

To connect two Arduinos you *swap* Tx and Rx like this:

[![Connecting two Arduinos together][4]][4]

---

## Speed

A wide range of speeds is supported (see graphic below). "Standard" speeds are usually a multiple of 300 baud (eg. 300/600/1200/2400 etc.).

Other "non-standard" speeds can be handled by setting the appropriate registers. The HardwareSerial class does this for you. eg.

    Serial.begin (115200);  // set speed to 115200 baud

As a rule-of-thumb, assuming you are using 8-bit data, then you can estimate the number of bytes you can transmit per second by dividing the baud rate by 10 (because of the start bit and stop bit).

Thus, at 9600 baud you can transmit 960 bytes (`9600 / 10 = 960`) per second.

---

## Baud rate errors

The baud rate on the Atmega is generated by dividing down the system clock, and then counting up to a pre-set number. This table from the datasheet shows the register values, and error percentages, for a 16 MHz clock (such as the one on the Arduino Uno).

[![Baud rate errors][5]][5]

The U2Xn bit affects the clock rate divisor (0 = divide by 16, 1 = divide by 8). The UBRRn register contains the number the processor counts up to.

So from the table above, we see that we get 9600 baud from a 16 MHz clock as follows:

    16000000 / 16 / 104 = 9615

We divide by 104 and not 103 because the counter is zero-relative. Thus the error here is `15 / 9600 = 0.0016` which is close to what the table above says (0.02%).

You will notice that some baud rates have a higher error amount than others.

According to the datasheet the maximum error percentage for 8 data bits is in the range of 1.5% to 2.0% (see the datasheet for more details).

---

## Arduino Leonardo

The Arduino Leonardo and Micro have a different approach to serial communications, as they connect directly via USB to the host computer, not via the serial port.

Because of this, you must wait for Serial to become "ready" (as the software establishes an USB connection), with an extra couple of lines, like this:

    void setup()
      {
          Serial.begin(115200);
          while (!Serial)
          {}  // wait for Serial comms to become ready
          Serial.print("Fab");
      }

    void loop ()
      {
      }

However, if you want to actually communicate via pins D0 and D1, (rather than by the USB cable) then you need to use Serial1 rather than Serial. You do so like this:

    void setup()
      {
          Serial1.begin(115200);
          Serial1.print("Fab");
      }

    void loop ()
      {
      }

---

## Voltage levels

Note that the Arduino uses TTL levels for serial communications. This means that it expects:

* A "zero" bit is 0V
* A "one" bit is +5V

Older serial equipment designed to plug into a PC's serial port probably uses RS232 voltage levels, namely:

* A "zero" bit is +3 to +15 volts
* A "one" bit is −3 to −15 volts

Not only is this "inverted" with respect to TTL levels (a "one" is more negative than a "zero"), the Arduino cannot handle negative voltages on its input pins (nor positive ones greater than 5V).

Thus you need an interface circuit for communicating with such devices. For input (to the Arduino) only, a simple transistor, diode, and a couple of resistors will do it:

[![Inverting buffer][6]][6]

For two-way communication you need to be able to generate negative voltages, so a more complex circuit is required. For example the MAX232 chip will do that, in conjunction with four 1 µF capacitors to act as charge-pump circuits.

---

## Software Serial

There is a library called SoftwareSerial that lets you do serial communications (up to a point) in software rather than hardware. This has the advantage that you can use different pin configurations for serial communications. The disadvantage is that doing serial in software is more processor-intensive and more prone to error. See [Software Serial](https://www.arduino.cc/en/Reference/SoftwareSerial) for more details.

---

## Mega2560

The Arduino "Mega" has 3 additional hardware serial ports. They are marked on the board as Tx1/Rx1, Tx2/Rx2, Tx3/Rx3. They should be used in preference to SoftwareSerial if possible. To open those other ports you use the names Serial1, Serial2, Serial3, like this:

    Serial1.begin (115200);  // start hardware serial port Tx1/Rx1
    Serial2.begin (115200);  // start hardware serial port Tx2/Rx2
    Serial3.begin (115200);  // start hardware serial port Tx3/Rx3

---

## Interrupts

Both sending and receiving, using the HardwareSerial library, use interrupts.

### Sending

When you do a `Serial.print`, the data you are trying to print is placed in an internal "transmit" buffer. If you have 1024 bytes or more of RAM (such as on the Uno) you get a 64-byte buffer, otherwise you get a 16-byte buffer. If the buffer has room, then the `Serial.print` returns immediately, thus not delaying your code. If there is no room, then it "blocks" waiting for the buffer to be emptied enough for there to be room.

Then, as each byte is transmitted by the hardware an interrupt is called (the "USART, Data Register Empty" interrupt) and the interrupt routine sends the next byte from the buffer out of the serial port.

### Receiving

As incoming data is received an interrupt routine is called (the "USART Rx Complete" interrupt) and the incoming byte is placed into a "receive" buffer (the same size as the transmit buffer mentioned above).

When you call `Serial.available` you find out how many bytes are available in that "receive" buffer. When you call `Serial.read` a byte is removed from the receive buffer and returned to your code.

On Arduinos with 1000 bytes or more of RAM, there is no rush to remove data from the receive buffer, provided you don't let it fill up. If it fills up then any further incoming data is discarded.

Note that because of the size of this buffer there is no point in waiting for a very large number of bytes to arrive, for example:

    while (Serial.available () < 200)
      { }  // wait for 200 bytes to arrive

This will never work because the buffer cannot hold that much.

---

## Tips

* Before reading, always make sure data is available. For example, this is wrong:

        if (Serial.available ())
          {
              char a = Serial.read ();
              char b = Serial.read ();  // may not be available
          }

    The `Serial.available` test only ensures you have *one* byte available, however the code tries to read two. It may work, if there are two bytes in the buffer, if not you will get -1 returned which will look like 'ÿ' if printed.

* Be aware of how long it takes to send data. As mentioned above, at 9600 baud you an only transmit 960 bytes per second, so trying to send 1000 readings from an analog port, at 9600 baud, won't be very successful.

---

## References

* [Async (Serial) peripheral interface - for Arduino](http://www.gammon.com.au/forum/?id=10894)
* [How to process incoming serial data without blocking](http://www.gammon.com.au/serial)
* [RS-232 - Wikipedia](http://en.wikipedia.org/wiki/RS-232)
* [Arduino Reference - Serial](http://arduino.cc/en/Reference/Serial)

  [1]: https://i.stack.imgur.com/LcurN.png
  [2]: https://i.stack.imgur.com/SoFKx.png
  [3]: https://i.stack.imgur.com/eFevW.png
  [4]: https://i.stack.imgur.com/QJO4F.png
  [5]: https://i.stack.imgur.com/Dlzee.png
  [6]: https://i.stack.imgur.com/8WUMU.png


body:
I am developing an educational product that I would like to mass produce. I am not sure of the quantity yet, but I imagine we will make a few hundred PCBs at least to begin

I spoke with an electrical engineering about how to take an Arduino prototype to mass production, and he warned me that the code written in the Arduino IDE cannot be fused onto the processor. (He used the term "fuse", although I don't see this elsewhere in the forum. is this the right term?)

He said that I would probably have to take each product, and load the Arduino code on manually, plugging in each one to a computer and upload like one would when prototyping. Also, he said the other option would be to recode my Arduino sketch from scratch using an AVR code.

Can someone shed some light on this for me? How can I take Arduino prototyping code and use it in mass production?

title: Take an Arduino or Teensy prototype to Mass production - Loading software onto microcontroller

Answers: 3

body:
Arduino code and AVR code is essentially the same, at least once compiled it is. The only real difference is the existence of the bootloader, and that is not essential.

For quantities of a hundred or so it is probably most cost effective to manually program them via an ISP connector to the board. For larger quantities Atmel provide a mass programming service to pre-program the chips, but that costs money so the more you have done at once the cheaper it is per chip. I am not sure on Atmel's procedure off hand but others I have used just take either a .elf or .hex file which the Arduino IDE is perfectly capable of producing.

Either way you should design in an ISP connector on your board so the firmware can be upgraded in the future if needed.

body:
Arduino code **is** AVR code. There's no real difference. The only thing is that Arduino's tend to use bootloaders, which might cause a problem. But in your case I'd advice to not use a bootloader anyways.

Since you plan to build a lot of them, you probably want to use bare ATMega chips, and not arduino boards. Bare chips don't have a bootloader to begin with.

You'd program the boards using ISP.

body:
> I spoke with an electrical engineering about how to take an Arduino prototype to mass production, and he warned me that the code written in the Arduino IDE cannot be fused onto the processor.

That's nonsense. The output from the IDE compiler is a .hex file which is then sent via `avrdude` to program the board. If the output cannot be "fused" onto the processor how does he imagine we ever get anything done?

Possibly he is referring to changing the fuses to make it impossible to read the code back from the chip. This can be easily accomplished.

---

> He said that I would probably have to take each product, and load the Arduino code on manually, plugging in each one to a computer and upload like one would when prototyping.

You have obviously spoken to someone with no experience in Arduinos, possibly one of those engineers with an active dislike of it.

I have written code to run on an Arduino to upload sketches to another board.

You can read about it at [Atmega chip stand-alone programmer to upload .hex files](http://www.gammon.com.au/uploader). The idea is you take your .hex file, put it onto an SD card and then program your target board in a few seconds.

User "Crossroads" from the Arduino forum has taken that idea and made a [stand-alone board](http://crossroadsfencing.com/BobuinoRev17/index.html), looking like this:

[![Hex programmer][1]][1]

You put up to 255 hex files onto the SD card. You dial-up which one you want with the rotary dial. You plug in the ICSP cable into your target board, and hit the "program" button. The whole thing takes a few seconds.

It is designed to be used "in the field". All you have to do is plug in a power-pack to supply power to it.

If you needed to protect the target boards with a fuse setting after uploading, you would modify the code in the programmer slightly to do that for you.

It would be helpful to have an ICSP header on your target boards, both for programming before deployment, and in case you find a bug and have to change it.

Failing that you might put the chips into a suitable board first (eg. with a ZIF socket), program them off-board, and then solder them on. There are lots of options for you.

---

> Also, he said the other option would be to recode my Arduino sketch from scratch using an AVR code.

I don't see why that would be necessary, in any way.

  [1]: https://i.stack.imgur.com/OQAQM.jpg


body: I am trying to write a sketch where a function will only be triggered when the ultrasound doesn't return back. Thus when the echo pin is checked after 1 second after the trigger pin was written high, it must be low. Will it be a digitalRead function?

title: What if Ultrasonic sensor doesn't detect object?

Answers: 1

body:
What type of Ultrasonic sensor do you have?

I'll go with HC-SR04, since I've got one of those laying around here. The other ultrasonic sensors should be working in the same way.

**Before you start!**

Read the datasheet. A fast search on google with: "[manufacturer][device id][device description] datasheet .pdf" will do good.

Example: http://www.micropik.com/PDF/HCSR04.pdf

The datasheet will tell you important things/values and sometimes even interfacing examples or code.
Like:

 - Max input voltage
 - Max current
 - Pin-out diagrams
 - How to interface with the device
 - Min/max operating temperature

**Wiring up**

The datasheet will tell you what to connect, to which pins.

We've got 5V, Trigger (input), Echo (output), 0V (ground).

(As per datasheet)

It's best to do the wiring before you put power on it, because you can accidently short it when moving wires around.

**Interfacing**

I would recommend checking some code examples before you attempt to roll your own. Or just start from an example and edit it to your specifications.

The timing diagram shows us it needs a 10uS pulse on the trigger input.
And the duration of the echo will show the distance (58 uS per cm or 148 uS per inch).

The datasheet also suggest to use over 60ms measurement cycles.

**Code**

Taking all that into account:

    #define trigPin 13
    #define echoPin 12
    #define led 11
    #define led2 10

    const unsigned long timeout = 400*58; //Max of 400CM, adjust this to your own max.

    void setup() {
      Serial.begin(115200);//Stop using 9600 as default, it's not fast.
      pinMode(trigPin, OUTPUT);
      pinMode(echoPin, INPUT);
      pinMode(led, OUTPUT);
      pinMode(led2, OUTPUT);
    }

    void loop() {
      unsigned long distance;//unsigned, since we don't get negative distances.
      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10); //10 uS pulse.
      digitalWrite(trigPin, LOW);

      distance = round(pulseIn(echoPin, HIGH,timeout) /58);//Distance in CM's, use /148 for inches.
      if (distance == 0){//Reached timeout
        Serial.println("Out of range");
      }
      else {
        Serial.print(distance);
        Serial.println(" cm");
      }
      delay(60);//Wait 60 ms for next cycle.
    }

To be honest, I'm not even slightly sure if this code is working.
I modified this code: http://www.instructables.com/id/Simple-Arduino-and-HC-SR04-Example/

So that you're actually using the timeout right, and do the timing according to the datasheet.


body:
Only 2 arduinos can normally be linked via serial port because TX and RX need to be cross-linked, and connecting multiple TXs together would cause conflict.

RS485 allows multiple nodes connected in parallel on a 2 wire differential 'bus', using a TX ENABLE pin to allow one master to transmit while all other slaves listen.

I suspect it should be possible to similarly connect multiple serial RXs together to give a common listening bus, and be able to use TX ENABLE on any one node at a time to transpose its RX and TX to allow its TX to transmit to the other RXs. This might be physically done using a changeover relay swapping RX with TX, but is it possible to somehow temporarily switch the TX and RX assignments on demand by software?

I doubt the actual pin assignments can be changed in-situ, but perhaps the same results are achievable with some programming wizards sleight-of-hand trickery?

title: Can RX and TX be temporarily transposed on demand?

Answers: 2

body:
It sounds to me like you are misunderstanding the purpose of the TX Enable pin and you are trying to come up with some convoluted method to do exactly what TX Enable actually does.

Under normal circumstances, in RS485, the UART's RX pin is connected to the bus.  When TX Enable is asserted the RX pin is disconnected and the TX pin is connected, thus allowing any node on the bus to be a transmitter and all the other nodes a receiver.

The main thing to watch out for though is that only one node is ever a transmitter at a time, otherwise you get a *collision* which means that the data is completely garbled.

The simplest way of stopping that happening is to have one node nominated as the *master* and all the other nodes as *slaves*.  The *master* first initiates communication by making a request to a *slave*.  The *slave* will then respond with data (it becomes the transmitter and the *master* a receiver) to send data to the master.  That way the only node that is a transmitter is either the *master* making the request, or the *slave* that is responding to a request.

If you want "random" peer-to-peer communication where any node could become a transmitter at any time it becomes a whole lot more complex.  There are things you should implement to try to avoid, or deal with, collisions, including monitoring the bus and only transmitting after a certain amount of idle time has been detected, reading the bus while writing to it (requires more hardware) and confirming that the data you read from the bus is the same as the data you wrote to the bus, and random delays before retrying a failed communication.  That last one is probably the trickiest to get right, since random numbers on Arduinos aren't really random unless you "seed" them from a truly random source. You don't want both ends delaying for the same amount of time to retry otherwise it will never complete.

----

Since you apparently want to achieve that kind of thing but *without* using RS485, it all gets much more complex.

No, you cannot "swap" the functionality of the TX and RX pins in the Arduino.  **BUT** you can do serial communication (albeit somewhat heavyweight) using pure software.  Take a look at the SoftwareSerial library - you will most likely need to make modifications to that to achieve what you want.

To do it externally with hardware is possible, but the end result will most likely be more complex than just using a simple RS485 interface chip which are very inexpensive and easy to get hold of.

Yes, you could use relays (*clunky*) or buffers, or multiplexers, etc, but why would you when RS485 does what you want?

body:
On an AVR-based Arduino, you can selectively enable the transmitter and
receiver side of the UART (c.f. the datasheet of your MCU). Thus, you
could in principle just connect all the TX and RX together, and make
sure only one transmitter is enabled at a time, while all the others are
in high impedance. If you do this, I would strongly recommend you put a
current-limiting resistor in series with each TX, just in case.

For example, on an Arduino Uno
([Atmega328P](http://www.atmel.com/images/Atmel-8271-8-bit-AVR-Microcontroller-ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet_Complete.pdf)),
you can use the following functions:

<!-- language: lang-cpp -->

    static inline void enable_tx()  { UCSR0B |=  _BV(TXEN0); }
    static inline void disable_tx() { UCSR0B &= ~_BV(TXEN0); }
    static inline void enable_rx()  { UCSR0B |=  _BV(RXEN0); }
    static inline void disable_rx() { UCSR0B &= ~_BV(RXEN0); }

**Edit**: Beware that `Serial.begin()` enables both the transmitter and
the receiver.


body:
One of the FastLED examples that I've seen was using code that looks like this:

>   EVERY_N_MILLISECONDS( 300 ) { transition_step(); }

I've copied it and successfully used it in the same context - but I have no idea what it is or how it works.

A Google search finds no reference anywhere at all.

I'm still a beginner with C but this looks like a Define to me - all being in uppercase - is it defined somewhere in the FastLED library?

title: "EVERY_N_MILLISECONDS"

Answers: 3

body:
Yes, it is defined in the FastLED library.  It is a *preprocessor macro* which is replaced by a block of code when compiled:

It is a very convoluted bit of preprocessing code that is difficult (even for me) to follow through with lots of concatenations and multiple layers of definition, so my advice is to just not worry about it and just use it.

If you want to try and decypher it all it's in the file `lib8tion.h` in the FastLED library.

body:
As @Majenko has said it is defined in the FastLED library http://fastled.io/.  There is also EVERY_N_SECONDS.

It is not necessary to call any other FastLed function in the run loop (such as FastLED.delay()) in order to use these functions.

    include <FastLED.h>

    void loop() {
       ....
       EVERY_N_MILLISECONDS( <mseconds> ) {
         <your timed code here>;
       }

       EVERY_N_SECONDS( <seconds> ) {
         <your timed code here>;
       }
    }

body:
Its a macro that wraps the code you put inside of it to only be run based on the time interval you pass to it. The purpose of it is to allow for timer based code to be ran without having to block the main `loop()`. When the code is compiled it gets wrapped by other code that governs how the code inside it should run.

Lets say you want to run a method every 100ms. A simple approach would be the following:

``` c
// loop() runs the code within it over and over at a rate based on the
// how fast the microprocessor runs - specifically how long it takes
// for the processor to get through the code inside of it.
void loop(){

doMethod();
delay(100);

checkForButtonInput();

}
```

The issue here is that during the `delay()`, the `delay()` function, by its design, hogs all the processor time for 100ms, and so the `checkForButtonInput()` is not able to check for input, as the program is currently stuck looping inside of `delay()` until 100ms has passed.

`EVERY_N_MILLISECONDS( <mseconds> ){}` is the answer here, and you can think of it working to add code to you code like this (although this isn't exactly accurate):
``` c
void loop() {
   EVERY_N_MILLISECONDS( 100 ){
  //pseudocode
  //if ( it has been 100ms since last time we did doMethod() ) {
      doMethod();
      // reset time since we did doMethod() to 0
  //}
  //else {
  //  continue...
  //}
  }
  checkForButtonInput();
}
```
so if it hasn't been 100ms since the last time we were in the `EVERY_N_MILLISECONDS` wrapped code then we just move on, and so the `checkForButtonInput()` is called as much as possible and inputs wont be missed.


body:
I am trying to learn how to use a shift register to control 8 LEDs but for some reason my shift register is misbehaving and none of the LEDs are lighting up. I imagine that it's a problem with my wiring? I have replicated the circuit on 123D Circuits.

[![circuit diagram][1]][1]

  [1]: https://i.stack.imgur.com/UJOA9.png

    //Pin connected to ST_CP of 74HC595
    int latchPin = 8;
    //Pin connected to SH_CP of 74HC595
    int clockPin = 12;
    ////Pin connected to DS of 74HC595
    int dataPin = 11;

    void setup() {
      //set pins to output so you can control the shift register
      pinMode(latchPin, OUTPUT);
      pinMode(clockPin, OUTPUT);
      pinMode(dataPin, OUTPUT);
    }

    void loop() {
      // count from 0 to 255 and display the number
      // on the LEDs
      for (int numberToDisplay = 0; numberToDisplay < 256; numberToDisplay++) {
        // take the latchPin low so
        // the LEDs don't change while you're sending in bits:
        digitalWrite(latchPin, LOW);
        // shift out the bits:
        shiftOut(dataPin, clockPin, MSBFIRST, numberToDisplay);

        //take the latch pin high so the LEDs will light up:
        digitalWrite(latchPin, HIGH);
        // pause before next value:
        delay(500);
      }
    }

title: Shift Register Not Working

Answers: 1

body:
From the Arduino website:

> ## shiftOut() ##
>
> Description
>
> Shifts out a byte of data one bit at a time. [...]
>
> Note: if you're interfacing with a device that's clocked by rising
> edges, you'll need to make sure that the clock pin is low before the
> call to shiftOut(), e.g. with a call to digitalWrite(clockPin, LOW).

You need to pull `clockPin` low before each `shiftOut()` call, as the documentation says.

Also, you have misunderstood the behaviour of the `latchPin`. This can be high or low at any time; it's the *change from low to high* that latches the data into the output cells.


body:
I am trying to make a robot turn (dc motors are being used) back 180 degrees. So I used an l289n for it and made one wheel turn clockwise and vice-versa.

But as I wan't it to make only a 180 degrees turn, I wanted to set an amount of time for it to turn.  Is there any other way to do the same thing, if yes, please tell, if no, help me...

title: How to make two wheels turn only for a particular amount of time?

Answers: 1

body:
Use the [delay()](https://www.arduino.cc/en/Reference/Delay) function.

Pseudo code as follows:

    1) Turn clockwise motor on;
    2) Turn counterclockwise motor on;
    3) delay(<time>);
    4) Turn CW motor off;
    5) Turn CCW motor off.


body:
So I bought a Bluetooth Shield from SeeedStudio lately (V2 model) and goofed around with it a little bit. I'm using my HTC One M8 to communicate with it just to send some dummy words. Whenever I send something from my phone to the Android, it works great and I'm pleased to see it's fast too.

The code is fairly simple. I just send data from my phone, gets received to my arduino, prints it on the Arduino IDE terminal. Same thing for communication in the other way. Write something in the terminal, send it to the arduino and then, the phone. The last on doesn't work and I've tried a couple of things in the past 36 hours. Now, I'm just banging my head against the wall (literally). Here's my code (I'm sure you've seen it a couple of times before):

<!-- language: c -->

    #include <SoftwareSerial.h>   //Software Serial Port
    #define RxD 6
    #define TxD 7

    #define DEBUG_ENABLED  1

    SoftwareSerial blueToothSerial(RxD,TxD);

    void setup()
    {
      Serial.begin(9600);
      pinMode(RxD, INPUT);
      pinMode(TxD, OUTPUT);
      setupBlueToothConnection();

    }

    void loop()
    {
      char recvChar;
      while(1){
        if(blueToothSerial.available()){//check if there's any data sent from the remote bluetooth shield
          recvChar = blueToothSerial.read();
          Serial.print(recvChar);
        }
        if(Serial.available()){//check if there's any data sent from the local serial terminal, you can add the other applications here
          recvChar  = Serial.read();
          blueToothSerial.print(recvChar);
        }
      }
    }

    void setupBlueToothConnection()
    {
      blueToothSerial.begin(9600); //Set BluetoothBee BaudRate to default baud rate 38400
      blueToothSerial.print("\r\n+STWMOD=0\r\n"); //set the bluetooth work in slave mode
      blueToothSerial.print("\r\n+STNA=SeeedBTSlave\r\n"); //set the bluetooth name as "SeeedBTSlave"
      blueToothSerial.print("\r\n+STOAUT=1\r\n"); // Permit Paired device to connect me
      blueToothSerial.print("\r\n+STAUTO=0\r\n"); // Auto-connection should be forbidden here
      delay(2000); // This delay is required.
      blueToothSerial.print("\r\n+INQ=1\r\n"); //make the slave bluetooth inquirable
      Serial.println("The slave bluetooth is inquirable!");
      delay(2000); // This delay is required.
      blueToothSerial.flush();
    }

On my phone, I use a simple Bluetooth SSP to pair and communicate. Btw, something odd: I can't change the name of the bluetooth device. When I try to connect it, it shows the same name in the SSP.

Note: When I upload my code, I make sure I reset the arduino everytime. Oh and I changed the jumpers on my board to make sure it was set on the right one.

Note 2: I tried to see if the pins on the Shield (for RdX and TdX) were not starting with 0 by moving the jumpers.

Still, it's pretty odd.

Thanks in advance for any help and don't hesitate to ask me question! It's my first time here!

title: Send data from computer to phone through bluetooth - Bluetooth SeeedStudio Shield V2.1

Answers: 0


body:
My question is simple. Is the following possible?

I am using one Arduino Mega 2560 board and its SPI functionality to adjust voltages (0-4.096V) through a 12-bit DAC (MCP4822).

I would like to measure the output voltages from the DAC by feeding them through a 12-bit ADC and back to the Arduino. The DAC's output voltages that will be directly measured by the ADC will be displayed on an LCD and on LabVIEW.

Is this possible, given that both the DAC and the ADC have to be connected to the same SDI and SCK pins on the Arduino for SPI to work?

title: Arduino to DAC to ADC back to Arduino?

Answers: 1

body: Yes, perfectly possible. Just provide two separate CS pins to select between the two devices.


body:
New to Arduino, I plugged in DCMotorTest from the Adafruit site and got this error message: a fatal error exit status 1

    /*
    This is a test sketch for the Adafruit assembled Motor Shield for Arduino v2
    It won't work with v1.x motor shields! Only for the v2's with built in PWM
    control

    For use with the Adafruit Motor Shield v2
    ----> http://www.adafruit.com/products/1438
    */

    #include <Wire.h>
    #include <Adafruit_MotorShield.h>
    #include "utility/Adafruit_MS_PWMServoDriver.h"

    // Create the motor shield object with the default I2C address
    Adafruit_MotorShield AFMS = Adafruit_MotorShield();
    // Or, create it with a different I2C address (say for stacking)
    // Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61);

    // Select which 'port' M1, M2, M3 or M4. In this case, M1
    Adafruit_DCMotor *myMotor = AFMS.getMotor(1);
    // You can also make another motor on port M2
    //Adafruit_DCMotor *myOtherMotor = AFMS.getMotor(2);

    void setup() {
      Serial.begin(9600);           // set up Serial library at 9600 bps
      Serial.println("Adafruit Motorshield v2 - DC Motor test!");

      AFMS.begin();  // create with the default frequency 1.6KHz
      //AFMS.begin(1000);  // OR with a different frequency, say 1KHz

      // Set the speed to start, from 0 (off) to 255 (max speed)
      myMotor->setSpeed(150);
      myMotor->run(FORWARD);
      // turn on motor
      myMotor->run(RELEASE);
    }

    void loop() {
      uint8_t i;

      Serial.print("tick");

      myMotor->run(FORWARD);
      for (i=0; i<255; i++) {
        myMotor->setSpeed(i);
        delay(10);
      }
      for (i=255; i!=0; i--) {
        myMotor->setSpeed(i);
        delay(10);
      }

      Serial.print("tock");

      myMotor->run(BACKWARD);
      for (i=0; i<255; i++) {
        myMotor->setSpeed(i);
        delay(10);
      }
      for (i=255; i!=0; i--) {
        myMotor->setSpeed(i);
        delay(10);
      }

      Serial.print("tech");
      myMotor->run(RELEASE);
      delay(1000);
    }

_**My error message was:**_

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

    /Users/student/Downloads/Adafruit_Motor_Shield_V2_Library-master/examples/DCMotorTest/DCMotorTest.ino:11:34:
     fatal error: Adafruit_MotorShield.h: No such file or directory
     #include <Adafruit_MotorShield.h>
                                      ^
    compilation terminated.
    exit status 1
    Error compiling.

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

title: DCMotorTest from the Adafruit site – got fatal error exit status 1

Answers: 1

body:
Based on the error report it seems that you have just opened the example program from the downloaded folder. In order to add library files (which includes the header files, c++ source code, etc.) you have to move the *Adafruit_Motor_Shield_V2_Library-master* folder to the libraries folder.

> Documents > arduino > libraries

If no such folder exist, then create a new folder and name it *libraries*.

To check weather the libraries have been installed, open arduino IDE goto

> file > example and check weather the example programs are added (you will see "adafruit" in the list)

Now, restart the arduino IDE and things should get going.

**Note:**
Do not use "-" and do not include space while naming a folder, as the compiler may throw up error. Instead you are free to use "_","$". Name of a folder should always start with a letter.

For more detail visit https://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use/how-to-install-a-library


body:
Short version:
I have a program that connects my ESP8266 to WIFI so I can control a relay connected to it over the internet or a button. I also have a sensor for my door. This software works perfectly, if I add a light dependent resistor to it (which is connected correctly since I do get readings from it) and start reading data I lose my WIFI connection. Has anyone got any idea why this is happening?

Long version:

So I have this program running on my Esp8266
<!-- language-all: lang-cpp -->

    #include <ESP8266WiFi.h>

    IPAddress ip(192, 168, 0, 150);
    IPAddress gateway(192, 168, 0, 1);
    IPAddress subnet(255, 255, 255, 0);

    const char* ssid = "mySSID";
    const char* password = "myPSW";
    const char* host = "192.168.0.228";

    const int buttonPin = 0;
    const int relayPin =  4;
    const int doorPin = 5;
    const int ldrPin = A0;

    //int ldrState;
    //int serialCount = 0;
    //int ldrMin = 0;
    //int ldrMax = 1024;
    int buttonState = 0;
    int doorState = 0;
    byte Main_Light_State_Begin;
    bool Main_Light_State;
    bool doorNotified = false;
    bool button_action_taken = false;
    bool Main_Light_DBR = true;
    String HTTP_Get_Response;

    WiFiServer server(80);

    //Functions
    String HTTP_Get(char* Adress, String URL, bool Last_Line_Bool) {
      WiFiClient client;
      const int httpPort = 80;
      if (!client.connect(Adress, httpPort)) {
        Serial.println("connection failed");
        return "Failed";
      }

      Serial.print("Requesting URL: ");
      Serial.println(URL);
      Serial.println("at adress");
      Serial.println(Adress);
      client.print(String("GET ") + URL + " HTTP/1.1\r\n" +
                   "Host: " + Adress + "\r\n" +
                   "Connection: close\r\n\r\n");
      delay(10);

      String Response;
      String Last_Line;

      while (client.available()) {
        String line = client.readStringUntil('\r');
        Serial.print(line);
        Response = Response + line;
      }
      return Response;

      Serial.println();
      Serial.println("closing connection");

    }

    void setup() {
      Serial.begin(115200);
      delay(1000);

      Serial.println();
      Serial.println();
      Serial.print("Connecting to ");
      Serial.println(ssid);

      WiFi.begin(ssid, password);
      WiFi.config(ip, gateway, subnet);

      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
      Serial.println("");
      Serial.println("WiFi connected");

      server.begin(); -
      Serial.println("Server started");

      Serial.println(WiFi.localIP());
      pinMode(relayPin, OUTPUT);
      pinMode(buttonPin, INPUT);
      pinMode(doorPin, INPUT);
    //  pinMode(ldrPin, INPUT);
    }

    void loop() {
      if (WiFi.status() != WL_CONNECTED) {
        Serial.println("Wifi NOT Connected");
      }
      //Sensors
      buttonState = digitalRead(buttonPin);
      doorState = digitalRead(doorPin);
      //ldrState = map(analogRead(ldrPin), ldrMin, ldrMax, 0, 100);
      //Serial.println(analogRead(ldrPin));
    //  if (serialCount == 1000) {
    //    Serial.println(ldrState);
    //    serialCount = 0;
    //  } else {
    //    serialCount ++;
    //  }

      //Doorsensor
      if (doorState == HIGH) {
        if (doorNotified == false) {
          Serial.println("DOOR");
          HTTP_Get_Response = HTTP_Get("192.168.0.228", "/index.php/?door_opened=true", false);
          doorNotified = true;
        }
      } else if (doorState == LOW) {
        if (doorNotified == true) {
          doorNotified = false;
          delay(500);
        }
        else {
          doorNotified = false;
        }
      }

      //Button
      if (buttonState == LOW) {
        if (button_action_taken == false) {
          if (Main_Light_State == true) {
            Serial.println("SWITCH");
            Main_Light_State = false;
            digitalWrite(relayPin, HIGH);
            delay(500);
            Main_Light_DBR = false;
          }
          else if (Main_Light_State == false) {
            Serial.println("SWITCH");
            Main_Light_State = true;
            digitalWrite(relayPin, LOW);
            delay(500);
            Main_Light_DBR = false;
          }
          button_action_taken = true;
        }
      } else if (buttonState == HIGH) {
        if (button_action_taken == true) {
          button_action_taken = false;
          delay(500);
        }
        else {
          button_action_taken = false;
        }

      }
      //Main_Light_State
      if (Main_Light_State == true) {
        digitalWrite(relayPin, LOW);
        if (Main_Light_DBR == false) {
          HTTP_Get_Response = HTTP_Get("192.168.0.228", "/index.php/?main_light_on_dbr=true", false);
          Main_Light_DBR = true;
        }

      } else if (Main_Light_State == false) {
        digitalWrite(relayPin, HIGH);
        if (Main_Light_DBR == false) {
          HTTP_Get_Response = HTTP_Get("192.168.0.228", "/index.php/?main_light_off_dbr=true", false);
          Main_Light_DBR = true;
        }
      }

      WiFiClient client = server.available();
      if (!client) {
        return;
      }

      Serial.println("new client");
      while (!client.available()) {
        delay(1);
      }

      String req = client.readStringUntil('\r');
      Serial.println(req);
      client.flush();

      if (req.indexOf("/main_light/on") != -1) {
        Main_Light_State = true;
        Main_Light_DBR = false;
      } else if (req.indexOf("/main_light/off") != -1) {
        Main_Light_State = false;
        Main_Light_DBR = false;
      } else if (req.indexOf("/main_light/switch") != -1) {
        Serial.println("SWITCH");
        if (Main_Light_State == true) {
          Main_Light_State = false;
        }
        else if (Main_Light_State == false) {
          Main_Light_State = true;
        }
        Main_Light_DBR = false;
      } else if (req.indexOf("/main_light/state") != -1) {

      } else {
        Serial.println("invalid request");
        client.stop();
        return;
      }

      client.flush();

      String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n";
      s += (Main_Light_State) ? "1" : "0";

      client.print(s);
      delay(1);
      Serial.println("Client disonnected");
    }

With the lines I commented like above everything works fine. I have a light dependant resistor connected (correctly, I get correct measurements from it) to A0. From the moment on I uncomment the lines involving this LDR and thus start reading data from it I lose my wifi connection. Has anyone got any idea why this is? Thank you!

title: ESP8266 Analog read interferes with wifi?

Answers: 3

body:
I have found that this was caused by reading the analog pin to many times in a short period of time. I replaced

      ldrState = map(analogRead(ldrPin), ldrMin, ldrMax, 0, 100);
      Serial.println(analogRead(ldrPin));
      if (serialCount == 1000) {
        Serial.println(ldrState);
        serialCount = 0;
      } else {
        serialCount ++;
      }
with this:

    if (serialCount == 10000) {
      ldrState = map(analogRead(ldrPin), ldrMin, ldrMax, 0, 100);
      Serial.println(ldrState);
      serialCount = 0;
    } else {
      serialCount ++;
    }

Although I thought of this approach before, my mistake was that I was still reading the sensor every time the code loops, I just wasn't printing it to the serial monitor until each 100th loop.

This still gives me a reading several times per second, which is way more then I need. Anyway, now I know that I can't read my ESP8266 Analog pin to many times per second or the wifi will disconnect (at least when using it with the Arduino IDE)

body:
This is an old question that has been answered, but I would like to offer a slightly more elegant solution (IMO!):

In my method which reads the analog data, I check and only read every 50 milliseconds:

    void readAnalogSensor() {
       if( millis() % 50 != 0 )
           return;
       .
       .  // Do your sensor read and processing here
       .
    }

This avoids having to keep a loop count and seems more deterministic - the loop count value will not necessarily increase in a consistent fashion depending on what else is going on in the loop.  Having the millis values available is also useful if you need to implement some button debounce code.

body:
Here is what I usually do to give repetition at fixed intervals:

    void readAnalogSensor(){
      if (millis()<taskTime) return; // time is not expired yet
      taskTime += 50; // set time for the following execution
      // .... more code for the task that is done every 50 ms
    }
This requires an `unsigned long variable taskTime`. You may also use a constant instead of the 50.
`taskTime` should be set to some value close to `millis()` at the end of `setup()`, otherwise there will be a rapid sequence of executions while `taskTime` catches up with `millis()`.


body:
I have a problem. I try to open a channel to arduino and PHP talk, the PHP would send a command and the Arduino should answer that. It works, but only if I execute some steps before:

 1.  sudo chmod 777 /dev/ttyACM0
 2.  sudo arduino
 3.  Open the serial monitor in arduino IDE
 4.  Close the serial monitor
 5.  Now everything is ok, they can talk

The first step is ok, I really need to do this, the 2-4 seems irrelevant, but the communication do not start without it. I put one LCD in arduino to print what he receive, when I send "HEYARD" with PHP to him, the RX led blinks and the TX led also, but nothing is printed on LCD. If I do the 2-4 steps, when PHP send "HEYARD", LCD show HEYARD and arduino answer with "HEYPHP"

Anyone could help? There is some way to open it via Terminal, or, at least, open the Serial Monitor from arduino and close to see if this start

title: Arduino and PHP communication only work if I open the Arduino IDE

Answers: 2

body:
Here the setup block:

    <?php
     require("php_serial.class.php");
     $serial = new phpSerial();
        $serial->deviceSet("/dev/ttyACM0");
     $serial->confBaudRate(9600);
     $serial->confParity("none");
     $serial->confCharacterLength(8);
     $serial->confStopBits(1);
     $serial->confFlowControl("none");
     $conect = mysql_connect("localhost", "root", "") or print (mysql_error());
     mysql_select_db("ANM", $conect) or print(mysql_error());
    ?>

And here the connection block:

    <?php
        $serial->deviceOpen();
        exec("echo 'HEYARD' > /dev/ttyACM0");
        sleep(1);
        $read = $serial->readPort();
    ?>

body:
stty -F /dev/ttyACM0 ignpar
stty -F /dev/ttyUSB0 ignpar

> IGNPAR Ignore framing errors and parity errors.

That is what you need to fix minor framing issues.

Screen switches this by default; but NONE of the serial drivers do.
Especially when connecting PIs or BBB to Arduinos


body:
I am communicating with two Arduinos with serial. The program works great for a while but then the serial monitor stops showing values in the RX code and will not work again unless the code is uploaded again. Why is this happening?

TX code:
<!-- language-all: lang-cpp -->

    /*
      Transmitting Code
      Reads potentiometers and sends them through serial
    */

    int data [12];     // to send bytes
    int start [2];

    int Pin1A = A0;
    int Joystick1A;  //crab

    int Pin1B = A1;
    int Joystick1B;  //up down

    int Pin2A = A2;
    int Joystick2A;   // pitch

    int Pin2B = A3;
    int Joystick2B;  // up down

    int Pin3A = A4;   // yaw r-l
    int Joystick3A;

    int Pin3B = A5;
    int Joystick3B;   // forward-back

    unsigned char checksum0;
    unsigned char checksum1;
    unsigned char checksum2;
    unsigned char checksum3;
    unsigned char checksum4;
    unsigned char checksum5;
    unsigned char handshake;
    unsigned char handshake2;
    unsigned char handshake3;

    void setup() {
      Serial.begin(4800);
      Serial1.begin(4800);
      pinMode(19, INPUT);
      pinMode(18, OUTPUT);
    }

    void loop() {

    // READ THE POTENTIOMETERS:

      Joystick1A = analogRead(Pin1A);   // reads the value of the potentiometer (Joystick1Aue between 0 and 1023)
      data[0] = Joystick1A & 0xFF; //least significant 8 bit byte
      data[1] = (Joystick1A >> 8); //most significant 2 bits

      Joystick1B = analogRead(Pin1B);
      data[2] = Joystick1B & 0xFF;
      data[3] = (Joystick1B >> 8);

      Joystick2A = analogRead(Pin2A);
      data[4] = Joystick2A & 0xFF;
      data[5] = (Joystick2A >> 8);

      Joystick2B = analogRead(Pin2B);   // reads the value of the potentiometer (Joystick1Aue between 0 and 1023)
      data[6] = Joystick2B & 0xFF; //least significant 8 bit byte
      data[7] = (Joystick2B >> 8); //most significant 2 bits

      Joystick3A = analogRead(Pin3A);
      data[8] = Joystick3A & 0xFF;
      data[9] = (Joystick3A >> 8);

      Joystick3B = analogRead(Pin3B);
      data[10] = Joystick3B & 0xFF;
      data[11] = (Joystick3B >> 8);

    // CREATE CHECKSUMS:

      checksum0 = ~(data[0]+data[1]) + 1;

      checksum1 = ~(data[2]+data[3]) + 1;

      checksum2 = ~(data[4]+data[5]) + 1;

      checksum3 = ~(data[6]+data[7]) + 1;

      checksum4 = ~(data[8]+data[9]) + 1;

      checksum5 = ~(data[10]+data[11]) + 1;
    // WRITE VALUES AND CHECKSUMS TO SERIAL:

    while (Serial1.available()<3) {
      ; //wait for request from receiver
    }
      handshake = Serial1.read();
      handshake2 = Serial1.read();
      handshake3 = Serial1.read();

      if ((handshake == 1) && (handshake2 == 2) && (handshake3 == 3)) {

    Serial1.write(1);

      Serial1.write(data[0]);
      Serial1.write(data[1]);
        Serial1.write(checksum0);

      Serial1.write(data[2]);
      Serial1.write(data[3]); //bytes sent
        Serial1.write(checksum1);

      Serial1.write(data[4]);
      Serial1.write(data[5]);
        Serial1.write(checksum2);

      Serial1.write(data[6]);
      Serial1.write(data[7]);
        Serial1.write(checksum3);

      Serial1.write(data[8]);
      Serial1.write(data[9]); //bytes sent
        Serial1.write(checksum4);

      Serial1.write(data[10]);
      Serial1.write(data[11]);
        Serial1.write(checksum5);

    Serial1.write(2);

       delay(10);     // delay in between reads for stability
      }

    // VIEW IN SERIAL MONTIOR:

    }

RX code:

    /*
      Receving Code
      Reads bytes from Transmitting Code and put thems back together
      Applies the read bytes to our motor control board
    */

    unsigned char val[12];    // variable to read the value from the analog pin
    int Joystick1A;      // 0-1024 received from serial
    int Joystick1B;
    int Joystick2A;
    int Joystick2B;      // 0-1024 received from serial
    int Joystick3A;
    int Joystick3B;

    unsigned char checksum0;
    unsigned char checksum1;
    unsigned char checksum2;
    unsigned char checksum3;
    unsigned char checksum4;
    unsigned char checksum5;
    unsigned char FirstByte;
    unsigned char LastByte;

    unsigned char checkit0;
    unsigned char checkit1;
    unsigned char checkit2;
    unsigned char checkit3;
    unsigned char checkit4;
    unsigned char checkit5;

    //ALL MOTORS:
    int V1Direction = 31;
    int V1PWM = 2;     //MOTOR V1
    int V1Motor;

    int V2Direction = 33;
    int V2PWM = 3;     //MOTOR V2
    int V2Motor;

    int V3Direction = 35;
    int V3PWM = 4;     //MOTOR V3
    int V3Motor;

    int V4Direction = 37;
    int V4PWM = 5;     //MOTOR V4
    int V4Motor;

    int H1Direction = 39;
    int H1PWM = 6;     //MOTOR H1
    int H1Motor;

    int H2Direction = 41;
    int H2PWM = 7;     //MOTOR H2
    int H2Motor;

    int H3Direction = 43;
    int H3PWM = 8;     //MOTOR H3
    int H3Motor;

    int H4Direction = 45;
    int H4PWM = 9;     //MOTOR H4
    int H4Motor;

    void setup() {
      Serial.begin(4800);
      Serial1.begin(4800);
    //  Serial1.begin(4800);
      pinMode(10, INPUT);
      pinMode(18, OUTPUT);
      pinMode(8, OUTPUT);
      pinMode(9, OUTPUT);
      delay(1000);
    }

    void loop() {

      Serial1.write(1);
      Serial1.write(2);
      Serial1.write(3);

      if (Serial1.available()>18) {

      FirstByte=Serial1.read();

      if (FirstByte == 1) {
        val[0]=Serial1.read();         // least significant 8 bits
        val[1]=Serial1.read();         // most significant 2 bits
         checksum0=Serial1.read();     // checksum

        val[2]=Serial1.read();
        val[3]=Serial1.read();
         checksum1=Serial1.read();

        val[4]=Serial1.read();
        val[5]=Serial1.read();
         checksum2=Serial1.read();

        val[6]=Serial1.read();         // least significant 8 bits
        val[7]=Serial1.read();         // most significant 2 bits
         checksum3=Serial1.read();     // checksum

        val[8]=Serial1.read();
        val[9]=Serial1.read();
         checksum4=Serial1.read();

        val[10]=Serial1.read();
        val[11]=Serial1.read();
         checksum5=Serial1.read();

       LastByte = Serial1.read();

    // get the checksum last

        checkit0 = val[0]+val[1]+checksum0;
        checkit1 = val[2]+val[3]+checksum1;
        checkit2 = val[4]+val[5]+checksum2;
        checkit3 = val[6]+val[7]+checksum3;
        checkit4 = val[8]+val[9]+checksum4;
        checkit5 = val[10]+val[11]+checksum5;

    if (LastByte == 2) {
      if (checkit0==0)  {
        Joystick1A = val[1]<<8 | val[0]; }

      if (checkit1==0)  {
        Joystick1B = val[3]<<8 | val[2]; }

      if (checkit2==0)  {
        Joystick2A = val[5]<<8 | val[4]; }

      if (checkit3==0)  {
        Joystick2B = val[7]<<8 | val[6]; }

      if (checkit4==0)  {
        Joystick3A = val[9]<<8 | val[8]; }

      if (checkit5==0)  {
        Joystick3B = val[11]<<8 | val[10]; }

    }
    else (Serial.println("Goodbye"));
        Serial.print(Joystick1A);
        Serial.print(" ");
        Serial.print(Joystick1B);
        Serial.print(" ");
        Serial.print(Joystick2A);
        Serial.print(" ");
        Serial.print(Joystick2B);
        Serial.print(" ");
        Serial.print(Joystick3A);
        Serial.print(" ");
        Serial.println(Joystick3B);
        delay(10);

      }
      }
      }

title: Serial Monitor Just Stops Working

Answers: 0


body:
I have an RGB LED common Anode attached to my Uno and this code detects a long press to turn the LED on and off.  Short presses cycle through colors, then off.

The problem is that a longpress is 2+sec, but it doesn't register until I release the button.  How would I set this up to execute the code at 2sec regardless of whether the button is released?

It's probably not worth my time if it requres too much modification.  I have a working item, it's just not... ideal.

<!-- language: c -->

    Xhunsigned long keyPrevMillis = 0;
    const unsigned long keySampleIntervalMs = 25;

    int redPin = 11;
    int greenPin = 10;
    int bluePin = 9;
    int LEDcolor=0; // 0=White, 1=Red, 2=Green, 3-Blue, 4=Yellow, 5=Purple, 6=Pink, 7=Orange, 8=Off
    int LEDstatus =0; //0=Off, 1=On
    int changed =0; //has the LEDstatus just changed?
    byte longKeyPressCountMax = 80;    // 80 * 25 = 2000 ms
    byte longKeyPressCount = 0;

    byte prevKeyState = HIGH;         // button is active low
    const byte keyPin = 2;            // button is connected to pin 2 and GND

    // called when button is kept pressed for less than 2 seconds
    void shortKeyPress()
    {
       Serial.println("short");
       if (LEDstatus==1)
       {
          LEDcolor = LEDcolor +1;
          if (LEDcolor==0) {analogWrite(redPin, 0);analogWrite(greenPin, 0);analogWrite(bluePin, 0);Serial.println("White");}
          if (LEDcolor==1) {analogWrite(redPin, 0);analogWrite(greenPin, 255);analogWrite(bluePin, 255);Serial.println("Red");}
          if (LEDcolor==2) {analogWrite(redPin, 255);analogWrite(greenPin, 0);analogWrite(bluePin, 255);Serial.println("Green");}
          if (LEDcolor==3) {analogWrite(redPin, 255);analogWrite(greenPin, 255);analogWrite(bluePin, 0);Serial.println("Blue");}
          if (LEDcolor==4) {analogWrite(redPin, 0);analogWrite(greenPin, 0);analogWrite(bluePin, 255);Serial.println("Yellow");}
          if (LEDcolor==5) {analogWrite(redPin, 175);analogWrite(greenPin, 255);analogWrite(bluePin, 175);Serial.println("Purple");}
          if (LEDcolor==6) {analogWrite(redPin, 0);analogWrite(greenPin, 255);analogWrite(bluePin, 155);Serial.println("Pink");}
          if (LEDcolor==7) {analogWrite(redPin, 5);analogWrite(greenPin, 215);analogWrite(bluePin, 255);Serial.println("Orange");}
          if (LEDcolor==8) {analogWrite(redPin, 255);analogWrite(greenPin, 255);analogWrite(bluePin, 255);Serial.println("Off");LEDstatus=0;}
       }
    }

    // called when button is kept pressed for more than 2 seconds
    void longKeyPress()
    {
       Serial.println("long");
       if (LEDstatus==0 && changed==0)
       {
          analogWrite(redPin, 0);
          analogWrite(greenPin, 0);
          analogWrite(bluePin, 0);
          LEDcolor=0;
          changed=1;
          LEDstatus=1;Serial.println("On");
       }
       if (LEDstatus==1 && changed==0)
       {
          analogWrite(redPin, 255);
          analogWrite(greenPin, 255);
          analogWrite(bluePin, 255);
          LEDcolor=0;
          changed=1;
          LEDstatus=0;Serial.println("Off");
       }
       changed=0;
    }

    // called when key goes from not pressed to pressed
    void keyPress() {
       Serial.println("key press");
       longKeyPressCount = 0;
    }

    // called when key goes from pressed to not pressed
    void keyRelease() {
       Serial.println("key release");

       if (longKeyPressCount >= longKeyPressCountMax) {
          longKeyPress();
       }
       else {
          shortKeyPress();
       }
    }

    void setup()
    {
       Serial.begin(9600);
       pinMode(keyPin, INPUT);
       digitalWrite(keyPin, HIGH);
       pinMode(redPin, OUTPUT);
       pinMode(greenPin, OUTPUT);
       pinMode(bluePin, OUTPUT);
       analogWrite(redPin, 255);
       analogWrite(greenPin, 255);
       analogWrite(bluePin, 255);
    }

    void loop() {
    // key management section
       if (millis() - keyPrevMillis >= keySampleIntervalMs) {
          keyPrevMillis = millis();

          byte currKeyState = digitalRead(keyPin);

          if ((prevKeyState == HIGH) && (currKeyState == LOW)) {
             keyPress();
          }
          else if ((prevKeyState == LOW) && (currKeyState == HIGH)) {
             keyRelease();
          }
          else if (currKeyState == LOW) {
             longKeyPressCount++;
          }

          prevKeyState = currKeyState;
       }
    }

title: Changing how a longpress is executed

Answers: 1

body:
I've rewritten the code entirely. Not that yours was terrible, it was just easier for me to start from scratch. You are left with a very empty `loop()`, which I always prefer.

The code contains three 'colours' and an OFF state. You can add as many other colours as you wish: add an enumeration to `_LED_STATE` and then add a corresponding `case(<NEW_COLOUR>)` statement in `LEDcontrol()`. I haven't included any `analogWrite()` functions - or in fact any declarations for the LED pins at all - because I'm a little too lazy but it should be obvious where to put them within the case statement.

Note that in the final `case()` statement, the LED state is changed from green to off. This means that a short press will turn the LED off after it has cycled through all the other colours, but will stay off until a long press. If you only want long pressed to switch off/on, change line 103 to `eLED_STATE = _LED_STATE_RED;`, or whichever the first colour is.

<!-- language: c -->

    #define btn 3 // button pin

    #define SHORT_PRESS 100  // useful for debouncing, can be changed
    #define LONG_PRESS 2000 // defines how long a 'long press' is
    #define CYCLE  false
    #define SHOW  true

    //--// You can add new colours in this enum block
    enum _LED_STATE
    {
     _LED_STATE_OFF,
     _LED_STATE_RED,
     _LED_STATE_BLUE,
     _LED_STATE_GREEN
    };

    _LED_STATE eLED_STATE = _LED_STATE_OFF;

    void setup()
    {
     pinMode(btn, OUTPUT);
     LEDcontrol(SHOW);
    }

    void loop()
    {

     if (digitalRead(btn))
      btnPressed();
    }

    void btnPressed()
    {
     unsigned long tStart = millis();

     //--// Loop continuously while button is pressed
     while (digitalRead(btn))
     {
      //--// If LONG_PRESS is exceeded...
      if (millis() > tStart + LONG_PRESS)
      {
       //--// If LED is off, turn it on
       if (eLED_STATE == _LED_STATE_OFF)
        eLED_STATE = _LED_STATE_RED;  // Choose 'starting' colour
       //--// If LED is on, turn if off
       else
        eLED_STATE = _LED_STATE_OFF;
       //--// Update LED to display new eLED_STATE
       LEDcontrol(SHOW);
       //--// Now loop here until button is released
       while (digitalRead(btn));
      }
     }

     //--// If button is released in between the two press times
     if ((millis() > tStart + SHORT_PRESS) && (millis() < tStart + LONG_PRESS))
     {
      //--// Ignore if LED is off   ////// REMOVE ////////////////////
      if (eLED_STATE == _LED_STATE_OFF) ////////// IF ////////////////////
       return;       ///////////// NECESSARY //////////

      //--// Change the LED colour
      LEDcontrol(CYCLE);
      //--// Update LED to display new eLED_STATE
      LEDcontrol(SHOW);
     }

     //--// This helps to debounce; experiment with it
     delay(10);
    }

    void LEDcontrol(bool SHOW_OR_CYCLE)
    {
     switch (eLED_STATE)
     {
      case(_LED_STATE_RED) :
      {
       if (SHOW_OR_CYCLE)
       {
        // paint it red
        return;
       }
       eLED_STATE = _LED_STATE_GREEN;
       return;
      }
      case(_LED_STATE_GREEN) :
      {
       if (SHOW_OR_CYCLE)
       {
        // paint it green
        return;
       }
       eLED_STATE = _LED_STATE_BLUE;
       return;
      }
      case(_LED_STATE_BLUE) :
      {
       if (SHOW_OR_CYCLE)
       {
        // paint it blue
        return;
       }
       //--// What happens after last colour? Next colour or OFF?
       eLED_STATE = _LED_STATE_OFF;
       return;
      }
      case(_LED_STATE_OFF) :
      {
       if (SHOW_OR_CYCLE)
       {
        // paint it black
        return;
       }
       eLED_STATE = _LED_STATE_RED;
       return;
      }
     }
    }


body:
Could I use something like this as a capacitive button for my arduino project?

http://www.banggood.com/10pcs-25mm-Vintage-Round-Metal-Buttons-Craft-Scrapbooking-Sewing-Suit-Shirt-Button-p-1011485.html

If I connect it into something like this... http://www.banggood.com/MPR121-Capacitive-Touch-Sensor-Module-For-Raspberry-Pi-Arduino-p-969002.html

Would that make that button a capacitive button? Or am I totally barking up the wrong tree here?

Thanks :)

title: Could I use metal buttons as a capacitive button for my arduino project?

Answers: 1

body:
Yes, that would work.

The only thing to watch out for is that the buttons might be plastic with a thin layer of metal on top (Chemical vapor deposition).


body:
I want to convert a bitmap into binary array. My bitmap image is 272*208 pixel monochromatic 1bpp image. I'm confused when the width I get from my image is 16 instead of 272, the height is corrected. And when I skip the bitmap header to get bitmap infomation, I got string of meaningless number in my text file.

<!-- language: c -->

    #include <SPI.h>
    #include <SD.h>
    #include <TFT.h>

    File bmpImage;
    File textFile;

    void setup()
    {
    Serial.begin(9600);
    while (!Serial) {
    ;
    }

    Serial.print("Initializing SD card...");
    if (!SD.begin(53)) {
      Serial.println("initialization failed!");
      return;
    }
    Serial.println("initialization done.");
    int height = 0;
    int width = 0;

    // Open
    bmpImage = SD.open("Circle.bmp", FILE_READ);
    textFile = SD.open("test.txt", FILE_WRITE);

    bmpImage.seek(0x12);// width in pixel = 16
    width = bmpImage.read();
    bmpImage.seek(0x16);// height in pixel = 208
    height = bmpImage.read();
    Serial.println(width);
    Serial.println(height);

    int imageSize = height*width;

    bmpImage.seek(0x36);//skip bitmap header

    for(int i = 0; i < height; i ++) {
      for (int j = 0; j < width; j ++) {
        textFile.write(bmpImage.read());
        textFile.write(" ");
      }
      textFile.write("\n");
    }

    bmpImage.close();
    textFile.close();

    Serial.println("done write");
    }

    void loop()
    {
      // nothing happens after setup
    }

title: How to read bitmap image on Arduino

Answers: 3

body:
That was a very raw way of trying to read a [BMP][1] file. There are a lot of assumptions that might give errors.

1. The file is a BMP file. The header signature is not checked.
2. The image offset is assumed to be directly after the file header. It is not read.
3. The image width is less than 256. Only the lowest byte of the 32-bit image width is read. As 272>256 the low byte is 16.
4. The image height is less than 256. Only the lowest byte of the 32-bit image height is read.

It is a small bitmap but it will take a very long time to read when reading a single byte at a time. There are methods to improve performance but that is an answer to another question.

A more robust method to read the BMP header and image information is to define them as a struct and read.

    struct bmp_file_header_t {
      uint16_t signature;
      uint32_t file_size;
      uint16_t reserved[2];
      uint32_t image_offset;
    };

    struct bmp_image_header_t {
      uint32_t header_size;
      uint32_t image_width;
      uint32_t image_height;
      uint16_t color_planes;
      uint16_t bits_per_pixel;
      uint32_t compression_method;
      uint32_t image_size;
      uint32_t horizontal_resolution;
      uint32_t vertical_resolution;
      uint32_t colors_in_palette;
      uint32_t important_colors;
    };

    bmpImage = SD.open("Circle.bmp", FILE_READ);
    ...
    // Read the file header
    bmp_file_header_t fileHeader;
    bmpImage.read(&fileHeader, sizeof(fileHeader));
    ...
    // Check signature
    ...
    // Read the image header
    bmp_image_header_t imageHeader;
    bmpImage.read(&imageHeader, sizeof(imageHeader));
    ...
    // Check image size and format
    ...
    // Locate the pixels
    bmpImage.seek(fileHeader.image_offset);

The file and image information are stored in little-endian so that works just fine on an AVR.

  [1]: https://en.wikipedia.org/wiki/BMP_file_format

body:
First of all I suggest you to read the full specification of the bmp file header (for instance on [wikipedia][1]).

Particularly see that

 1. You can have a color table (palette): consequently the starting address of the bitmap data CAN not be 0x36
 2. The pixels are not stored one per byte, but can be packed (see [Pixel storage][2])
 3. There are different type of headers
 4. Width and Height are 4 byte integers, so your width is fine (272 = 256 + 16)

This said, *if* your bitmap has a standard `BITMAPINFOHEADER` header, and *if* your bitmap has a 24 bit standard coding (16 millions of colors) you can do something like this:

<!-- language: lang-c -->

    int32_t readNbytesInt(File *p_file, int position, byte nBytes)
    {
     if (nBytes > 4)
      return 0;

     p_file->seek(position);

     int32_t weight = 1;
     int32_t result = 0;
     for (; nBytes; nBytes--)
     {
      result += weight * p_file->read();
      weight <<= 8;
     }
     return result;
    }

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

     Serial.print("Initializing SD card...");
     if (!SD.begin(53)) {
      Serial.println("initialization failed!");
      while (1); // <- this is how you should block execution, not with returns
     }
     Serial.println("initialization done.");

     // Open
     File bmpImage = SD.open("Circle.bmp", FILE_READ);
     File textFile = SD.open("test.txt", FILE_WRITE);

     int32_t dataStartingOffset = readNbytesInt(&bmpImage, 0x0A, 4);

     // Change their types to int32_t (4byte)
     int32_t width = readNbytesInt(&bmpImage, 0x12, 4);
     int32_t height = readNbytesInt(&bmpImage, 0x16, 4);
     Serial.println(width);
     Serial.println(height);

     int16_t pixelsize = readNbytesInt(&bmpImage, 0x1C, 2);

     if (pixelsize != 24)
     {
      Serial.println("Image is not 24 bpp");
      while (1);
     }

     bmpImage.seek(dataStartingOffset);//skip bitmap header

     // 24bpp means you have three bytes per pixel, usually B G R

     byte R, G, B;

     for(int32_t i = 0; i < height; i ++) {
      for (int32_t j = 0; j < width; j ++) {
       B = bmpImage.read();
       G = bmpImage.read();
       R = bmpImage.read();
       textFile.print("R");
       textFile.print(R);
       textFile.print("G");
       textFile.print(G);
       textFile.print("B");
       textFile.print(B);
       textFile.print(" ");
      }
      textFile.print("\n");
     }

     bmpImage.close();
     textFile.close();

     Serial.println("done write");
    }

The text output of this should be a file with an array of strings like `R10G100B25`, where R is the red component of the pixel, G is the green component and B the blue one.

Now, this is only compatible with the 24bpp format. If you want to support more formats you will need to read the specs and code them.

Let me know if this works for you

  [1]: https://en.wikipedia.org/wiki/BMP_file_format
  [2]: https://en.wikipedia.org/wiki/BMP_file_format#Pixel_storage

body:
Or you could keep your old code with some adjustments, if you just want to read your image without bothering with too many checks.

Change the type of imageSize to `unsigned long`.

The height and width are 4-byte fields, so a single read() wont cut it. You have to declare the height and width as *long* or *int32_t* variables and then read 4 bytes at each offset, while using bit shifting to assemble the bytes into one number and remembering that it's little endian.
Something like this:

    long width |= bmpImage.read();
    width |= (long)(bmpImage.read()) << 8;
    width |= (long)(bmpImage.read()) << 16;
    width |= (long)(bmpImage.read()) << 24;

Repeat this to get the height but use *abs()* to get the absolute value since its usually negative.
You can also check for a colour table; usually the ColorDepth field is a good indicator (offset 28); if its less than 16, then you should expect a colour table. But if you know this already, you can skip it and get to the start offset, usually 0x36.
Your current code doesnt take the padding into account (even though your image doesn't have any padding) and it also isnt using the actual image width in bytes. To get this width, assuming the BMP uses RGB888 24 bits per pixel:

    width = ((width * 24) + 31) / 32;
    width *= 4;

With this, you can now read each row, though its usually arranged bottom-up. However, you arent writing properly to the file. You should use `textfile.print()` and not `write()`; the former will write the decimal value of each byte to your file while the latter will write the exact un-encoded byte to the text file, which would result in a lot of gibberish when you try to display the file's contents, say on Notepad, since the range of printable characters (under default ASCII encoding) is between 32 - 127 and your image probably has lots of bytes outside that range.


body:
Is Arduino uno SPI comunication can be also master and slave in the same time?

OR master 2 slaves in the same time?
------------------------------------------------------------

I want to recevice data from a sensor and display on OLED (all data transfer with SPI bus)

Can I master those two device (sensor & OLED) in the same time? (with SS pin to select slave )

OR Can I be both slave(recevices the data from sensor) and master (sent data to OLED) in the same time ?

What should I do ? and How can I do?

(I read the SPI example code on the Official website , but I still have no ideal about it)

Answers: 2

body:
You can have several devices on an SPI bus. Each must have a chip select. The Arduino SS pin (Uno pin 10) is often used for chip select. Chip select pins should then be in output mode.

Connect the sensor and display to the SPI bus (MOSI, MISO, SCK) and use a chip select pin for each.

A driver (library) for a device connect to the SPI bus will typically assert the chip select pin and transfer commands and data. The SPI transfer is both read and write at the same time.

body:
SPI is bi-directional, so sending data or receiving data doesn't indicate if it's a master or a slave.

The master is the one that initiates the communications, that's all. So the arduino is a master in both cases. The master send data to the OLED. The master requests data from the sensor.


body:
I have bought a 2.5" TFT shield online, which is equipped with the ILI9341 controller. I need to dim the intensity of the background LEDs to match ambient light.

This particular shield does not provide a pin to control the intensity of the LEDs with PWM via a separate input, so I need to dim the background LEDs of this display via software.

The zip file with the libraries can be downloaded [here][1].

Does one of you know how can issue a command to the TFT display to dim the background LEDs?

Thanks in advance!

# UPDATE 1:

I wrote a new function to set the display's brightness by controlling the background LEDs, but something is missing as I can seem to be writing correctly to the display. So I'm trying to get the display to answer to a known command first, like 0x28 (Display Off).

The new function is defined in Adafruit_TFTLCD.cpp:

    // Set display brightness (background LED's)
    void Adafruit_TFTLCD::setDisplayBrightness(uint8_t x) {
      // Try with 0x28 (Display Off) to see if display reacts
      writeRegister8(0x28, 0);
      return;
    }

The function prototype is defined in Adafruit_TFTLCD.h

    // New functions
    void setDisplayBrightness(uint8_t x);

Then I call the function in my main loop. To make sure, I first write some rectangles on screen, wait 5 seconds, then fill the screen with blue, call the new function and enter an endless loop so no other commands can interfere:

      tft.fillScreen(BLUE);
      tft.setDisplayBrightness(10); // Which really is command 0x28 to test

Any clues what I might be missing?

Thanks!

UPDATE 2:

I got so far as to have the ILI9341 react to some commands, but not all the time, and not to all commands. I suspect there is something in the way you issue the commands that I'm missing( timing?, sequence?, other?)

Here is what I have found out so far:

I can get the display to react to the Display Off command (0x28), but only when I issue it in the begin(..) function. So, the original code in Adafruit_TFTLCD.cpp is like this:

    void Adafruit_TFTLCD::begin(uint16_t id) {
    ...
    writeRegister8(ILI9341_DISPLAYON, 0);
    delay(500);

If I change it to the following the display reacts by remaining white:

    void Adafruit_TFTLCD::begin(uint16_t id) {
    ...
    writeRegister8(ILI9341_DISPLAYON, 0);
    writeRegister8(ILI9341_DISPLAYOFF, 0); // Display off is declared as 0x28
    delay(500);

So, I have a reaction to command 28h.

Then I tried function 0x51 like this in the begin(...) function:

    void Adafruit_TFTLCD::begin(uint16_t id) {
    ...
    writeRegister8(ILI9341_DISPLAYON, 0);
    delay(500);
    writeRegister8(0x51, 0x80); // Test command 0x51 - background intensity
    delay(500);

To no effect :-(

I even added command 0xBE (background PWM frequency) to see if it had any effect, but nothing :-(

    void Adafruit_TFTLCD::begin(uint16_t id) {
      ...
      writeRegister8(ILI9341_DISPLAYON, 0);
      writeRegister8(0xbe, 0x80);
      delay(500);
      writeRegister8(0x51, 0x0);
      delay(500);

Also if I issue the 0x28 command:

    writeRegister8(ILI9341_DISPLAYOFF, 0)

elsewhere in Adafruit_TFTLCD (e.g. in FillScreen, Fill Rect etc, it doesn't work either).

Any ideas? They would be highly appreciated!

  [1]: http://forum.arduino.cc/index.php?action=dlattach;topic=314613.0;attach=121865

title: How to dim background LEDs on TFT display with ILI9341

Answers: 5

body:
It looks like it should be controllable with command 0x51.

I would modify the library and add a new method to the `Adafruit_ILI9341_8bit_AS` class - something like:

    void Adafruit_ILI9341_8bit_AS::setBacklight(uint8_t brightness) {
        writeRegister8(0x51, brightness);
    }

Then you can change the brightness by calling that method on your TFT object in your sketch.  (Don't forget to add the prototype to the class definition in the header file of course).

body:
I got in contact with the manufacturer of the shield, they informed that the background LEDs are hardwired and not controllable via the ILI9341. So, it is not possible to dim the background light in this shield

:-(

I will look for another TFT shield and make sure it's dimmable before buying.

body: After looking at the schematic (mine is different) but on pin 16 is labeled as BL. If that is indeed the power for the LED backlights then a voltage applied to it should vary the brightness.  Caution:You need to know how much current the LEDs are pulling. If over the limit for a PWM pin you will have to run it through a transistor to boost the current.

body:
Most of thees cheap Chinese LCD modules have the LED backlight hardwired to Vcc and GND and cannot be controlled.

However, after inspecting the module I have and some similar ones online I found that most have the Back-light LEDs pins available through the LCD panel flex cable. If yours is similar to the one in the picture then you will notice that the main flex cable is for the LCD itself, and there are usually two other flex cables connected to it. The one on the left is for touch panel (if equipped), and the one of the right is for the back light LEDs (sometimes it is connected on the backside of the flex).

[![enter image description here][1]][1]

In this panel and on mine (a little different from this) they are labeled as K1, K2, K3 and K4 which are mostly the Cathode side of the LED (negative side) and they are exposed as separate pins in the main flex cable, while the Anode is soldered to the main flex cable Vcc plane and cannot be easily accessed without desoldering the LED flex cable.

[![enter image description here][2]][2]

So in ordered to control the backlight you have to cut the trace on the PCB (not the flex cable) and connect it to a transistor which you control through the Arduino.

* Double check the polarity in your LCD panel, it could be different from mine.

  [1]: https://i.stack.imgur.com/A8F27.png
  [2]: https://i.stack.imgur.com/geDK8.png

body:
I have successfully dimmed the backlight on a ili9341 by simply modulating the pin the LED pin is connected to.

Note, I am using a teensy 3.2 your mileage may vary.

    ledPin=32;

    void loop() {
    analogWrite(ledPin, 60);