text:
28 BYJ stepper motor runs faster using delay() and little slower using millis(), why?
I'm working to develop a code for the stepper motor to use it in a project. And since using delay() isn't as efficient as millis(). So I first developed the code that use delay with 1ms delay between the steps which is the fastest I could do with this stepper motor.
Then I developed similar code using millis() with same 1ms delay but it didn't feel as smooth/fast as the one with delay() function.
So what's the reason for that?
These are the code:

With delay():
    void clockwise(void){
        digitalWrite(in4, HIGH);
        digitalWrite(in3, LOW);
        digitalWrite(in2, LOW);
        digitalWrite(in1, LOW);
    delay(1);
        digitalWrite(in4, HIGH);
        digitalWrite(in3, HIGH);
        digitalWrite(in2, LOW);
        digitalWrite(in1, LOW);
    delay(1);
        digitalWrite(in4, LOW);
        digitalWrite(in3, HIGH);
        digitalWrite(in2, LOW);
        digitalWrite(in1, LOW);
    delay(1);
        digitalWrite(in4, LOW);
        digitalWrite(in3, HIGH);
        digitalWrite(in2, HIGH);
        digitalWrite(in1, LOW);
    delay(1);
        digitalWrite(in4, LOW);
        digitalWrite(in3, LOW);
        digitalWrite(in2, HIGH);
        digitalWrite(in1, LOW);
    delay(1);
        digitalWrite(in4, LOW);
        digitalWrite(in3, LOW);
        digitalWrite(in2, HIGH);
        digitalWrite(in1, HIGH);
    delay(1);
        digitalWrite(in4, LOW);
        digitalWrite(in3, LOW);
        digitalWrite(in2, LOW);
        digitalWrite(in1, HIGH);
    delay(1);
        digitalWrite(in4, HIGH);
        digitalWrite(in3, LOW);
        digitalWrite(in2, LOW);
        digitalWrite(in1, HIGH);
    delay(1);
}

With millis():
  void stepper_run_cw(void){
  stepper_step_cw(1,0,0,0,1);
  stepper_step_cw(1,1,0,0,1);
  stepper_step_cw(0,1,0,0,1);
  stepper_step_cw(0,1,1,0,1);
  stepper_step_cw(0,0,1,0,1);
  stepper_step_cw(0,0,1,1,1);
  stepper_step_cw(0,0,0,1,1);
  stepper_step_cw(1,0,0,1,1);
}

void stepper_step_cw(uint8_t m_in1, uint8_t m_in2, uint8_t m_in3, uint8_t m_in4, uint8_t delay_time){
  if (!stepper_run){
    digitalWrite(in1, m_in1);
    digitalWrite(in2, m_in2);
    digitalWrite(in3, m_in3);
    digitalWrite(in4, m_in4);
    stepper_start = millis();
    stepper_run = 1;
  }

  if(stepper_run){
    stepper_current = millis();
    if(stepper_current - stepper_start >= delay_time){
      stepper_run = 0;
    }
  }
}

why would you repeat digitalWrite(in1, LOW); five times in a row? .... you only need to run it one time  .... same for the other pins   ........... also, the if(stepper_run){ should be an else instead

@jsotola 1. How to run it one time? And in which function? The 1st or 2nd posted codes? 2. Got the tip about using else thanks.

How can the second function work at all? What if you enter in stepper_run_cw with stepper_run = 0 and millis not changing , nothing? stepper_step_cw call that does something is purely random, the one where millis changed form the last call to stepper_step_cw.

try using micros() instead of millis()

i just had a thought ..... i wonder if the order of the digitalWrite commands has anything to do with the speed difference .... one is 4321 and the other is 1234 ................ change the order in one of them ....... also put stepper_start = millis(); at the top of the if block

@jsotola yep the micros() works too, I can crank the speed even faster :) thanks for the tip.

Maybe for the second function you want something like this:
 void stepper_run_cw(void){
  stepper_step_cw(1,0,0,0,1);
  stepper_step_cw(1,1,0,0,1);
  stepper_step_cw(0,1,0,0,1);
  stepper_step_cw(0,1,1,0,1);
  stepper_step_cw(0,0,1,0,1);
  stepper_step_cw(0,0,1,1,1);
  stepper_step_cw(0,0,0,1,1);
  stepper_step_cw(1,0,0,1,1);
}

void stepper_step_cw(uint8_t m_in1, uint8_t m_in2, uint8_t m_in3, uint8_t m_in4, uint8_t delay_time){
  unsigned long temp, i;
  for (i=0;i<delay_time;i++){
    temp = millis();
    while (temp == millis){};//wait for millis to change
  }
    digitalWrite(in1, m_in1);
    digitalWrite(in2, m_in2);
    digitalWrite(in3, m_in3);
    digitalWrite(in4, m_in4);
}

This code is also avoiding the millis overflow issue if you run your board for a long time.
Still, apart for a improved timing, there is no gain in using millis(), you still have to wait for millis to change, you might want to use a timer interrupt to do the job in background.

The real gain when using millis() is that you aren't blocked in delay() and can react to inputs changing without needing to resort to interrupts.

Yes, that's my aim. Is not to use delay. Hmm I'm still considering to improve the function which uses millis(), it's working anyway, it just give a different result like littttle slower that's all. Otherwise it's works like a charm :)

After working on developing the function couple times, I got a way with this function and runs smoothly too :)
Hope anyone find it useful.
// this library is for the 28BYJ stepper motor

  #define in1 6
  #define in2 7
  #define in3 8
  #define in4 9

  // blink
  unsigned long blink_start_millis;
  unsigned long blink_current_millis;
  unsigned long blink_period = 100;

  uint8_t stepper_masks[] = {0x80,0xc0,0x40,0x60,0x20,0x30,0x10,0x90};
  int8_t s=0;
  uint32_t stepper_start;
  uint32_t stepper_current;
  uint32_t stepper_period;
  byte stepper_run;

  void blink_pin13(void);
  void stepper_step(uint8_t *mask, uint8_t delay_time, uint8_t dir);

  void setup() {
    Serial.begin(9600);// put your setup code here, to run once:
    for(byte i=in1;i<=in4;i++){
      pinMode(i,OUTPUT);}

    pinMode(13,OUTPUT);

  }

  void loop() {
   stepper_step(stepper_masks,1,0);
    blink_pin13();

  }

  void blink_pin13(void){
      blink_current_millis = millis();
      if(blink_current_millis - blink_start_millis >= blink_period){
      digitalWrite(13, !digitalRead(13));
      blink_start_millis = blink_current_millis;
    }
  }

  void stepper_step(uint8_t *mask, uint8_t delay_time, uint8_t dir){
    if (!stepper_run){
      for(byte i=6;i<10;i++){
        digitalWrite(i, 0<(mask[s]&0x80>>i-6));
      }
      if(!dir){s++;if(s>7)s=0;}
      else {s--;if(s<0)s=7;}
      stepper_start = millis();
      stepper_run = 1;
    }

    if(stepper_run){
      stepper_current = millis();
      if(stepper_current - stepper_start >= delay_time){
        stepper_run = 0;
      }
    }
  }


text:
How to read the raw data from GY-85 module?
This module has 3 sensors. Gyroscope, Accelerometer and Magnetometer.
I think I'm reading the raw data in the wrong way.
For example, for the magnetometer HMC5883L, I'm using this code which I copied from a library and it gives the correct values, but when I use the same code for reading the raw data from the accelerometer ADXL345 then it's not what it should be according to different sources I've read.

The magnetometer HMC5883L:
void HMC5883L_print_Serial(void)
{
  int16_t x,z,y;
  uint8_t data[6];
  float heading,heading_in_degrees,declination_angle_YANBU;

  data_read(data);

  // This one doesn't
  x = data[1] << 8 | data[0];
  z = data[3] << 8 | data[2];
  y = data[5] << 8 | data[4];

  // This one works OK
  /*x = data[0] << 8 | data[1];
  z = data[2] << 8 | data[3];
  y = data[4] << 8 | data[5];*/

  heading = atan2(y,x);
  declination_angle_YANBU = ((3.0 + (52.0 / 60.0)) / (180 / M_PI));  // in yanbu city it's
  heading += declination_angle_YANBU;

  // Correct for heading < 0deg and heading > 360deg
  if (heading < 0){
    heading += 2 * PI;
  }

  if (heading > 2 * PI){
    heading -= 2 * PI;
  }

  heading_in_degrees = heading * 180 / M_PI;
  Serial.println(heading_in_degrees);
  _delay_ms(20);

}

The accelerometer ADXL345
void ADXL345_print_Serial(void){
  int16_t x,z,y;
  uint8_t data[6];

  ADXL345_read_raw(data);

  // This one gives values from -255 to +255
  x = data[1] << 8 | data[0];
  z = data[3] << 8 | data[2];
  y = data[5] << 8 | data[4];

  // This one give values from -32768 to +32768
  /*x = data[0] << 8 | data[1];
  z = data[2] << 8 | data[3];
  y = data[4] << 8 | data[5];*/
    Serial.print(x);Serial.print("\t");
    Serial.print(y);Serial.print("\t");
    Serial.println(z);
    _delay_ms(100);
}

So basically I want to learn how to work with these sensors and also I want to know the principles about each one, because I'm confused between then I feel they are the same and each one provides similar functions; like, tilt sensing.

One gives you an absolute orientation using the earth's magnetic field. The other gives you changes in velocity (and gravitational pull, which is a form of acceleration). In what way are they the same?

Have you looked at the ADXL345 datasheet to see what the communication protocol is? Is it the same as for the HMC5883L? Or should you be implementing a different system?

Hi, they both use I2C protocol. All the sensors on that board use the same protocol. You're right they are different but I thought it's like similar, because they change the values when tilting! That confuses me because; for example, the accelerometer should change the values only when I move it forward, backward and up-down, so it also changes the values when I flip or tilt it .. that was confusing.

OK, I started to understand the the accelerometer is actually measuring the static gravity values, that's why it gives values on each side of the module. The internal mass is tilting positions. So, I just now have to understand how to know how to prepare these values for my project.

One of the places where the datasheets for the sensors of the GY-85 module can be found is here: https://www.hotmcu.com/gy85-9dof-imu-sensor-module-p-298.html
The following information comes from these datasheets:
Both the HMC5883L and the ADXL345 have internal registers which are numbered consecutively. When reading more than one register they are most efficiently read in the order they are numbered. For each of the three axes both sensors use two 8-bit registers to hold the measured value.
In the HMC5883L the register with the lower number holds the most significant byte (MSB) and the register with the higher number holds the least significant byte (LSB). This means that in a consecutive read the MSB is read first followed bij the LSB. When you combine these two bytes into one 16 bit number (datatype int) you have to shift the MSB-holding byte (the first byte received) 8 places to the left and "OR-in" the LSB-holding byte (the second byte received).
In the ADXL345 the internal numbering is the other way around: the register with the lower number holds the LSB and the register with the higher nummer holds the MSB. When reading, the LSB is red first followed by the MSB. So this time you have to shift the second byte received and "OR-in" the first byte received.
Both sensors give the measured value as a 16-bit 2-complement number, corresponding to datatype int (Arduino Uno). An 16-bit int can hold values from -32,768 to +32,767 but the sensors don't (can't) use this full range:
The ADXL345 has an adjustable range with a maximum of 13 bits (-4096 to +4095).
The HMC5883L has a range of 12 bits (-2048 to +2047).

