🚌 I2C bus and Arduino

Daniil Zhuk
The serial communication protocol IIC (also called I2C - Inter-Integrated Circuits, intermicrocircuit connection) uses two bidirectional communication lines for data transmission, which are called the serial data bus SDA (Serial Data) and the clocking bus SCL (Serial Clock).

Read more β†’

πŸ— How to make a copy of a key for a doorphone in home conditions

Daniil Zhuk
With the help of Arduino, you can make at home a copy of the key for the intercom in 15 minutes, if, for example, the workshop is closed and the key is needed urgently.

Read more β†’

πŸ’³ How to connect RFID reader RC522 to Arduino

Daniil Zhuk
In this article, we will look at the connection to the Arduino of the RC522 RFID card reader and keyfobs operating at 13.56 MHz.

Read more β†’

πŸ“‘ How to connect to Arduino bluetooth module

Daniil Zhuk
Connect the wireless Bluetooth module to the Arduino and learn how to receive data from it and transfer data from it to your computer.

You will need
  • Arduino Nano board or similar;
  • Bluetooth module HC-06 or any other (for example, such);
  • a set of connecting wires (like this);
  • debug board for mounting without soldering.

Instructions for connecting the Bluetooth module to the Arduino

Description of the Bluetooth module HC-06

There are a large number of implementations of Bluetooth modules. Each has its own characteristics, but in general, they are all very similar. Consider the representative of the Bluetooth module of the family HC-06, which can be purchased at a great price on this site.

This module operates at a frequency of 2.40 GHz to 2.48 GHz and supports the Bluetooth version 2.1 + EDR specification: reduced power consumption, increased data protection and easy connection of Bluetooth devices. A stable reception with the module is guaranteed within 10 meters.

Β 

The purpose of the conclusions of the Bluetooth module is:

Output Purpose
VCCΒ & GND β€œPlus” and β€œminus” of the module power supply, supports voltages from 3.6 to 6 volts;
TXΒ & RX transmitter and receiver module;
MCU-INT (Status, State) status output;
Clear (Reset) reset and restart of the module, in this case, is carried out by a low logic level.

The last two conclusions may not be involved; You can often find modules without any of these findings.

Connection scheme of the Bluetooth module to the Arduino

Connect the bluetooth module to the Arduino according to the above scheme.
Note that the transmitter (Tx) Arduino is connected to the receiver (Rx) of the module, and vice versa.

The Status output shows a high level when the module is paired with another Bluetooth device, and a low one when it is not paired. You can read its value by connecting to the pin of the Arduino and assigning it the pinMode mode (pinStatus, INPUT) and thus learn the status of the module. But the status indicator does not work correctly on all modules, so we will not use it in this example.

As a result, it should turn out approximately as in the photo.

Sketch for Arduino for work on Bluetooth


Let's write such a sketch and load it into the Arduino memory:

const int ledPin = 13; 
char incomingbyte; 

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

void loop() {
  if (Serial.available() > 0) { 
incomingbyte = Serial.read(); switch(incomingbyte) { case '1': digitalWrite(ledPin, HIGH); break; case '0': digitalWrite(ledPin, LOW); break; } } }

We include assembled circuit with Arduino and Bluetooth module connected to it. A properly connected module immediately enters the connection standby mode, which will be indicated by a rhythmically flashing status LED.

Pairing with a Bluetooth device

Now you need to add a Bluetooth device to the list of trusted devices. Turn on Bluetooth on your computer, go to the Bluetooth Device Settings.

If the Bluetooth icon appears on the computer in the notification area when you turn on Bluetooth, you can right-click on it and select the Add Bluetooth device item:

Make sure our Bluetooth module is visible to the computer. Select it from the list and click the Link button. In the dialog box, enter the default password 1234. If you add successfully, the device will appear in the list labeled Paired.

The default password for a specific module may differ from "1234". This information must be provided by the manufacturer (seller) of the module.

If you want to connect to your Bluetooth module from your smartphone, then the procedure is the same: turn on Bluetooth on the smartphone, find the module connected to the Arduino, and pair it with it.

Connect to the bluetooth module via Bluetooth from computer

To connect to the Bluetooth module, you can use various programs that can connect to the COM port. For example, such as HyperTerminal, PuTTY, Tera Term, Termite and others. They are all free and freely distributed on the Internet.

The convenience of the program TeraTerm is that it automatically displays a list of COM ports that are assigned to the Bluetooth module of your computer. Run the program, select the Serial connection, select the appropriate Bluetooth COM port from the list, click OK.

The PuTTY program also asks for the port number (COM4, you will have your own), connection speed (9600), connection type (Serial). Then click the Connect button.

In case of an error during the connection, the program will display an appropriate notification. If your computer is connected to the Bluetooth module successfully, then you will see a terminal field in front of you.
Enter from the keyboard in this field the number 1 - and the LED on the 13 pin of the Arduino will light up, enter 0 - will go out.

Connecting from a smartphone using Bluetooth Terminal

Similarly, you can connect to the Bluetooth module from your smartphone. Download the application to work with Bluetooth on the terminal, for example, Bluetooth Terminal. Connect to the module and enter commands 0 or 1.

Thus, we have learned to connect via Bluetooth to the Arduino and transmit data to it.

Read more β†’

πŸ”Ά How to connect the digital compass HMC5883L to Arduino

Daniil Zhuk

Consider connecting the GY-273 module with the Honeywell HMC5883L three-axis digital compass. This microcircuit can be used for magnetometric measurements, in navigation, if greater accuracy of measurements is not required (with an accuracy of 1 ... 2 Β° and the possibility of calibration). The device is connected via the I2C interface.

We will need:

  • Arduino UNO or another compatible card;
  • GY-273 module with digital magnetic field sensor HMC5883L;
  • connecting wires (I recommend this set);
  • breadboard;

Description of the HMC5883L digital compass and GY-273 module

The HMC5883L digital compass is a miniature microchip made on a single chip, cheap and unpretentious, and it quickly gained recognition from radio amateurs. Often it is sold as part of a finished module with all the necessary strapping, for example, GY-273.

Here are the main technical characteristics of the magnetic sensor:

  • 3-axis magnetosensitive sensor;
  • 12-bit ADC with a resolution of 2 MGs (milligauss);
  • built-in self-test;
  • low operating voltage and low consumption;
  • I2C digital interface;
  • high scanning speed - up to 160 times per second (the time of one measurement is about 6 ms);
  • accuracy of determining the direction of 1 ... 2 Β°;
  • can be used in strong magnetic fields (up to Β± 8 Gauss).

Connecting the HMC5883L digital compass to the Arduino

The diagram of the connection of the magnetic sensor HMC5883L to the Arduino is shown in the figure. It is very compact and simple: the two-wire interface IIC is good, which requires a small number of connections.

You can use the breadboard. It should turn out about as in the photo. I also have a logic analyzer connected to the SCL and SDA buses in order to control the information exchange.

Sketch for Arduino that reads HMC5883L identification registers

How is the exchange with the magnetic sensor HMC5883L? Open the passport to the sensor HMC5883L and find out that the address of the device is 0x1E, and the following registers are available:

Let's try to read the identification registers of 10 (0xA), 11 (0xB) and 12 (0xC) devices as the first acquaintance.

#include <Wire.h>  
#define addr 0x1E 
  
void setup() {
  Serial.begin(9600); 
Wire.begin(); } void loop() { Wire.beginTransmission(addr); Wire.write(0x0A); Wire.endTransmission(); Wire.requestFrom(addr, 3, true); while( Wire.available() ) { char a = Wire.read(); char b = Wire.read(); char c = Wire.read(); Serial.print("A = "); Serial.println(a, HEX); Serial.print("B = "); Serial.println(b, HEX); Serial.print("C = "); Serial.println(c, HEX); Serial.println(); } delay(100); }

Opening the serial monitor, we will see:

A = 48
B = 34
C = 33

The signal received by the logic analyzer will be as follows:

What does it mean? The first byte is the I2C address with which we (the master, Arduino) establish a connection (the upper 7 bits 0x1E), and the write mode (the low bit is 0x0); the number 0x3C is obtained. The second byte is the number 0xA, which we recorded at address 0x1E and the acknowledge bit from the HMC5883L sensor, which is a slave. This is the register number from which we will start reading data. This is where the first transaction ended. Begins next. The third byte is the read request from the slave (the upper 7 bits are the address 0x1E, the 8th bit is the read operation 0x1; the number 0x3D is obtained). The last 3 bytes with the values ​​0x48, 0x34 and 0x33 are the response of the HMC5883L slave device from the registers 0xA, 0xB, and 0xC, respectively.

Moving through the registers of the digital compass HMC5883L with continuous reading is carried out automatically. Those. each time it is not necessary to specify the register (but not prohibited). For example, if instead of 0xA we would write 0x3 and count 10 times, then we would get the values ​​in 10 registers, starting from the 3rd to the 12th.