OK, then my current HMC5883L is wrong. I put the first byte on the right of the 16-bit register. As in this code: x = data[1] << 8 | data[0];   z = data[3] << 8 | data[2];   y = data[5] << 8 | data[4]; But I have to change it.

Success! Please let us know if if you new code works.

Yeah it's working now. My current concern is that I know that taking the atan2(y,x); would give me the heading. But what is the benefit of z-axis? And how can I use the HMC5883L in a quadcopter?

source: Stack Exchange

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

sort: votes


text:
Why using static volatile for variables and only static for arrays in TWI library?
I want to know why to declare variables with static volatile and arrays with only static in TWI library?
For example;
static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH];
static volatile uint8_t twi_masterBufferIndex;
static volatile uint8_t twi_masterBufferLength;

Do you understand what volatile does?

I learned something like that this variable maybe changed but in which aspect I don't know.

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


text:
Difference between ISR and other functions in AVR twi library
I was studying the ISR for twi and I want to know how is it working.
I have two questions about the code handling for ISR and the other functions and what they do exactly:

My first question is about how ISR for twi is working? The following example shows a piece of the ISR for twi library. My concern here is how switch statement is working?

And probably I have to understand how TWSR works; for example, I think when twi module sends or receive an address, the TWSR is updated according to TWSR Status codes. But I really don't understand exactly what is happening?! Which happens first?
The programmer issue the twi operation; like, sending a start address. Then, the TWSR is updated with the code 0x08 which means according to the datasheet "A START condition has been transmitted". If that so, then why in the following ISR code. The status code is called as a switch result for twi operation, then it issue an action based on that??!! that what is confusing to me!
So, is the procedure of twi:
1. Send start address.
2. TWSR is updated with 0x08 as a confirmation for the start action.
3. Here the ISR issues another action based on the TWSR again? This is what I didn't understand.
ISR(TWI_vect)
{
  switch(TW_STATUS){
    // All Master
    case TW_START:     // sent start condition
    case TW_REP_START: // sent repeated start condition
      // copy device address and r/w bit to output register and ack
      TWDR = twi_slarw;
      twi_reply(1);
      break;

My second question is about the relationship between ISR and other functions. For example,
  if (true == twi_inRepStart) {
twi_inRepStart = false;
do {
  TWDR = twi_slarw;
} while(TWCR & _BV(TWWC));
TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE);
}
else
TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE) | _BV(TWSTA);
while(wait && (TWI_MTX == twi_state)){
continue;
}

Here is another start send address operation. So which one is the real one? The start send in the ISR or this one?

The confusing thing is that there is only one interrupt, and it is called for a number of different reasons.
To make sense of why it's being called you also have to know what you have just done in order to know what to expect. In this case we have just sent a START bit, so we set the current status to "start sent". When the interrupt fires we know that it must be in response to the start bit we sent earlier having been completed, so it's time to then send the address.  It's just implementing a simple state machine.
To answer your second question: both are "real" and used.
When sending data to a slave it can be easily implemented with a non-blocking interrupt arrangement. This makes it fast and efficient, and you can get on with doing other things while the data is being sent. That uses the ISR.
When reading from a slave it's harder to implement it with an ISR and still fit into the Arduino ethos of "data is available immediately", so when using requestFrom a simpler blocking routine is called that doesn't use the ISR. This means that when the function is completed all the data has been received and you can get on with reading it from the buffer. If you used the ISR instead then data wouldn't have arrived until some unknown time after you have made the request - so you would have to implement either some kind of callback system to execute a user function when the data has arrived, or manually block waiting for the data to arrive polling a status set by the ISR, which is pretty pointless anyway. So it's just been implemented as a simple blocking routine.
It's crude, but like much of the Arduino API it "gets the job done with the minimum of fuss" - sacrificing efficiency for simplicity and ease of use.

To break it down for you further:

When using Wire.beginTransmission(...) the ISR is used to empty the buffer onto the physical wires. Your sketch can continue while that is happening.
When using Wire.requestFrom(...) the ISR is not used. Your sketch cannot continue until the whole buffer has been received (or it times out).

When using Wire.beginTransmission(...) you first fill the buffer (32 bytes maximum) with your data to send. Calling Wire.endTransmission(...) then starts the sending of the data from the buffer using the ISR.
When you use Wire.requestFrom(...) a call to the Wire.beginTransmission(...) and Wire.endTransmission(...) functions are called to send the address. This uses the ISR.  Following that the twi_readFrom(...) function is called to receive the data in a blocking fashion. That first blocks itself waiting for the ISR to signal that the I2C bus is available and it has finished sending the address. The twi_readFrom(...) function then, if it's using repeated start, sends the start bit again. If it's not using repeated start then it just gets on with the task of reading the data into the buffer.  The actual reception of the data triggers an interrupt which copies the data into the incoming RX buffer from the FIFO, but that's pretty much all the interrupt does when receiving.
Much of the confusion (and it's confusing even to me) comes because the Wire library is written in two layers - an Arduino API wrapper class which implements the Wire object that you are familiar with, and a pure C set of helper functions which most likely were ported over from some other Atmel application library originally. This makes it quite hard to follow what is going on, since the two programming styles and ways of working are very different. Following the thought processes of two different parties working in different ways with different goals in mind is tricky at best.
To better understand how it all fits together you want to sit down with a couple of example transactions (both read and write) and a copy of the datasheet and trace exactly how the program would flow and respond to the different events and sequences within those transactions. Have the transaction waveforms on paper in front of you and mark on them where the different interrupts trigger. Follow that through in the code and work out what exactly gets called when and why it gets called. Quite an arduous task, but essential if you want to fully understand exactly what is going on in the code.

Call back functions which is something I didn't understand until this moment. First thing you said it's one interrupt and called for different reason, that I understand because of different TWSR codes. Second, you say we sent a start bit? Where did we do that? There is no start bit in both cases the start is sent with the address. But, in the readFrom function, there are two start conditions which is connected to the ISR start case. So, if repeated start is true then it should send address without start, else is should initiate only start without address and that triggers the ISR.

Setting the bit _BV(TWSTA) sends the start bit. The ISR has no relation to the receiving data function. It is not used. It is only used for pure transmission.

Yes, what is interesting is that the author is wrapping the wire library from twi library, but I stopped looking into the wire library and focus on the twi library, I think it's all I need to understand how to fix my I2C code. First, I had a bug in my I2C code and the reason is because I don't send a NACK after reading the last byte, the code performed much better. Now, I have another problem with the numbers I read.

All the variables in the twi library are declared in uint8_t and in the Arduino application code which uses wire library the final variables to hold the 16-bit of x,z,y axis are declared in int and the results are OK. I don't know how the values are converted when they are received in uint8_t buffers and then transferred to int variables works well, I did the same but I have very different results.

OK, in regard to your further explanation, I think I understand now, that everything is done in the ISR mode, and the functions like readFrom are the arrangement of handling the ISR, and the buffers are already filled in the ISR because it's passing the array and copying the received data into the passed parameter. I just left little things to understand. Like, while(TWI_READY != twi_state){     continue;   } When this while loop should breaks? I mean when the code is locked by this while loop, what is the interrupt which would break it and how?

Also, I want to be sure of the point I mentioned in the main post about TWDR = twi_slarw; This line is present in both the main function and the ISR, what is the difference between the two situations?

uint8_t I2C_start(uint8_t address) {  TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);  while (!(TWCR & (1<<TWINT)));  TWDR = address;  TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);  while (!(TWCR & (1<<TWINT))); } Is this a good start code? I'm clearing TWINT two times! I don't know where I learned that.

ISRs are triggered by status (more precisely status changes). For example, once the device address is sent, the hardware will set a flag, which will be serviced by the isr; if the data is sent, the hardware will set another flag, triggering the isr....
It is through this process that the transmission is carried out in an orderly fashion, without tying up the mcu.
For a more detailed description of how avr i2c modules work, check out datasheet for older lpc/nxp mcus.
The other approach is for the mcu to poll the hardware and process the flags accordingly.
Hope it helps.

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


text:
Where to find the attribution name for a certain board?
I'm working on lcd128x64 spi library. And was working with my Arduino Atmega328p chip.
Now I want to run the code with my maple mini board too.
So I have to specify the name on the pins for each chip board.
But I want to learn the basics of how to write these statements.
Could you tell me where to find the attributions for each board ?
For now I want to define the pin names for the Atmega328p and maple mini. This is my intention:
#if defined(__AVR_ATmega328P__)
    #define CS_PIN                  10
    #define MOSI_PIN                11
    #define CLK_PIN                 13
#elif defined(STM32_SERIES_F1)
    #define CS_PIN                  PB12
    #define MOSI_PIN                PB15
    #define CLK_PIN                 PB13
#endif

I don't think that's %100 correct, but I'm pretty sure that it's not the correct names of boards.

The whole point of the Arduino API is that you don't need to know the names of pins. You just need the numbers that the API assigns to them.

the SPI libraries know the pin numbers. you don't need to spceify them in normal case. the pins 11, 12, 13. are valid for Uno and Nano, not for ATmega328p.

Yeah I know but in my lcd128x64 library, I'm using both atmega328p and stm32 which is using other pins names and also it has two spi modules. Like, in this init function void lcd128x64_init(void){  pinMode(CS_PIN, OUTPUT);  pinMode(CLK_PIN, OUTPUT);  pinMode(MOSI_PIN, OUTPUT);  digitalWrite(CS_PIN, LOW);       // disable CS_PIN  SPI.begin();  _delay_ms(100);          // initial delay  digitalWrite(CS_PIN, HIGH);       // enable CS_PIN ... } the pins names are different, so I want to unify them in the header file.

Also spi2 initialization for stm32 is different SPI_2.begin(); //Initialize the SPI_2 port.   SPI_2.setBitOrder(MSBFIRST); // Set the SPI_2 bit order   SPI_2.setDataMode(SPI_MODE0); //Set the  SPI_2 data mode 0   SPI_2.setClockDivider(SPI_CLOCK_DIV16);  // Use a different speed to SPI 1   pinMode(SPI2_NSS_PIN, OUTPUT); so I have put that in my lcd128x64 lib

When I try to compile the code for the maple mini I get this:
`Arduino: 1.8.12 (Windows 10), Board: "Maple Mini, Original (17k RAM,108k Flash), 72MHz (Normal), Smallest (default)"
H:\Programming\Program_Files\Arduino\libraries\lcd128x64_spi\lcd128x64_spi.cpp:14:20: fatal error: avr/io.h: No such file or directory
#include <avr/io.h>
                ^

compilation terminated.
exit status 1
Error compiling for board Maple Mini.
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.`

The Arduino defines to identify a board are in form of ARDUINO_<board>, where <board> is the value from <x>.build.board from boards.txt for board <x>
For example for Arduino AVR boards, in the boards.txt file is uno.build.board=AVR_UNO so the define is ARDUINO_AVR_UNO.
And Arduino has 'architecture' identification define too. This has form of ARDUINO_ARCH_<arch.name>. The <arch.name> is the uppercase version of the folder name with the boards package version. For example AVR for packages/arduino/hardware/avr/1.6.21.