And what are these three numbers - 0x48, 0x34, 0x33? Using the passport on the HMC5883L digital compass again, we will see that these are the default values ​​for the three identification registers:

Sketch for Arduino, reading digital compass HMC5883L

And now let's consider a typical measuring task: let's take readings of magnetic induction along three axes. This example is described in the passport to the device. We only translate it into a language understandable Arduino. So sketch.

#include <Wire.h>
#define addr 0x1E 

void setup() {
    Serial.begin(9600);  
    Wire.begin(); 
  
    Wire.beginTransmission(addr);
    Wire.write(0x00); 
    Wire.write(0x70); 
    Wire.write(0xA0); 
    Wire.write(0x00); 
    Wire.endTransmission();
}

void loop() { 
  
  Wire.beginTransmission(addr);
  Wire.write(0x03); 
  Wire.endTransmission();
  
  Wire.requestFrom(addr, 6); 
  while( Wire.available() )  
  { 
    int h = Wire.read(); 
    int l = Wire.read(); 
    int x = word(h, l);  

    int y = Wire.read(); 
    y = y << 8; 
    y = y | Wire.read(); 

    int z = Wire.read() << 8; 
    z |= Wire.read(); 
    Serial.print("X = ");  
    Serial.println(x, DEC); 
    Serial.print("Y = ");  
    Serial.println(y, DEC); 
    Serial.print("Z = ");  
    Serial.println(z, DEC); 
    Serial.println();    
  }
    delay(100);
}

This shows the different options for obtaining a two-byte number from two separate bytes. Here's how we did it: separately we counted the high byte and the low byte, and then we used the word operator, which combined two bytes into a two-byte number (the β€œword”). You can do this: read the high byte, move it 8 bits to the left, count the low byte, and then combine them by OR (OR). In the latter case, simply the shorter syntax of the previous version is given. Choose the one that is more convenient and understandable to you.

Consider the timing diagram of information exchange:

The first 5 bytes to a short pause are what we described in the void setup () section:

  • selection of slave address and recording mode;
  • selection of the first control register A (CRA) with the address 0x00 (according to the table above);
  • entry in the first CRA control register of the number 0x70 - averaging over 8 points, 15 Hz, normal measurements (see passport for details); HMC5883L translates the pointer to the next register - Control Register B (CRB);
  • write to the CRB register the number 0xA0, which corresponds to a sensitivity setting of 5; HMC5883L translates the pointer to the next register - Mode Register, mode selection register;
  • write to the mode register the number 0x00 - infinite measurement mode.

Then there is a small pause of about 20 Β΅s, and two more bytes are transmitted - this is the choice of the slave address in the write mode and the write of the registered address - 0x03 - with which we will begin each data reading cycle defined by us in void loop (). This is the first data register, as shown in the table above.

The last 7 bytes mean the following:

  • the first byte of the 7th - the choice of the address of the slave and the read mode;
  • the next two are reading two bytes of readings from the X-axis channel;
  • the next two are the Y-axis;
  • the next two are the z-axis.

As a result, in the port monitor, we see the indications of the magnetic sensor in three axes:

Β 

Β If you rotate the sensor in space, you can see how the readings change.

I think that the calibration and adjustment of the digital compass is a topic for a separate article.

Read more β†’

πŸ“» Connecting the XY-MK-5V / FS1000A radio module to Arduino

Daniil Zhuk
Today we are going to connect the radio module, or rather, two modules - the XY-MK-5V receiver and the FS1000A transmitter - to the Arduino. Also to two.

We will need:

  • 2 Arduino UNO boards or other modification (you can buy it inexpensively on this site);
  • FS1000A radio transmitter and XY-MK-5V radio receiver purchased here;
  • connecting wires (I recommend this set, which has all the combinations "mother-mother", "father-father", "father-mother").

Description of the FS1000A radio transmitter and XY-MK-5V receiver

This pair has a very low cost, while it has a very good transfer radius (about 50 meters in the city). The FS1000A radio transmitter and XY-MK-5V radio receiver must operate on the same frequency. Out of the box, they are tuned to the 433 MHz carrier frequency. This is a common radio frequency. For example, it is used to communicate with a home weather station like Oregon Scientific with remote weather sensors (we will return to them later), in some automatic gate control systems, and in other β€œsmart” devices and systems that transmit data β€œover the air”.

Connection to the Arduino FS1000A radio transmitter and XY-MK-5V receiver