But I want the specific attribution that are like in this link. @https://www.microchip.com/webdoc/avrlibcreferencemanual/using_tools_1using_avr_gcc_mach_opt.html@ I want the same for the STM32 I couldn't find its attribution.

@R1S8K, use arduino board or architecture identification, not the chip identification.

OK but I get now fatal error that including the avr/io .. `Arduino: 1.8.12 (Windows 10), Board: "Maple Mini, Original (17k RAM,108k Flash), 72MHz (Normal), Smallest (default)"
H:\Programming\Program_Files\Arduino\libraries\lcd128x64_spi\lcd128x64_spi.cpp:14:20: fatal error: avr/io.h: No such file or directory
#include <avr/io.h>
                ^

compilation terminated.
exit status 1
Error compiling for board Maple Mini.
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.` What to do now ?

@R1S8K, ask a new question

OK I'm trying to solve it before asking a new question.

How to use the board identification ?

@R1S8K, instead of __AVR_ATmega328P__ use ARDUINO_AVR_UNO for pin mapping defines

ok thanks I didn't care for the Arduino as it's already defined but I was searching for the stm32 attribution. I think I found it and it's basically working.

If you are working on Maple Mini, you may look in this folder, you will found the pin mapping between STM32 and Arduino nomenclature.

Yep, you're right. I didn't notice the rest of the name ! I thought they are just STM chips but I found the maple mini folder there, but also couldn't find the right attribution.

I don't get what you are looking for: is not enough this
{&gpiob,   NULL, NULL, 11, 0, ADCx}, /* D0/PB11 */ ?

Maybe the official repo is cleaner: look at this file

@fabuiz7 thank you so much for your help. I'm actually found part of the solution which is just to use what I put in the main post which is STM32_SERIES_F1 it worked, but I'm getting other errors that I'm trying now to solve them.

try this define, for me it worked ;) ARDUINO_MAPLEMINI_F103CB

Nope it got me this error list: `error: 'CS_PIN' was not declared in this scope
pinMode(CS_PIN, OUTPUT);
error: 'CLK_PIN' was not declared in this scope
pinMode(CLK_PIN, OUTPUT);
error: 'MOSI_PIN' was not declared in this scope
pinMode(MOSI_PIN, OUTPUT);
error: 'delay_ms' was not declared in this scope
delay_ms(100);          // trying initial delay`

Which Arduino Core are you using? I had installed this one

How to post a link ? Sorry I don't know how.

Let us continue this discussion in chat.

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


text:
Topic: How to draw a circle on LCD128x64?
I want to know what's the default or recommended arithmetic to draw a circle on the LCD128x64 using ST7920 driver.
I've done the following functions:

drawing a pixel at any point on the LCD
sending an image
drawing a vertical, diagonal and horizontal lines
send CGRAM chars

But I can't draw a circle.
Here's my code:
/*  Project name:       lcd128x64
    Author:             r1s8k
    Date:               22/12/2019, 12:25 AM

    Project specs:      This is the source file of the lcd128x64 driver that uses
                        MCP23017 as the lcd driver using SPI interface

*/

#include <avr/io.h>
#include <Arduino.h>
#include <SPI.h>
#include <avr/pgmspace.h>
#include <math.h>
#include "lcd128x64_spi.h"

////////////////////////////////////////////////////////////////////////////////////////////
// global variables
static uint8_t graphics, horizontal,y_pre,p_dr_act,block_pre;
//static uint16_t p_buf;
static uint16_t p_pre;
uint8_t p_hi,p_lo,p_block,p_pos,p_bit;

////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
// control functions

// init
void lcd128x64_init(void){
    pinMode(CS_PIN, OUTPUT);
    pinMode(CLK_PIN, OUTPUT);
    pinMode(MOSI_PIN, OUTPUT);
    digitalWrite(CS_PIN, LOW);                          // disable CS_PIN
    SPI.begin();
    _delay_ms(100);                                     // trying initial delay
    digitalWrite(CS_PIN, HIGH);                         // enable CS_PIN

    _delay_ms(50);                                      // datasheet says > 40ms
    lcd128x64_cmd(FUNCTION_SET_BASIC);  //_delay_us(28);// datasheet says > 100us - 72 = 28us
    lcd128x64_cmd(FUNCTION_SET_BASIC);  //_delay_us(28);// important for going to / coming back from graph mode
    lcd128x64_cmd(DISABLE_V_SCROLL);                    // if you have extended list to scroll
    lcd128x64_cmd(DISPLAY_CONTROL);     //_delay_us(28);// display = 1, cursor = 0, blink = 0
    lcd128x64_cmd(ENTERY_MODE);                         // cursor = right, display shift = 0

    lcd128x64_cmd(DISPLAY_CLEAR);
    lcd128x64_cmd(RETURN_HOME);
    graphics = 0;
    horizontal = 0;
}
// command tx
void lcd128x64_cmd(uint8_t cmd){
    SPI.transfer(CMD_MSK);
    SPI.transfer(cmd & 0xf0);
    SPI.transfer(cmd << 4);
    if(cmd == 0x01)_delay_us(1600); else _delay_us(72);
}
// data tx
void lcd128x64_data(uint8_t data){
    SPI.transfer(DATA_MSK);
    SPI.transfer(data & 0xf0);
    SPI.transfer(data << 4);_delay_us(72);
}
// move cursor
void lcd128x64_move_cursor(uint8_t row, uint8_t col){
    if      (row == 1)lcd128x64_cmd(0x80 + (col - 1));
    else if (row == 2)lcd128x64_cmd(0x90 + (col - 1));
    else if (row == 3)lcd128x64_cmd(0x88 + (col - 1));
    else if (row == 4)lcd128x64_cmd(0x98 + (col - 1));
}
// clear lcd
void lcd128x64_clr(void){
    uint8_t y,x;
    lcd128x64_graphics_set_mode(1);
    for(y=0;y<32;y++){
        for(x=0;x<8;x++){
            lcd128x64_cmd(0x80+y);lcd128x64_cmd(0x80+x);
            lcd128x64_data(0x00);lcd128x64_data(0x00);
        }
    }
    for(y=32;y<64;y++){
        for(x=0;x<8;x++){
            lcd128x64_cmd(0x80+y-32);lcd128x64_cmd(0x88+x);
            lcd128x64_data(0x00);lcd128x64_data(0x00);
        }
    }
}
// graphics mode
void lcd128x64_graphics_set_mode(uint8_t mode){
    lcd128x64_cmd(FUNCTION_SET_EXTENDED);
    if(mode){
        lcd128x64_cmd(GRAPHICS_ON1);
        lcd128x64_cmd(GRAPHICS_ON2);
        graphics = GRAPH;
    }
    else{
        lcd128x64_cmd(GRAPHICS_OFF1);
        lcd128x64_cmd(GRAPHICS_OFF2);
        graphics = TEXT;
    }
}
// write chars
void lcd128x64_write_chars(uint8_t row, uint8_t col, uint8_t *str, uint8_t w){
// row1: 80H~8FH // row2: 90H~9FH // row3: 88H~AFH // row4: 98H~BFH
    if(graphics){lcd128x64_graphics_set_mode(0);}

    if      (row == 1)lcd128x64_cmd(0x80 + (col - 1));
    else if (row == 2)lcd128x64_cmd(0x90 + (col - 1));
    else if (row == 3)lcd128x64_cmd(0x88 + (col - 1));
    else if (row == 4)lcd128x64_cmd(0x98 + (col - 1));

    uint8_t i;
    for(i=0; i<w; i++){lcd128x64_data(str[i]);}
}

////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
// draw functions

// pixel set
void lcd128x64_pixel_set(uint8_t y_axis, uint8_t x_axis){
    uint16_t p_buf;
    if(!graphics){lcd128x64_graphics_set_mode(1);}

    p_block = x_axis / 16;              // calculate x_axis block
    x_axis ^= 127;
    p_pos = (x_axis % 16);              // calculate the position of pixel in 16-bit
    p_buf = (1 << p_pos);               // set the bit

    if(!p_dr_act){
        p_dr_act = 1;                   // set pixel draw activate flag
        y_pre = y_axis;                 // copy y_axis current position
        block_pre = p_block;            // store the first block
    }

    if(block_pre != p_block){           // if block changed
        p_pre = 0;                      // clear global pixel buffer
        block_pre = p_block;            // store new block,
    }                                   // to disable triggering this check

    if(y_axis == y_pre){
        p_pre |= p_buf;                 // put current pixel in global buffer
        p_buf |= p_pre;                 // put previous pixels in local buffer
    }
    else{                               // when changing the row,
        y_pre = y_axis;                 // copy new row position
        p_pre = 0;                      // clear global buffer
        p_pre = p_buf;                  // store the last pixel position
    }

    if(y_axis<32){
        lcd128x64_cmd(0x80+y_axis);
        lcd128x64_cmd(0x80+p_block);
        lcd128x64_data(p_buf>>8);
        lcd128x64_data(p_buf);
    }
    else{
        lcd128x64_cmd((0x80+y_axis)-32);
        lcd128x64_cmd(0x88+p_block);
        lcd128x64_data(p_buf>>8);
        lcd128x64_data(p_buf);
    }
}
// pixel clear
void lcd128x64_pixel_clear(uint8_t y_axis, uint8_t x_axis){
    uint16_t p_msk;
    if(!graphics){lcd128x64_graphics_set_mode(1);}
    p_block = x_axis / 16;
    x_axis ^= 127;
    p_pos = (x_axis % 16);
    p_msk &= ~(1 << p_pos);

    if(y_axis<32){
        lcd128x64_cmd(0x80+y_axis);
        lcd128x64_cmd(0x80+p_block);
        lcd128x64_data(p_msk>>8);
        lcd128x64_data(p_msk);
    }
    else{
        lcd128x64_cmd((0x80+y_axis)-32);
        lcd128x64_cmd(0x88+p_block);
        lcd128x64_data(p_msk>>8);
        lcd128x64_data(p_msk);
    }
}
// draw image
void lcd128x64_img(unsigned char *img){
    uint8_t y,x;
    if(!graphics){lcd128x64_graphics_set_mode(1);}

    for(y=0;y<32;y++){
        for(x=0;x<8;x++){
            lcd128x64_cmd(0x80+y);
            lcd128x64_cmd(0x80+x);
            lcd128x64_data(pgm_read_byte_near(&img[(y*16)+(x*2)]));
            lcd128x64_data(pgm_read_byte_near(&img[(y*16)+((x*2)+1)]));
        }
    }
    for(y=32;y<64;y++){
        for(x=0;x<8;x++){
            lcd128x64_cmd((0x80+y)-32);
            lcd128x64_cmd(0x88+x);
            lcd128x64_data(pgm_read_byte_near(&img[(y*16)+(x*2)]));
            lcd128x64_data(pgm_read_byte_near(&img[(y*16)+((x*2)+1)]));
        }
    }
}