Before connecting the FS1000A transmitter to the Arduino, it is necessary to solder a piece of wire with a cross-section of approximately 0.25 ... 0.5 mm and a length of 17.3 cm to the pad marked on the ANT board. This will be the antenna.

The frequency of 433 MHz corresponds to a wavelength of approximately 69 cm. With an antenna length equal to 1/4 of the wavelength, the wave vibrator (antenna) is in resonance with the wavelength, and its efficiency is maximum. Hence the number of 17.3 cm (= 69/4).

The FS1000A transmitter can be powered with a voltage of 3.3 to 12 V. Depending on the applied voltage, the transmission distance may vary somewhat: with a higher voltage, a longer range. We will apply a voltage of 5 V to the transmitter, and connect the remaining outputs according to the diagram.

The XY-MK-5V receiver is also easy to connect. The output "DATA" on the module is double, you can connect to either of the two legs. Power will also be supplied by 5 volts from the Arduino board.

An example of the simplest data transmission over the air using Arduino

The peculiarity of the radio transmission is that it is impossible to transmit continuous signals of the same level, the transmission will be disrupted. For more or less stable transmission, it is necessary to transmit a variable signal. And it is necessary to somehow separate the useful signal from the noise that is always present on the radio.

For the first experiment, let's take the standard blink sketch with the Blink LED and slightly modify it: every 5 seconds we will send a command from one Arduino (transmitter) to another (receiver). By accepting a command, the receiver will either light the LED if it is extinguished or extinguish. That is, every 5 seconds the receiver will change its state according to the accepted command. Make it a little more difficult than it seems, because we need to select a team from the constantly present noise.

The first sketch is for the transmitter. It is quite simple.

#define prd 4 
#define ledPin 13 

void setup() {
  pinMode(ledPin, OUTPUT); 
  pinMode(prd, OUTPUT); 
}

void loop() {
  sendCommand(); 
  delay(5000); 
}

void sendCommand() {
  digitalWrite(ledPin, HIGH);  
  digitalWrite(prd, HIGH);
  delay(100); 
  digitalWrite(prd, LOW);
  delay(50); 
  digitalWrite(prd, HIGH);
  delay(50); 
  digitalWrite(prd, LOW);
  delay(50); 
  digitalWrite(prd, HIGH);
  delay(100); 
  digitalWrite(prd, LOW);
  delay(50); 
  digitalWrite(ledPin, LOW); 
}

The command timing diagram is shown in the figure:

The sketch for the receiver, in view of the reasons described above, is more difficult. Therefore, to begin with, let's just periodically read the data at the receiver input and output what we accept to the serial port.

#define prm 2 
#define ledPin 13

void setup() {
  Serial.Begin(9600);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  int data = digitalRead(prm);
  Serial.println(data);
  delay(10);
}

In the serial monitor, we will see a series of fast-changing ones and zeros. If the data obtained in approximately 17 seconds is displayed graphically, then we will see the following:

As you can see, a noise signal is constantly present at the receiver input. The moments when the transmitter emits are easily tracked by eye (in the figure they are highlighted with blue dotted frames). After the transfer is completed, the zero levels is set for a short time, but then the automatic gain control system again boosts the noise, and a chaotic change of logic levels appears at the receiver input.

However, the selection of the useful signal from the noise with the help of the equipment is not as easy as the eye.

There is a so-called Kotelnikov's theorem, which says that when sampling an analog signal, there will be no information loss only if the frequency of the useful signal is equal to half or less of the sampling rate (the so-called β€œNyquist frequency”).

For simplicity, let's take the data polling period (sampling period) from the receiver input 50 ms - this number is equal to the duration of the shortest part of the command, which we send to the radio every 5 seconds by the transmitter. Taking one sample for 50 ms, we, of course, break the Kotelnikov theorem (the sampling period must be taken at least 25 ms or less). But to make the example as simple as possible, let’s leave it like that and see if we can make our team stand out from the noise in the radio.

Polling the data from the receiver every 50 ms (green vertical bars in the figure are the moments when the receiver was polled), we should see the sequence "110101100". At the same time, the probability of false alarms of our detector will be quite high, since There is a considerable chance that at the moments of reading data from the receiver, a random noise signal will have exactly the same values. Fortunately, at the end of the sequence, there is a large number of zeros. So we will look for a sequence, say, β€œ11010110000000”.