// draw line
void lcd128x64_line(uint8_t y0, uint8_t y1, uint8_t x0, uint8_t x1){
    uint8_t ih,iw,j,h,w,div;
    h = y1 - y0;
    w = x1 - x0;
    if(w>h){
        div = w/h;
        for(ih=y0,iw=x0;iw<x1;iw++){
            lcd128x64_pixel_set(ih,iw);
            if((iw%div)==(div-1)){ih++;}
        }
    }
    else{
        div = h/w;
        for(ih=y0,iw=x0;ih<y1;ih++){
            lcd128x64_pixel_set(ih,iw);
            if((ih%div)==(div-1)){iw++;}
        }
    }
}

// draw circle
void lcd128x64_circle(uint8_t y, uint8_t x, uint8_t r){
    uint8_t py,px,d,f;
    if(y>x){
        //d = y/x;
        f=1;
        for(px=x,py=y-r;px<x+r;px++){
            lcd128x64_pixel_set(py,px);
            if(((px%f))==(r%f)){py++;f++;}
            //if((py%(d%f))==1){px++;f++;}
        }
    }
    else{
        d = x/y;
        for(py=y-r,px=x;px<x+r;px++){
            lcd128x64_pixel_set(py,px);
            if(((px%d))==(d-1)){py++;}
        }
    }
}

This is the function I use in DisplayCore. Feel free to use it.

Considering you already can put a pixel at any position of the display you can try and use something like described here: http://www.softwareandfinance.com/Turbo_C/DrawCircle.html

Yep! Absolutely worked like a charm. But it's a bit slow and uses a relatively big memory .. these lines used 1.7kb of program memory! `double i, angle, x1, y1;
for(i = 0; i < 360; i += 0.1){
angle = i;
x1 = r * cos(angle * PI / 180);
y1 = r * sin(angle * PI / 180);
lcd128x64_pixel_set(x + x1, y + y1);
}`

This is what I got https://i.ibb.co/r4z4pxM/20200120-002911.jpg

@Majenko, that is a nice and efficient algorithm! By comparison the Turbo C example, to be honest, is a waste of processing power. It's not optimized at all (for example, by using symmetry) and uses expensive floating point functions.

@StarCat Yes I know it's a waste of memory! I think it's not for microcontroller stuff. I'm still working on finding the function that would work perfectly with the most optimized memory usage.


text:
Using Arduino Uno as ISP to program Mega 2560
I'm trying to use Arduino Uno as ISP to program Arduino Mega 2560 using this Pin connections (Uno->Mega):
slave reset: 10:       ->        RESET on target
MOSI:        11:      ->           51
MISO:        12:      ->         50
SCK:         13:      ->        52
It runs perfectly when I "Burn Bootloader" from Arduino IDE and LED starts blinking on target. So I assume my pin connections are correct.
However, when I open the Blink example and perform "Upload Using Programmer" in Sketch tab after choosing "Arduino as ISP" in Tools>Programmer it uploads the code but LED on Mega doesn't blink.
I'm afraid that I have problem in my Mega Bootloader hex file and think it's not configuring Pin 13 as a LED pin. But in this case I shouldn't have seen the led blinking after burning the bootloader.
What am I missing here? I appreciate your help.
-Bex

The problem may be related to reset. See http://arduino.stackexchange.com/a/19131/3879

No, I checked the connections and they look fine. I set the RESET pin as D13 in Arduino Uno and don't think it's wrong. Also defined the RESET pin as D13 in the ArduinoISP Example.

When you "upload using programmer" the target board's bootloader is not involved, and I believe it actually gets removed by doing that.

Find the file called "boards.txt" located in your Arduino installation directory. In my case, the path is "arduino-1.6.5/hardware/arduino/avr/boards.txt". Open it with your favourite text editor and locate the ATMEGA2560 section. (not in notepad, it breaks the file format, notepad++ my choice)
in boards.txt

back-up the file incase you break it,
find the line :
mega.menu.cpu.atmega2560.bootloader.high_fuses=0xD8
and change it with :
mega.menu.cpu.atmega2560.bootloader.high_fuses=0xD9

Source : http://soc.ninja/documentation/programming-atmega2560-with-arduino-uno-or-mega/#rating-74


text:
How do you use an Arduino to control a 4 - 20 mA transmitter?
I am using an Arduino Mega to control the speed of an AC pump. This can be done by connecting to the variable frequency drive. Here is a link of the relevant datasheet, pages 66 and 67 relate to what I am doing.
http://www.parker.com/Literature/SSD%20Drives/AC%20Drives/AC650/HA464828U003.pdf
From what I have read and been told already, I should be able to control this using a 4 - 20 mA loop, which is fed into AIN2, as long as I connect the 0V terminal as well?
My question is what is the best way to make a current loop transmitter using an Arduino Mega.
So far the options I have are:

Create a circuit out of discrete components, this would then be controlled using the Megas PWM
Use an IC circuit, I was looking at the AD694JNZ
Use an add on board, I was looking at this one: http://uk.rs-online.com/web/p/products/8828929/?grossPrice=Y&cm_mmc=UK-PLA--google--PLA_UK_EN_Semiconductors-_-Semiconductor_Development_Kits&mkwid=sm9dTYvCc_dc|pcrid|88057061283|pkw||pmt||prd|8828929&gclid=CjwKEAjwk6K8BRDM3aCSkdCtzSQSJAA3Vf38mNs9lZrg2A1AjrVpS3SCubT0AbAr7L8OImUZbfCPzRoCIXjw_wcB

I have a budget for my project so cost is not an issue, however I am running out of time. What would be the easiest method to implement and how?
I have been thinking of using options 2 or 3, however my issues are that this is my first Arduino project. I understand what PWM is but I don't know how I would go about implementing it. I also can't find any tutorials online that demonstrate how to program the MIKROE board using an Arduino.
Thank you in advance for any help :)

I can recommend the Click boards from MikroElektronica (I am the chief engineer porting support for them, and the PIC32-based Clicker development board series, to the chipKIT™ system).
The 4-20mA-T Click board is controlled by the Microchip MCP4921 DAC. This is a common DAC family used in many Arduino projects and there are plenty of libraries around for them (mine is here though it's aimed at the 4822 not the 4921).
Basically you set the DAC output voltage which sets the current output from an XTR116 current loop transmitter.
The XTR116 takes an input of 0 - 4.095v, and provides a convenient 4.095v reference voltage to the MCP4921.

Datasheet for the XTR116
Datasheet for the MCP4921
Manual for the 4-20mA T Click

The whole thing is isolated from your main board through an ADu M1411 to keep everything safe from industrial process noise.

I don't know how I would go about implementing it.

Both option 2/3 require coding - generally simple and doable, even for newbies.
To go down the DAC route, current-feedback DACs are quite common, especially in the good old days. they are ideal here -> make sure your device matches up with the dac in terms of current source vs. current sink.
option 1 is good if you don't like coding. turning a voltage into a current is fairly simple.


text:
Atmega328p clock and safe operation zone
im not used to write in english but i hope you guys can understand. I have some doubts about using the arduino pro mini 3v3@8Mhz

I know its possible to change the clock to 1 MHz with the fuses easily by setting CKDIV8 to '0'. But i dont understand if its possible to divide the internal 8 MHz clock to intermediate values like 4 MHz and 2 MHz.
I know i can divide the clock with program running. The problem is i would like to run the arduino with a voltage less than 2,4V and arduino will start at 8MHz(out of safe operation area) for later change the clock to 4MHz(inside of safe operation area). Is there another way by software to always be in the safe zone ?

Just let CKDIV8 set (it just sets system clock prescaler to /8). And you can set different system clock prescaler later.
For changing system clock prescaler you need:
#include <avr/power.h>

And:
clock_prescale_set(clock_div_2); // possible values are clock_div_1 ... clock_div_256

Just don't forget that millis, delays and basically everything based on F_CPU might be slower/faster when prescaler gets changed.


text:
Sending data via SoftwareSerial results in garbled reception
My overall goal is to have an Arduino Uno with an Ethernet Shield send a short (5-character) string via a SoftwareSerial connection and a UDP packet when I press a button.
The device which is receiving the serial message is fixed at 9600 baud, no parity, one stop bit.
For the purposes of debugging my serial problem I have removed the Ethernet Shield. I mention it above only so that potential responders understand my intended final hardware configuration.
I am using a USB/serial adaptor and Kermit to check the serial output.
C-Kermit>show communications

Communications Parameters:
 Line: /dev/ttyUSB0, speed: 9600, mode: local, modem: none
 Parity: none, stop-bits: 1 (8N1)
 Duplex: full, flow: none, handshake: none
 Carrier-watch: off, close-on-disconnect: off
 Lockfile: /var/lock/LCK..ttyUSB0
 Terminal bytesize: 8, escape character: 28 (^\)

My first job on receiving garbled characters was to test my test rig. I connected the predecessor device and was able to receive the expected characters. (It cannot send the UDP packet, which is why it is being replaced.)
One button on the original device sends "X0401", exactly as expected:
$ od -b oldserial⋅
0000000 000 130 060 064 060 061
0000006

Another button on the original device sends "X0402" (which I expected) and also a whole bunch of nuls, which I didn't expect:
$ od -b oldserial⋅
0000000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
0000020 000 000 000 000 000 130 060 064 060 062
0000032

In any event, it seems that the terminal is actually receiving 8N1 data at 9600, so I can trust what it shows me.
I was going kind of nuts trying to figure out what was the problem, because nothing I sent from the Arduino came through properly. Then I stumbled on a suggestion that 'U' made a good test character because an ASCII 'U' is 0123 or 01010101. Indeed, I am able to send sequences of arbitrary length and so long as they contain only the 'U' caracter, they come through correctly.
(I've got three buttons and three different sets of messages, so my tests tend to run in sets of three attempts.)
Next step is to reintroduce a little bit of variety and see what comes through:
Here I send "UUUUU", "UUEUU", and then "UUQUU". 'E' and 'Q' were chosen because they are each just one bit different from 'U'.
What I saw when I sent the first message was:
UUUUU

Then sent the second:
UUUUUUU]UU

Then the third:
UUUUUUU]UUUUWUU

Kermit was also storing the session to a log file, which looked like this:
$ od -b serialUsequesnce⋅
0000000 125 125 125 125 125
0000005
$ od -b serialUsequesnce⋅
0000000 125 125 125 125 125 125 125 135 125 125
0000012
$ od -b serialUsequesnce⋅
0000000 125 125 125 125 125 125 125 135 125 125 125 125 127 125 125
0000017

Somehow, 'E' (0105) turned into 0135 and 'Q' (0121) turned into 0127. In each case, a sequence of three 0 bits were turned into 011, while no 1 bits were changed.
Sending:
UUAUU

Got me:
$ od -b serialUsequesnce2⋅
0000000 000 125 125 137 125 125
0000006

The five consecutive 0 bits in 01000001 were turned into 01111 to give me 01011111 or 0137
Longer strings get weirder.⋅
Test strings of:
UU0123456789UU
UUABCDEFGUU

Got me:
$ od -b serialUsequesnce3
0000000 125 125 326 266 226 166 126 066 026 366 215 125 125 000
0000016
$ od -b serialUsequesnce4
0000000 125 125 137 257 335 325 315 305 125 125 001
0000013

Now I'm seeing not just bits being replaced, but I'm getting fewer characters than I'm sending.
Since I wasn't getting good data from my SoftwareSerial port, I thought I would listen in on the USB traffic, which is also set to 9600 baud.
This text from the Arduino monitor:
UUAUU
Start button pressed
UU0123456789UU
Stop button pressed
UUABCDEFGUU
Light button pressed

Came through as this:
$ od -b serialUSB
0000000 125 125 137 125 125 171 275 165 324 332 027 277 073 025 027 027
0000020 041 043 277 037 031 031 065 067 345 353 000
0000033
$ od -b serialUSB2
0000000 125 125 326 266 226 166 126 066 026 366 215 125 125 345 353 131
0000020 027 041 037 277 073 025 027 027 041 043 277 037 031 031 065 067
0000040 345 353 000
0000043
$ od -b serialUSB3
0000000 125 125 137 257 335 325 315 305 125 125 225 353 147 055 061 057
0000020 027 277 073 025 027 027 041 043 277 037 031 031 065 067 345 353
0000040 000
0000041

I'm guessing that I'm doing something wrong with the hardware, but my serial connector simply has pin 5 connected to ground and pin 2 connected to digital 6 (or 2 when watching USB traffic).
I'm powering the Arduino Uno via its USB connection. When I checked the voltage at Vin and the adjacent ground, I got 4.51 volts.
/*
Listens on three buttons:
 - Start
 - Stop
 - Lights

Sends serial messages to a Color Kinetics iPlayer 2
9600 baud, 8 data bits, no parity, 1 stop bit
Commands are
 - X0100 Lights Off
 - X0288 Lights at half
 - X02FF Lights at full
 - X0401 Set Show #1

Created 2016-07-13
by David H. Silber
(Cribbing extensively from the Arduino examples.)
*/

#include <SPI.h>         // needed for Arduino versions later than 0018

#include <SoftwareSerial.h>
SoftwareSerial softSerial( 5, 6 ); // RX, TX

const int noButton = 100;
const int startButton = 2;
const int stopButton = 3;
const int lightButton = 4;
bool startTriggered = false;
bool stopTriggered = false;
bool lightTriggered = false;
int lastTriggered = noButton;
unsigned long lastButtonTime = 0;

const char startSerial[] = "UUUUU";
const char stopSerial[]  = "UUEUU";
const char lightSerial[] = "UUQUU";

void setup() {
  // initialize the pushbutton pin as an input:
  pinMode(startButton, INPUT);
  pinMode(stopButton, INPUT);
  pinMode(lightButton, INPUT);

  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("Starting");  // prints hello with ending line break⋅

  // set the data rate for the SoftwareSerial port
  softSerial.begin(9600);
  delay( 1000 );
}

void loop() {
  // read the state of the pushbutton value:
  startTriggered = ( HIGH == digitalRead(startButton) );
  stopTriggered = ( HIGH == digitalRead(stopButton) );
  lightTriggered = ( HIGH == digitalRead(lightButton) );

  if ( startTriggered && (startButton != lastTriggered) ) {
    action( "Start button pressed", startSerial );

    lastTriggered = startButton;
    startTriggered = false;
  }

  if ( stopTriggered && (stopButton != lastTriggered) ) {
    action( "Stop button pressed", stopSerial );

    lastTriggered = stopButton;
    stopTriggered = false;
    }

  if ( lightTriggered && (lightButton != lastTriggered) ) {
    action( "Light button pressed", lightSerial );

    lastTriggered = lightButton;
    lightTriggered = false;
  }

  buttonTimeout();
}

void action( const char usbMessage[], const char serialMessage[] ) {
    Serial.println( serialMessage);⋅
    Serial.println( usbMessage);⋅

    softSerial.write( serialMessage );

    lastButtonTime = millis();
}

void buttonTimeout() {
  if ( millis() - lastButtonTime > 2000 ) {
    lastTriggered = noButton;
  }
}

A friend came and visited me with his oscilloscope and we determined that the 'serial' output from the Arduino was not actually RS-232. It was only an accident that any data came through at all.
I think my answer will be to add https://www.arduino.cc/en/Main/ArduinoBoardSerial or something like it.
One of our realizations was that we needed to level shift the output, searching on "arduino serial level shifter" led me to http://forum.arduino.cc/index.php?topic=18689.0 which in turn led us to the MAX232 chip and boards that provide it.
It would be a good thing if there were some mention in the Arduino documentation that the 'serial' connection one would get from it was not actually RS-232.

RS232 is old. And people have implemented it in many ways.  So we are all bound to have problems with RS232 at some point.  Depending on where you got your RS232 signal from, it could have swung as high/low as 15V / -15V respectively.  So do check to make sure your Atmel processor is still working as expected.  Good luck

Arduino serial is UART 5V Logic. Just in case.

Of course, its not RS232. That protocol defines mark and space voltage levels, as well as other signals to be used in asynchronous serial communication. RS232 does not define the actual signalling protocol used on the TX/RX lines. That protocol is a lot older and encompasses more than RS-232. The Uno is a 5V device and has no built-in RS232 level shifter, so the serial output is directly from its UART peripheral or in your SoftwareSerial case, merely a result of toggling the pins at the desired baud rate. Not unlike digitalWrite().


text:
do i need an I/O shield for quadcopter motors
I would like to know if I need an I/O shield for the 4 ESC's on a Quadcopter I am building using Arduino Mega2560.  The current to the ESC's should come from the battery itself and the data from the board so my first thought is that it is not needed however I wanted to be sure.

What's an I/O shield?

You really do not want to be flying a literal Arduino, especially not a mega - it just means excess weight, bulky awkward connectors, and unsuitable power circuitry.  Even the projects that were once Arduino derived have typically moved on, first to purpose-designed ATmega boards and now to ARM boards.

If the ESC accepts a signal that the Arduino can generate (i.e., 5V PWM) then no interfacing is required.
If the ESC is running from 3.7V (or similar) then some level shifting may be required to reduce the 5V signal to 3.7V, depending on the ESC. That may be built on a shield of some form or just with discrete resistors wired in manually to the leads.


text:
Why does my Arduino freezes when i turn a servo
I have a Servo Motor and an Arduino Uno.
I used the Arduino to run a servo motor. The code was very simple. It was to just Turn it 90 Deg Anti-Clockwise when a switch is pressed and Turn back to its original position (90 Deg Clockwise).
The servo had 3 pins.
 1. V+
 2. Ground
 3. Data
I connected the V+ to the Arduino's 5v Output. And the Ground to the Arduino's GND pin. I connected the Data to Digital Pin 3.
When ever this script runs, The servo turns a little and then stops. It stops because the arduino froze and It wont do anything. I pressed the Reset button and it does nothing. I plugged off the Servo and the Power Supply and replugged the Power and it works.
The power source was a battery pack with 4x 1.5 Volts batteries in it. Maybe there was a problem with this?
Do anyone know what might be the problem here? Any Answer will be Appriciated. Thanks.

Can we get a schematic and your code? Might be something in the code.

Also, does this occur every time you run it? Is the problem reoccurring?

Which servo motor are you using? Do you have the spec, or at least an exact model name?

1.5V battery cells have little current capacity; try running off the same code and arrangement using a bench supply.

You said that you were using 4x 1.5v batteries. That would make a total of 6 volts. The current that those batteries can supply is also little.
The Recommended Input Range is 7-12 volts. And the Limit is 6-20 volts.
You were supplying it with 6 Volts which is at the very limit of the Input Voltage Range. When the motor runs, the Voltage might have dropped and made the arduino freeze.
The fix is to supply the arduino with another source such as a benchtop supply that can supply more than 8 volts.


text:
Which LCD Pins, if any, require PWM?
In the Arduino Tutorial Page named "Hello World" aimed to help people connect a 16x2 LCD Display compatible with Hitachi HD44780 driver to an Arduino Uno. The pins used to connect the Arduino Uno and LCD Module are as follows:

LCD RS pin to digital pin 12
LCD Enable pin to digital pin 11
LCD D4 pin to digital pin 5
LCD D5 pin to digital pin 4
LCD D6 pin to digital pin 3
LCD D7 pin to digital pin 2

Pins 3,5 and 11 are connected to PWM Pins, however, I'm wondering if they actually need these PWM capabilities or does this tutorial just pick random pins and the LCD's D6, D4 and Enable pins doesn't actually need the PWM capabilities available of these pins.
I'm asking this as I'm considering on using an Arduino Mega for my next project and it would be much easier and neater for all the pins of the LCD to go onto the digital pins instead of some being on the digital and others on the PWM pins.

you are overthinking it. PWM is an additional capability of the pin. all gpio pins of Uno and Mega are digital pins. of course the LCD libray doesn't use PWM

Likely all programmable pins on modern embedded processors are able to perform digital I/O.  In addition, many can also perform other tasks such as PWM, or Analog to Digital Conversion (ADC).  This is true for many of the different processors used on different Arduino boards.
Often, the nice people who write the C++ driver class of programs or Arduino Libraries offer the user the ability to change pin assignments used by the Arduino Libraries when instantiating an instance of the driver.  This is true for the LiquidCrystal driver in the tutorial in the question.  This can be an advantage as processor's resources are limited.  For example, if you need PWM controlled pin to dim LEDs, you can move LCD controlling pins to other non-PWM pins.
The LCD specified in the tutorial linked to in the above question uses a common Hitachi HD44780 interface.  Such assemblies only need embedded processor Digital I/O pins for control.  Had the LCD no electronic driver, the segments need to be directly driven by very low alternating current (AC).  This is difficult for embedded processors.  However, it may be possible using enough PWM pins and some clever software & hardware.

Too many words.

PWM is not used on those pins for the LCD operation. You can choose more convenient pins as long as they are general purpose pins. For example, not A/D input only.
(I thought you might appreciate a short clear answer)


text:
What is the Maximum Current an Arduino can Supply?
I was wondering how much my Arduino I/O pin can output when it is set at Output and is at High.
I am using an Arduino Uno R3.
Thanks in Advanced.

@brhans Alright, Gonna move it there

@brhans but it seems to have an answer already. So i think im just gonna keep it here

40.0mA.
The Arduino UNO Digital IO pins are connected directly to the IO pins on the ATMEGA328P processor.
From page 299 of the data sheet for that processor...

Note that there is also a total current limit for all output pins combined, and that the voltage starts to drop as the current goes up.

You should probably note that it's never a good idea to go anywhere near the "Absolute Maximum Ratings". Perhaps include the notice that's referred to by the asterisk on that page in the datasheet.


text:
analogRead returning 0 constantly when connected to joystick
What reasons could there be for a joystick to return 0 when using analogRead?
X-pin is connected to AO and y-pin is connected to A1.
VCC is connected to 5V and GRND is connected to GRND.
By default (as in when not using the joystick) the value should be approximately 500, right? Well why is the value then 0? Can this only be a wiring issue?

What value do you get when you move the stick? Maybe 0 just means centre and then when the stick is moved you get -90 and +90 (or something like that)?

It doesn't go below 0 at any point, however it does increase by 2 or so when moved up/right

Moving just 2 sounds like electrical static and that the joystick is not working or not powered correctly. Have you set your arduino analog pins as INPUT?

thank you... I changed the wiring a bit and it worked :)

For a question like this you need to a) check your joystick out of circuit with an ohm meter and confirm the values that the pots are producing, and b) describe (ideally with a schematic) the exact circuit you're using. Note that as it stands this isn't a very good StackExchange question because it's unlikely to help anybody else. Going back and filling in the details might get you some upvotes.

Follow these steps to identify the problem.

Disconnect A0/A1 from Arduino and use a multimeter to check the voltage coming from the joystick X and Y. If it swings from 0 to 5V....the problem is in the Arduino. Check your code and connections. Maybe your wires are damaged?
If the voltage is not changing at X and Y pins, disconnect power from the joystick and use a multimeter to check the joystick potentiometer. Check all three terminals in each axis of the joystick. If R is the measured resistance between the two outer pins, then the resistance between the central pin and each of the outer pins should vary from 0 to R depending on the position of the joystick.
If there is no problem at all with the joystick readings by potentiometer then the problem has to be on the Arduino side.

Adding an answer after clarification:-
Moving the joystick also failed to produce a valid reading which indicated a wiring issue or incorrect configuration of the Analog pin in the Arduino code.
Proven to be a wiring problem


text:
Arduino + DS18B20 array
I want to connect 24 DS18B20 sensors to arduino by onewire library in the same digital pin .
Can anyone post an example code ?
Thanks

Use the OneWire and the DallasTemperature libraries. They are both in the Arduino IDE in the Library Manager.
The DallasTemperature library has the example "Multiple". You need to make an array of DeviceAddress.
To tell them apart, you have to label each temperature sensor with its device address (a unique identifier inside each DS18B20). Therefor you have to connect them one-by-one and write down the device address.
Start with one sensor, and if that works, try to make arrays.
For 24 temperature sensors, you need a lot of wires. That could make it less reliable. You can use two or three or more pins as well. Then you have to create more than one "OneWire" bus in the sketch.
There are many examples for multiple DS18B20 sensors. For example this one is with an array: Arduino forum: "multiple temp sensors ds18b20".


text:
Sending data from Arduino to laptop via bluetooth using java
I intend to establish communication between my laptop and Arduino via Bluetooth. I'm using BlueCove Java API. I'm unable to understand how to send data to Arduino using this. There are no clear examples available on the internet regarding how to establish the communication between these two. Could somebody provide any information on this?
I just want to send some string to Arduino, based on which it must send back something to the laptop. Any help on this would be greatly appreciated. Thank you.

I was able to establish bluetooth communication between Arduino and my laptop successfully. I made some observations, which I'd like to share. BlueCove library which I've been using, ultimately communicates to the Arduino by constructing a bluetooth URL. This bluetooth URL is of the form btspp://bluetooth_address_without_colon:1;authenticate=false;encrypt=false;master=false.
To find the bluetooth address of a device, enter the following command in the terminal
hcitool scan

This will display a list of devices along with their addresses.
For instance, if my HC-05 has an address  20:16:10:09:47:93 then the bluetooth URL can be formulated as
btspp://201610094793:1;authenticate=false;encrypt=false;master=false.
Note that the '1' here represents the rfcomm channel. By observation, I've found that HC-05 modules use rfcomm channel 1.
In your project, ensure that you import the two jars of BlueCove libraries viz bluecove-2.1.0.jar and bluecove-gpl-2.1.0.jar (latest version). You can download them from here.
This is the Java code for communicating with the Arduino to turn an LED ON/OFF:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.bluetooth.DeviceClass;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.DiscoveryListener;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.RemoteDevice;
import javax.bluetooth.ServiceRecord;
import javax.bluetooth.UUID;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
public class HC05 {
boolean scanFinished = false;
String hc05Url =
"btspp://201610094738:1;authenticate=false;encrypt=false;master=false"; //Replace this with your bluetooth URL
public static void main(String[] args) {
try {
new HC05().go();
} catch (Exception ex) {
Logger.getLogger(HC05.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void go() throws Exception {
StreamConnection streamConnection = (StreamConnection)
Connector.open(hc05Url);
OutputStream os = streamConnection.openOutputStream();
InputStream is = streamConnection.openInputStream();
os.write("1".getBytes()); //'1' means ON and '0' means OFF
os.close();
byte[] b = new byte[200];
Thread.sleep(200);
is.read(b);
is.close();
streamConnection.close();
System.out.println("received " + new String(b));
}
}

This the Arduino code for controlling the LED:
int ledPin = 13;
int flag = 0;
int receivedData;
void setup() {
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
Serial.begin(9600);
}
void loop() {
if(Serial.available()>0){
receivedData = Serial.read();
flag = 1;
}
if(flag == 1){
switch(receivedData){
case '0':
digitalWrite(ledPin, LOW);
Serial.println("LED Turned OFF");
break;
case '1':
digitalWrite(ledPin, HIGH);
Serial.println("LED Turned ON");
break;
default:
Serial.println("Nothing here");
break;
}
flag = 0;
receivedData = 12;
}
Serial.flush();
}

Thanks to @Sigma for sharing some valuable information
Reference:
https://stackoverflow.com/questions/33473926/best-practice-java-serial-bluetooth-connection-hc-05

Are using a bluetooth module like HC-05 or HC-06? Then first establish an connection to the module. Then start sending bytes(a string). But first thing first start the connection. Ive only done it with an Android to Arduino, but still the Android is written with Java.

Yeah, I'm using HC-05. I've been able to detect it by using the BlueCove library. I referred the code from here http://snapshot.bluecove.org/bluecove/apidocs/overview-summary.html#DeviceDiscovery. But, I have no clue what to do after this. I'm a beginner in Java.

I followed this one Github repo bluetooth Android, I understand that it isn't exactly Java but found a similar ex in Java with almost the same code, they follow the same practice. Open bluetooth, find the device-history of paired BT, set up an socket to that device, start sending and reciving message. Or else there is this one on SO link

The SO link worked out. It wasn't direct though. First I ran the Service Search program from here, and found out the url of my HC-05 device, after getting bombarded with exceptions few times. After that, I used that URL directly and sent data to the Arduino via bluetooth. But, while receiving data from Arduino on my laptop, there's loss of bytes. I send "LED" from Arduino, and end up receiving only "L". Thanks

Do you have a example code from Arduino and PC? Could be that your Read-method isn't running more then once. Are you sending the message from the Arduino, can you verify that? Are you using SoftwareSerial on Arduino? What BaudRate is everything running on, 9600-115200? Anyway you are doing progress, there is communication. Lets debug, is the problem on Arduino or PC?!

I'm running the Arduino code program from the SO link that you gave. I modified the code by just removing the delay(). I added a sleep of 200ms in my Java code after writing the request to Arduino. 200ms was enough for the Arduino to process my request. Then I read from the Arduino. This time it worked out well. But, I'm not sure if using Thread.sleep() is advisable in Java. I read somewhere that sleep() must be avoided.

I was successful in achieving bidirectional communication: PC to Arduino and vice versa. I didn't set any Baudrate in my Java code. I think it's taking 9600 by default. At the Arduino end, I set 9600bps. No, I didn't use SoftwareSerial on Arduino. I'll share the code and the method, once I optimize things. Whatever I did was not systematic. I need to make it systematic, so that everybody can understand. Thank you so much for providing the help.

You are awsome man! Hade the same problem and found out that thread.sleep(100) on the smartphone help me. Yes 9600 is default, you can change that by AT-commands to the HC-05. One thing to keep in mind is there shouldn't be any blocking code on the Arduino-side, it need to be flawless and always running. Read this a couple days ago, this awsome man explained what to use and what you should avoid in Serial communication. This is our bible now.

Thank you for sharing that link. It contains valuable information. Very soon, I'll be posting the shortcut that I've found.

I've posted it as answer. Hope it helps someone in future. Thanks for your help mate.


text:
Arduino to Beaglebone black
I have an Arduino uno3 which gets data from a digital caliper and shows the data in serial monitor. Now I should make a connection between this Arduino and my Beaglebone black through SPI to get the data sent from caliper in Beaglebone black. and I don't know what to do and how to create codes related to this purpose.

Have a look at the first several links from googling for Arduino and my Beaglebone black through SPI.  Here are a few comments on those first few links:
• SPI - Beaglebone Black Master Arduino Uno Slave (forum.arduino.cc topic 446924.0) – This page asks your question in more detail, and includes Beaglebone master code and Arduino Slave code.  However, the poster makes an egregious error in the Arduino code by saying Serial.println("SPI"); within the SPI interrupt service routine.
• Communicate Beaglebone Black and Arduino via SPI
(ulasdikme.com) – This page addresses your question in rather more detail, and apparently shows working code.  It also explains how to enable SPI in the Beaglebone device tree.  Note, this poster too makes an egregious error in the Arduino code by saying Serial.println(c); within the SPI interrupt service routine.
• SPI communication: BeagleBone Black (as Master) to 4 Arduinos (as Slaves) (adurthi.com) – This page covers level shifting and device tree setup and provides ok code.  It seems to cover BeagleBone concerns nicely, and has ok Arduino code as well.
One or two of the above also make reference to Nick Gammon's excellent SPI pages:
• SPI - Serial Peripheral Interface - for Arduino (gammon.com.au forum id=10892) – This page is where you should start if you have questions about how SPI works.  After you are familiar with SPI basics, scroll down to the “How to make an SPI slave” heading, and set up the master-slave example with two Arduinos.  When you have that working, you can substitute or add a BeagleBone as master.  Other code examples further down the page include  “How to get a response from a slave”, slave SS pin interrupt examples, SPI via USART, speed settings, SPI on ATtinys, sending data structures, and (under the heading “SPI under IDE 1.6.0 and later”), exegesis of SPI library methods.
• Debugging using SPI/I2C and a second processor (gammon.com.au forum id=11329) – This page illustrates master-slave communication between two Arduinos, using one as a slave to forward information sent from a system being debugged.  Also illustrates use of I2C for similar purpose.  Note, Debugging The Arduino With The SPI Interface Instead Of Serial.println() (utopiamechanicus.com) is a follow-on article, by another author, about this debugging technique.


text:
From Exploring Arduino Text
I am working thru the Exploring Arduino text mostly with success up until chapter 4. I have most of the parts required but for Figure 4-3 I used the following:
100nF Capacitor, (In place of 1uF Capacitor)
1N4007 Diode Rectifier, (In place of 1N4004 Diode)
S8050 NPN Transistor, (In place of PN2222 NPN)
DC Motor rated for 3V with a Reference Current of 0.35 to .4 Amps (Text lists "DC Motor")
Im aware that the Capacitor was undersized, Diode was a 4 series (so I assumed it was compatible), and the Transistor also the same but of a different manufacturer. Im also aware that the motor is underrated compared to the 9v input, but I didnt think this would cause a problem for a small time period.
My problem is that after about 10 seconds of running (both with the motor free spinning as intended, and sometimes just staying put but making a high pitched noise) the bread board started smoking. So, I disconnected everything and gave up for the day.
What was it that caused the breadboard to start smoking? Do you think I damaged my Arduino?
Link to companion site with diagrams: http://www.exploringarduino.com/content/ch4/

the parts sound fine, you probably hooked something up wrong. i've never seen smoke from something that continued to work perfectly after. if you gave a 3v motor 9v, then anything in it's path is probably damaged; the lower-voltage motor drew several extra watts over design.

Thanks for the reply, im pretty confident that I wired it correctly, i guess i can give it another try. Should i replace the motor with a higher rated one?

If you used the 9 V battery as described in the diagram, but with a 3 V rated motor, then the motor starts smoking and you might damage it. Use e.g. 2 AA batteries with 1.5 V instead of the 9 V battery, then it should work without smoke and your motor will survive much longer.


text:
RGB LED Resistance
In tutorials I've seen, people connect every LED of a RGB LED to a resistance. I understand the purpose, but could we simply put the same resitance once, if we connect it to the common cathode or annode?
Example:

It won't cause any damage, but it has some negative sideeffects like BartmanEH explained. Why not try it out youself, and see what happens if you e.g. connect both red and blue at the same time. You'll learn more by trying.

For a detailed explanation see Why exactly can't a single resistor be used for many parallel LEDs?

The problem with one resistor in common anode/cathode is that when you activate more than one colour of the RGB LED, you will have additional current flowing through the one resistor which will cause increased voltage drop across the one resistor due to ohms law which will cause less forward voltage across the LED and likely extinguish it or at least make it much less bright.

So if I want to turn one at a time it's ok?

Yes, if you only need one colour activated at a time, then it would be ok to have just one resistor.

Ok thanks, will wait to have other feedback before accepting it!

See Why exactly can't a single resistor be used for many parallel LEDs?. However if you only ever turn one on at a time, it should be OK as the answer says.


text:
Link Arduino Uno to Particle Photon
I'm working on a prototype with a Particle Photon, but I've realized the required number of pins is bigger than the number of pins on my photon.
I thought I could have an Arduino Uno wired to some sensors, and link the Arduino to the photon via a Software Serial from the Arduino (as its serial pins will already be busy) to the Serial pins of the photon.
Is it possible, and is there a better way to solve my problem?

https://www.particle.io/

If you just need to get more inputs you could use multiplexing. The multiplexing method is more robust than software serial will be. How to do this is explained here and datasheet for the commonly used cd4051 here
You don't specify what kind of sensors you will use. if the sensors are i2c or similar it is possible to daisychain (multiplex too) them.

Everything is possible, it is programming. People are doing software-only USB on AVRs.
I doubt that the effort is worth it, given how hard it is to debug such low-level code. Besides you can use on-board UART if you don't need the USB connectivity - just disable it.
Main question is - where is the main software run, aka "Who's the Brain"? If Photon, maybe you can use SPI? SPI is dead-simple to emulate in software.

The photon is the brain, the Arduino would provide me with more pins

The USB of the Photon will already be used, do I have options other than softSerial?

Photon has SPI. Arduino Uno has SPI.
Photon has I2C. Arduino Uno has I2C too.
Programming them will be easier than software emulation of UART. I'd try SPI.

Oh, I didn't know this protocol. I'll definitely take a look!

I2C looks very interesting also, especially the fact that it uses only 2 pins and still works with a small voltage difference (5V vs 3.3V)

Yes, I2C is nice to wire, but it's relatively complex to program. SPI is simpler to program than UART, but requires more wires (4 vs 2).

authors: Виктор Багрий


text:
Arduino UNO Rx/Tx speaks to itself
I'm trying to make my chinese arduino (which use a chinese CH340G chip) speaks to itself via serial.
I have wired rx/tx together.
Then, I run the arduino IDE and go to the serial monitor.
When I write a message, the arduino should respond with the exact same message, right ? Actually, when I write a message, the arduino doesn't respond anything...

Please see for instance http://arduinobasics.blogspot.se/2012/07/arduino-basics-simple-arduino-serial.html

please re-read my question, I don't want to use any software, I have put a physical jumper between rx and tx pin

You cannot use the same serial port to have the Arduino speak to the computer and speak to itself.

well in fact I have read that the arduino uno only have 1 serial port and that this port is shared between the computer and the serial pin on the arduino... Isn't that right ?

This will depend on the bootloader and which state it leaves the port at.

could you be more precise? talk to me like I'm 5 ;)

is there a sketch running on the board (blink?)

no, just an empty sketch

@MikaelPatel: The Uno bootloader (optiboot) leaves pretty much everything in the initial, after-reset state: USART disabled and its pins as high-impedance inputs.

I checked the init() and it will puts PORTB to all input. So that is not the issue. The RX might require a pullup when in loop-back?

TX is an output (DDD1 overridden) when the UART transmitter is active, so no need to pull up.

Found this Russian web-page that had schematics for an UNO with CH340G. A closer look shows that there are a few 1K ohm resistors in the way (voltage divider for the RX/TX LEDs). http://jarick.com.ua/%D0%B2%D1%81%D0%B5-%D0%BE%D1%81%D1%82%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5/25-%D1%81%D1%85%D0%B5%D0%BC%D0%B0-%D0%BA%D0%BB%D0%BE%D0%BD%D0%B0-arduino-uno-r3-%D0%BD%D0%B0-atmega328-%D0%B8-ch340g.html

I have put a physical jumper between rx and tx pin - to clarify, you jumpered together digital pins 0 and 1? Not some other place?

yes exactly http://i.imgur.com/ZtG2IEl.jpg

As Mikael Patel pointed out in his answer, you have set up a voltage divider. Mikael has thoughtfully provided a schematic of the clone Uno, where the relevant part is here:

Equivalent circuit
If you jumper together pins D0 and D1 (Rx and Tx) on the Uno effectively you have made this circuit:

Testing
If I set up this with a function generator, I get this result:

You can see that for a square-wave input of 0 to 5V, we only get an output of 2.16 to 5V.

What is LOW?
Now looking at the datasheet for the DC characteristics we see:

For an input to register as LOW it has to be no higher than 0.3 * Vcc = 0.3 * 5. Thus the voltage cannot be higher than 1.5V. Since we are measuring 2.16V, that will not count as a LOW.
Now admittedly that is for the Atmega328P and not the CH340G, but it will probably have similar characteristics.
I found a datasheet for the CH340G, and that shows even stricter requirements for a LOW signal:

Official Uno
Comparing to the official Uno circuit:

You will note there that the indicator LEDs are on a different circuit, and thus do not form a voltage divider.

The Maths
The clone Uno circuit above can be re-arranged like this:

Given that the LEDs have a voltage drop of 1.86V (measured in practice, and about right for the red LEDs I am using) then effectively we have the resistors R1 and R2 connected to 3.14V.
Since they are in parallel they are effectively 500 ohms.
Now using the formula for voltage dividers:
1000 / (1000 + 500) * (5 - 1.86) = 2.09V

This is close enough to the observed result. I didn't check each resistor to make sure it was exactly in spec.
I don't think R4 affects the results because it is effectively "floating".

Great job, Nick! You filled in the blanks and added yet a level of engineering (again). Thanks! Hope others appreciates your knowledge sharing.

Thanks, @MikaelPatel. There is one thing I'm not happy with, I can't make the maths work out. I am measuring a voltage drop of 1.86V over the LEDs with the 1k resistor.

If I remove the D2 LED then I measure 1.567V which agrees with: 1000 / 2000 * (5 - 1.86) = 1.57

I think I worked the maths out, see amended answer.

After some research I found the below schematics of an Arduino UNO with CH340G. A loop-back is not possible as there is a voltage divider (1K ohm, i.e. RX/TX LED) resistors on the RX and TX line.

Tested on a Chinese Arduino Uno clone (VISduino) with CH340G and just as you wrote a loop-back does not work. Tested also an Arduino Mega 2560 clone with CH340G and a Duemilanove clone with FTDI. Both these work just fine.
Cheers!

Thanks for your research :) so it means that a message which come through the RX pin can't go to the usb because of this resistor, right ?

Nja, if you look at the circuit and add the loop-back connecting pin 0 and pin 1. The TXD signal from the CH340G has to go though 1 K and then back through another 1 K to the RXD on the CH340G. The TTL signal is not low enough after that (my guess).

My loopback test does work.

@EdgarBonet  Your loopback test on an Arduino Uno clone with CH340G does work?

No, it's a real Uno, but the RX and TX are wired almost the same as in your clone, with the same 1K resistors.

There is no problem doing a loopback on an Arduino Uno, but you cannot
use the serial monitor at the same time. I wrote the following test
program, which works as expected:
const int LED_PIN = 13;

void setup() {
    pinMode(LED_PIN, OUTPUT);
    Serial.begin(9600);
}

void loop() {
    uint8_t data = random();
    Serial.write(data);
    while (!Serial.available()) { /* wait */ }
    if (Serial.read() == data) {

        // Two short pulses = success
        digitalWrite(LED_PIN, HIGH);
        delay(100);
        digitalWrite(LED_PIN, LOW);
        delay(100);
        digitalWrite(LED_PIN, HIGH);
        delay(100);
        digitalWrite(LED_PIN, LOW);
        delay(700);
    } else {

        // One long pulse = failure
        digitalWrite(LED_PIN, HIGH);
        delay(500);
        digitalWrite(LED_PIN, LOW);
        delay(500);
    }
}

There are, however, two caveats with this naive program:

the loopback wire has to be removed before uploading
after connecting the wire, the Arduino has to be reset to get out of
the while loop.

This is loop-back on the Arduino side. I think the OP was referring to loop-back on the USB side. It is a good answer but maybe not the right question.

yes Mikael Patel is right.

@MikaelPatel: Oh, now I see your point. Since the OP said he wanted to “make my chinese arduino speaks to itself”, it seemed to me he wanted to loop back the Arduino side. I also assumed he did not understand that having two TX talking on the same line cannot work.

the capacitor on pin 4 is connected to GND not to +5V

Not on the schematic provided by Mikael Patel. In any case, this doesn't answer the original question.


text:
Send analog value over IR?
for my rc robot I want to use ir to send/receive the value from a jostick.
Is it possible ? I can't use any other radio chip like nrf24l01.

Yes. It's possible.

documentation ? library? website?

I don't know any of those. I know it is technically possible though, which is what you asked. Maybe Google knows where the websites are?

Yes, it is possible. That is already supported by the IR library. Please see this tutorial for further details. The outline of the sender is:
 uint16_t sample = analogRead(A0);
 irsend.sendSony(sample, 16);

And the receiver:
 if (irrecv.decode(&decodedSignal)) {
    uint16_t sample = decodedSignal.value;
    ...
 }

Cheers!


text:
Extract binary data from text string. Like Perl pack, not just regexp
If I have data coming into an Arduino in an ASCII serial format from some external device (or from a PC, or whatever) and I want to extract binary values from that data and log it or put it on a little display or react to it or whatever there are a few ways I can do it. But it seems like there should be a reversed version of sprintf, mashed up with regexp, mashed up with Perls pack/unpack that would make it easy and configurable.
For example, let's say I'm getting hex numbers from a data logger. something like
c,03,1234,5678,9ABC
where c is just a code telling me this line is channel data, there are 3 channels installed, and then there are the 3 sets of data. I can use split or something like that and then extract the values, convert the hex to binary, apply Y=mX+B and display the channel readings. If a channel goes flat, I can sound an alarm, etc... No worries.
But then I have a different data logger plugged in, and this one uses a different format. Like decimal raw ADC counts. It spits out
2342 1313 234236
Now I gotta recode.
But wait, what if I just had a regexp in eeprom and I used that to extract the data? Something like /^c,\X+,(\X+),(\X+),(\X+)$/ for the first logger and /^(\d+) (\d+) (\d+)$/ for the second. That would be really cool because I could pretty much extract data from any serial device for local display. No need to reprogram, just update the regexp. And there is a nice regexp library:
https://github.com/nickgammon/Regexp
although it uses the LUA regexp syntax.
Oh, but that won't work... because although my program in the Arduino gets back 3 values from the regexp, it doesn't know that the first set are hex strings, and the second set are decimal.
Now, if I was doing this in Perl, I'd just apply a pack string to the binary data. But then pack can't reject a bad match, it always returns a result, even if the input wasn't valid.
Doesn't it seem like the regexp should be able to return /binary/ values instead of just the string? It knows those values are hex. And shouldn't pack be able to do matching against the other characters in the string and reject the value if it's not a match?
Seems to me like there is a hole in our standard libraries. Something that does both simple matches, and converts data to binary return values on the fly.
Or is that too much to ask from an engine? Perhaps few people would use it; better to just hardcode for the rare times you need something like this?

atoi(), strtol(), etc see https://stackoverflow.com/questions/20654424/atoi-from-hex-representation-string also https://stackoverflow.com/questions/33662818/arduino-serial-read-and-parse-hex

Something that does both simple matches, and converts data to binary
  return values on the fly.

You are describing sscanf(). It is way less powerful than
regexps when it comes to pattern matching, but it seems to closely match
your requirements.
Dummy example:
const int FORMAT_COUNT = 2;
const char * formats[FORMAT_COUNT] = {
    "c,%*x,%lx,%lx,%lx",  // first data logger
    "%lu %lu %lu"         // second data logger
};

// Here goes the data.
unsigned long channels[3];

// Try to parse using all the known formats.
void parse(const char *message)
{
    for (int i = 0; i < FORMAT_COUNT; i++) {
        int ret = sscanf(message, formats[i],
                &channels[0], &channels[1], &channels[2]);
        if (ret == 3) {
            Serial.print("Message \"");
            Serial.print(message);
            Serial.print("\" matched with format \"");
            Serial.print(formats[i]);
            Serial.println("\"");
            return;
        }
    }
    Serial.println("Could not parse message.");
}

Sample output:
Message "c,03,1234,5678,9ABC" matched with format "c,%*x,%lx,%lx,%lx"
Message "2342 1313 234236" matched with format "%lu %lu %lu"

Perfect! Thank you! I actually knew about scanf but didnt realize it was that powerful.

Yes, but it doesn't really know something is hex. What about the patterns:
[\dA-F]
[0-9A-Fa-f]

And so on. The regexp library is simply a way of extracting out substrings of a target string. It doesn't make a heap of sense for it to try to auto-detect the type of the returned string. For example, a GUID might be a lot of hex digits. Do you want something like 182676d07497c511f850 to be somehow converted into binary? And then what? Compressed into an int?
In fact it doesn't return (decimal) numbers anyway, it returns a string which may or may not be convertible into a number. Chris Stratton's suggestion of using atoi, sttol and so on is the logical way to go. Just have a flag in your EEPROM that tells the decoding routine what format the input data is. Also, for simple string sequences, don't forget strtok.


text:
WiFi Password Safety
Are there any best practices regarding password safety?  The following is taken from a wifi tutorial sketch.
#include <SPI.h>
#include <WiFi.h>

char ssid[] = "yourNetwork";      // your network SSID (name)
char pass[] = "secretPassword";   // your network password
int keyIndex = 0;                 // your network key Index number (needed only for WEP)

While I accept that the tutorial is there for learning how to use the shield, I would assume hard coding the password into the sketch leaves this open to attackers.  Is this actually the case?  If so, are there any strategies to harden the sketch, for example with encrypted storage?
I am a relative newbie with physical computing and Arduino, so sorry if I am overlooking something obvious.

Any system which needs to communicate a password between an MCU and a standard wifi module in cleartext is readily open to attack by anyone who has physical access just by sniffing the serial, spi, or whatever channel in between them.  The tools to do so sell for $6-24.

You'll have to physically secure the Arduino device, as the attacker has to have physical access to the Arduino to get to the password. In corporate environments, they would set up a separate wifi network, with a firewall, to reduce the risks when that network is compromised.

On the avoiding hard-coding front, I just found this: https://www.instructables.com/id/Avoid-Hard-Coding-WiFi-Credentials-on-Your-ESP8266/
It basically creates its own network to address the bootstrapping issue. Which makes this a nice way to package a device for someone else to use, too.

I'm not as concerned about someone hacking the hardware on my desk to get the Wifi password. I'm concerned about the code-sharing implications of hard-coding a password into the source. Is there a way to read from environment variables instead of hard-coding for example? Then I can share my sketches on github without concern.

You're actually entering into a very tricky and difficult area.
Yes, having a plain text password in your sketch is a risk. It is stored in flash as plain text. If an attacker can gain access to the contents of the flash through some means (whatever they may be) then they could obtain that WiFi password.
You would think that encrypting the password would be the answer, but that's not the case. The problem with an encrypted password like this is it has to be decrypted to use it. That means that both the encrypted password and the encryption key are both stored together in flash. If you can get one you can get the other, and thus the encryption is null and void.  Encryption security relies on keeping the encrypted data and the key used to encrypt/decrypt it completely separate. After all, you don't leave the key to your house in the front door lock when you go out, do you? It's exactly the same.
So what do you do?
Well, there's lots of different ways of looking at security. In this case there is one specific viewpoint that works best:
Security Through Obscurity
Your system is (pretty much) unique. Nobody but you knows just what it does and how it does it, or how you interact with it. It's not obvious to the casual observer just what it is or what could be done with it. That means that they won't know how to break in to it.
The majority of use of vulnerabilities in systems rely on those systems being ubiquitous - that is, all over the place; easy to obtain. In short, easy to find out what they are, how they work, and even reverse engineer them to a certain extent. Attackers aren't going to be able to do that with your system, since you are the only person in the world with it.
However, it's far from perfect, and you shouldn't rely only on Security Through Obscurity.
Simple obfuscation of the password (not actual encryption, but just storing it in a way that isn't obvious) can help, since it isn't then easy to see where in a memory dump the password would be. Splitting it up and scattering it around the place, too, can be useful.
Basically there is no simple answer, other than make it as hard for an attacker to find sensitive things as possible and don't tell anyone what you have done to hide it ;)

Level-up to Majenko for the thorough breakdown. I've seen some crypto libraries for arduino, and your only concern is the key for your string. I have used some bits unique to systems (and which could be grabbed from C, once just a username and hostname) when I had to obfuscate strings, but I don't think that's a good practice. If attackers (who attack your arduino, inside your house perhaps?) dump its memory, you probably have bigger problems which require a shotgun. But if you insist, I recommend finding some bits unique to the mcu (serial number perhaps) and XOR'ing the wpa key with that.

Unfortunately, I don't have a precise answer to your question currently, but I would like to warn you about the Security Through Obscurity approach proposed by Majenko.
This approach may be reasonable for something very homemade, but it is strongly discouraged by researchers and experts.
For instance, if you have a look at the Guide to General Server Security you will read between the "Server Security Principle":

Open Design—System: security should not depend on the secrecy of the implementation or its components.

So, try always to use a standard approach if you can.


text:
How I can use more than 64 analog in arduino
Hi dears
I want help I’m in begging in programming. I want use more than 64 analog pin for ldr photoresistor in single reading. Because I can’t   use digital pin 0-1.
Any methods I can use ,,,,
And How??

what are you trying to do? .... Because I can’t use digital pin 0-1. ... why do you say that? ... how would that give you 64 analog inputs?

Which Arduino? I don't know of any that have 64 analog inputs to start with. I agree with jstotola. What are you trying to achieve? This sounds like an X-Y problem.

You basically have 2 ways to do this:

You can use multiplexer chips, which are capable of carrying analog signals. Then you can connect the multiplexers to an analog input and the inputs of the multiplexers to the LDRs. Each multiplexer gets controlled over multiple digital pins (depending on the exact chips; it may be good to find one with a serial interface like I2C) and connects the analog input with one of the LDRs. Which one depends on the control inputs.

You can use external ADCs (Analog Digital Converters, like the one in the Arduino). These are normally controlled over a serial interface (like I2C) and give you multiple analog inputs at once. For example this board from adafruit, which gives you 16 analog inputs and is controlled over only 2 lines (I2C, A4 and A5 on an Arduino Uno/Nano). This is probably a simpler way, though for a higher cost. If you want to to cheaper than the linked board, you may wanna use blank ADC chips instead of a breakout board.

Thanks dear you can help me more which the best and easier one,, and if you have an example for that.

Besr and easiest ist probably using the ADC board from adafruit. Are you willing to invest that much?

I've just built a board that allows an Arduino to access 192 analog inputs - one at a time of course. More is possible. It uses 4067 16 x 1 analog mux chips. A single 8 bit port controls it.
Need a schematic?

Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.

My page about multiplexers gives some details about this approach.


text:
Uno R3's a4 and a5 not working after installing itead SD Shield 3.0
I'm working on a data logging project and would like to use all six analog inputs on my Arduino Uno R3.  I've been able to get everything working, including writing to the SD card.  However, with the shield installed I'm getting junk readings from a4 and a5.  They work fine without the shield.

The shield has pull-up resistors for I2C/TWI on pins A4 and A5. Special care (resistor bridge) needs to be taken if using these as analog pins. Please see the schematics for more details.
https://www.itead.cc/wiki/images/4/46/Sch_sd_shield_3.0.pdf
Cheers!


text:
Controlling an OSX app by Arduino
I am trying to control an app on OSX with an Arduino Uno.  Specifically, I would like to start and stop play of an MP3 on iTunes, or a track on Spotify, using an Arduino connected to the Apple computer with USB.
Any suggestions would be greatly appreciated.

This sounds more like an OSX question than an Arduino one.  If the things you want to do can be done by a keyboard, you can get a Leonardo type board and be a keyboard.  Otherwise you will probably need custom software on the Mac which takes custom messages from the Arduino and turns them into actions.  The hard part will be coming up with the Mac side - since it is custom, the Arduino side can be trivial, for example just Serial.println("pause itunes");

You could write a small script that interfaces through serial to the Arduino and forwards commands and instructions on to other places using AppleScript.

@Majenko that is exactly what I'd like to do.  But how?  I suppose I should ask the question on 'Ask Different'?

90% of what you are wanting to do would be Apple programming. Not something we know much about here.

We can help you with the Arduino side of things, but that would just be simple serial operations really.

I am now having Screen output to log.txt, and the following applescript works just great!
set trigger to 1
set stopString to ""
repeat until (stopString = "stop")
set testTxt to paragraphs of (read POSIX file "/Users/fed/log.txt")
set countTxt to (count of testTxt) - 1
set lastLine to item countTxt of testTxt
if lastLine contains "Start MP3" and trigger is 1 then
    tell application "Spotify" to playpause
    set trigger to 0
end if
if lastLine does not contain "Start MP3" then
    set trigger to 1
end if
if lastLine contains "Stop Loop" then
    set stopString to "stop"
end if
end repeat

Applescript can read stuff from a .txt file, and cause an event on a specific word? Then you'll indeed only need a program that takes serial input (USB COM-port) and put it in a file.