If you take more zeros, then the probability of false positives will decrease. But we must understand that the search for a coincidence of a larger array will take longer, and 50 ms will no longer be 50, but a bit more. Because of this, the moments at which we interrogate the receiver will gradually shift (β€œrunaway” frequencies). In addition, we cannot guarantee that at the moments when we expect the arrival of zeros, some random burst will not occur at the receiver input, and we do not recognize the incoming command. That is, we get the omission of the desired sequence. Here it is necessary to achieve a compromise between the number of false positives and the number of omissions - both of these conditions do not suit us.

const int prm = 2;
const int ledPin = 13; 
const int len = 14; 

bool state = false;  
int pattern[len] = {1,1,0,1,0,1,1,0,0,0,0,0,0,0}; 
int testReg[len] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 

void setup() {
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
}

void loop() {
  int data = digitalRead(prm); 
  ShiftReg(data, testReg); 
  if (IsCommandDetected) { 
    state = !state; 
    digitalWrite(ledPin, state);
  }
  delay(50); 
}

void ShiftReg(int newVal, int *arr) {
  for (int i=0; i<len; i++) {
    arr[i] = testReg[i+1]; 
  }
  arr[len-1] = newVal; 
}

bool IsCommandDetected() {
  for (int i=0; i<len; i++) {
    if (testReg[i] != pattern[i]) { 
      return false;
    }
  }
  return true;
}

The ShiftReg () function takes two arguments as input: the current contents of the test register and the last value received from the input of the receiver. It shifts all values in the register by 1 position, and places the currently accepted value in the lower position of the register. Thus, 16 (in this particular case) last values read from the receiver are permanently stored in the register. If we look at how the contents of the register change, which is formed by the ShiftReg () function, we will see something like the following:

0000000000000000
0000000000000001
0000000000000010
0000000000000100
0000000000001000
0000000000010000
0000000000100001
0000000001000010
0000000010000101
0000000100001010
0000001000010101
0000010000101010
0000100001010101
0001000010101010
0010000101010100
0100001010101001
1000010101010010
0000101010100101
0001010101001010
0010101010010101
0101010100101010
1010101001010101
0101010010101011
1010100101010110
0101001010101101
1010010101011010
0100101010110101
1001010101101010
0010101011010101
0101010110101010
1010101101010101
0101011010101011
1010110101010110
0101101010101101
1011010101011010
0110101010110101
1101010101101010
1010101011010101
0101010110101010
1010101101010100
0101011010101000
1010110101010000
0101101010100001
1011010101000010
0110101010000101
1101010100001010
1010101000010101
0101010000101010
1010100001010101
0101000010101010
1010000101010100
0100001010101001
1000010101010010

The IsCommandDetected () function compares two arrays term-by-case β€” the reference array (the desired sequence) and the contents of the test register (the array of values ​​obtained from the receiver), and if the arrays are the same, then we β€œcaught” the command. In this case, change the state of the built-in LED.

findings

In practice, the resulting detector copes quite well with the task. The LED on the Arduino board, to which the receiver is connected, changes its state as expected every 5 seconds. This is what was required of him.

However, in reality, as a rule, there are more complex tasks, namely, to transmit some meaningful data. In the next article on working with the XY-MK-5V and FS1000A modules, I examined in detail the possibility of transmitting data over the air. The idea is focused on transfer between two computers using UART modules. But Arduino also has Rx and Tx lines related to UART. So I am sure that adopting the idea to use with Arduino will not be difficult.

Read more β†’

🌀 How to connect the temperature and humidity sensor DHT11 to Arduino

Daniil Zhuk
DHT11 temperature and humidity sensor is a popular and cheap sensor that can be used in a fairly wide range of temperatures and relative humidity. Let's take a look at how to connect it to the Arduino and how to read data from it.

Read more β†’

πŸŽ‡ How to connect the BH1750 lighting sensor to Arduino

Daniil Zhuk
This time, we will connect the digital 16-bit BH1750 illumination sensor (lux meter), implemented on the GY-302 module, to the Arduino.

Read more β†’

πŸ“Ÿ How to connect clover LCD screen M235 to Arduino

Daniil Zhuk
Clover Display M235 LCD screens and others like it were often used in copiers, fax machines, telephones, and other office equipment. Today, this screen is quite rare, and it is difficult to find documentation on it. And yet in this article, we will connect the Clover M235 LCD screen to the Arduino and make it work.

Read more β†’

πŸ’‘ How to connect RGB LED to Arduino

Daniil Zhuk
RGB LED - these are three LEDs of different colors (Red - red, Green - green, Blue - blue), enclosed in one package. Let's see how to connect the RGB LED to the Arduino.

Read more β†’