Outils pour utilisateurs

Outils du site


issue130:tutoriel3

Ceci est une ancienne révision du document !


In the last issue, I showed you how to dim an LED with a potentiometer. In this issue, we will read the values of the potentiometer using the analog-to-digital conversion (ADC), and send these values to a serial console. This time, we need additional hardware – a USB-to-serial adapter (it is advised not to use the serial port on your computer as damage may occur to the microcontroller because of high voltage from the computer serial port). Many USB-to-serial adapters will work. Common chipsets are CH340, CP210x, FTDI, PL2303, but any other chipset will work as well. Importantly, they must provide voltages at 3V or 5V, and a Linux driver. It would also be useful if the USB-to-serial adapter is ‘breadboard friendly’, which means it has pins to connect to it, whether directly or through cables, to the breadboard. You could use an Arduino as a usb-serial adapter, see https://oscarliang.com/use-arduino-as-usb-serial-adapter-converter/ for more information.

Dans le dernier numéro, je vous montrais comment fairer lavier la muminosité d'une LED avec un potentiomètre. Dans ce numéro, nous lirons les valeurs du potentiomètre en utilisant une conversion analogique/digitale (ADC), et enverront ces valeurs à une console série. Cette fois, nous avons besoin d'un matériel supplémentaire - un adaptateur USB-vers-série (il est conseillé de ne pas utilisé le port série de votre ordinateur car des dommages peut affecter le microcontrôleur à cause de la tension élevée sur le port série de l'ordinateur).

Beaucoup d'adaptateurs USB-vers-série conviendront. les jeux de puces classiques sont les CH340, CP210x, FTDI, PL230, mais beaucoup d'autres fonctionneront aussi. Il est important qu'ils puissent fournir une tension de 3 V ou de 5 V et disposent d'un pilote pour Linux. Il serait bien ausi que l'adaptateur USB-vers-série soit fait pour une plaque d'essai, ce qui signifie qu'il doit avoir des picots pour les connexions, soit directement, soit avec des fils, à la plaque d'essai. Vous pouvez utiliser l'Arduino comme adaptateur USB-vers-série ; regardez https://oscarliang.com/use-arduino-as-usb-serial-adapter-converter/ pour plus d'information.

Serial communication and hardware A serial communication means that a byte of data is sent bit-by-bit through a dedicated receiving and transmitting line. See the end of this article for more basics of serial communications. For the program flow, it is further important if the communication is blocking (the program must halt until the data is fully received or transmitted) or non-blocking (the data is buffered and the program need not halt until data is transmitted or received, then the data would be processed). Some microcontrollers have a Universal Synchronous and Asynchronous Receiver-Transmitter (USART) implemented. The ATmega328p (the one on the Arduino UNO R3) for example has a USART on PIN2 for receiving and PIN3 for sending serial data.

Communication série et matériel

Dans une communication série, les octets de données sont envoyés bit par bit dans une ligne dédiée de réception et de transmission. Voyez en fin d'article d'autres informations de base sur les communications série.

Pour le déroulement du programme, il est important par la suite si la communication est bloquante (le programme s'arrête jusqu'à ce toutes les données soient reçues ou émises) ou non bloquante (les données sont bufferisées et les programme n'a pas besoin de s'arrêter jusqu'à la bonne fin de répcetion ou d'émission des données ; ensuite, les données seront traitées). Certains microcontrôleurs disposent d'un émetteur-récepteur universel synchrone et asynchrone (USART - Universal Synchronous and Asynchronous Receiver-Transmitter). Le ATmega328p (celui de l'Arduino UNO R3), par exemple,a un USART sur PIN2 en réception et PIN3 en émission des données série.

Great Cow BASIC has a solution to get the hardware USART to work with a few lines of code. Additionally, Great Cow BASIC supports some functions to send and receive data in different data types. See the Great Cow BASIC help for more information, but, to use the USART in the ATmega328p, and send some data, you would start with the following lines. (In real life you would, of course, send more meaningful data): Setup the Hardware USART for Serial operations An example of using the hardware USART in the ATmega328p is shown on the previous page.

Great Cow Basic a une solution pour faire fonctionner l'USART matériel avec quelques lignes de code. De plus, Great Cow Basic dispose de fonctions pour envoyer et recevoir des données dans différents types de données. Voyez l'aide de Great Cow Basic pour plus d'information, mais, pour utiliser l'USART du ATmega328p et envoyer quelques données, vous commencerez avec les quelques lignes qui suivent. (Dans la vraie vie, vous enverriez, bien sûr, des données plus significatives).

Paramétrer l'USART matériel pour des opérations série

Un exemple de l'utilisation de l'USART matériel du ATmega328p est présenté sur la page précédente.

Setup for Serial operations using Software Some microcontrollers do not have a hardware USART; which is true for the ATtiny13a I am using for these examples. Another reason could be the need of an additional serial connection without changing the microcontroller. In order to receive and send data, the serial communication could be achieved in software as well. For me, this would be quite a hard task to program, but, luckily, Great Cow BASIC has two methods for serial communication. For comparison, I will provide an example for each, and observe the differences in the two methods. Great Cow BASIC also has two methods for Serial operations using software, and these are both shown below. For simplicity, I provide the examples for sending values over the serial line. If you want to receive data, go right ahead and add the few missing lines of code.

Option 1 - ‘Legacy Software Serial Method’: This legacy method was implemented in 2007 - and is a popular method for software serial operations. This method (top right) can handle up to three different serial lines, with baud rates between 300 and 19,200.

Option 2 - ‘Optimised Method’: This method (bottom right) uses an additional library for Great Cow BASIC from Frank Steinberg, and is an optimised software serial driver written in portable assembler. Portable assembler means this optimised method supports AVR and PIC microcontrollers. This method provides higher baud rates (eg: an AVR clocked at 1 MHz can handle up tp 28.800 baud), and the program generated is small enough to fit on the tiny13a microcontroller. If you compare the code examples, keep in mind that the ATMega328p on the Arduino comes with a 16 MHz Resonator, so the system clock is at 16 MHz. The ATtiny13a comes with a 9.6 MHz integrated systems clock; but, by default, the clock is divided (read: limited) by 8 to a mere 1.2 MHz. To change that, it would be necessary to change the fuses, which I did not want to do in this set of articles – I wanted to keep things simple.

Software prerequisites to work with the serial adapter If you did not have to use a serial adapter, nor serial terminal software, on your computer, here are some brief explanations to get the serial communication to work. The chances are good that your computer has the necessary drivers right out-of-the-box: Plug in your serial adapter to your USB-Port, and type: dmesg | grep tty You should see a line like this: […] usb 6-2: cp210x converter now attached to ttyUSB0 Now, you know the chipset of your adapter is supported (in my case it is a cp210x), and it was assigned as device ttyUSB0. Then give your Linux user the permission to use this device. Type: sudo chmod 666 /dev/ttyUSB0

Give your superuser password if prompted. Then, if you do not have a serial terminal installed, I suggest putty, as it is easy to use and easily installed. A sudo apt install putty is all you need to do. Then start putty and change the serial line to /dev/ttyUSB0, the baud rate according to your chosen one in the microcontroller program (I chose 9600 baud for the examples). Make sure the other parameters of the serial line are correct, scroll down the category tab and look for the entry Serial. Make sure the data, stop, and parity bit settings are correct. The entry flow control is not important for the time being - leave it as is. Then, click ‘Open’ - and you should see the awaited data scrolling along the terminal.

Breadboard circuitry Compile the program and flash it to the ATtiny13a with your hardware programmer of choice. The USB-to-serial adapter should have +5V or +3V, and GND, to power up the microcontroller. Then, hook up the receiving line from the adapter to the sending PIN (PB1) of the ATtiny13a. Hook up the Poti to +5V or +3V, and GND as well, and the middle pin to the PIN ADC2 (PB4).

Conclusion After some experimentation, it shows that the legacy software serial method produces a program that is large - too large for the tiny13a; The version of my code shown above compiles to 1.016 Bytes. Why is this a problem? First, you have no more program space left for anything else. Second, and more importantly, the readings on the terminal were not human readable as we are limited to the raw values being displayed. I would suggest, if using the legacy serial method, to utilise a microcontroller which has more program flash memory, eg, the ATtiny85. But, all is not lost! Serial communication on the ATtiny13a is still feasible. The optimized serial software compiled to around 368 bytes and worked like a charm. With the optimised software, we have a working solution to get serial I/O to work; even with the small program memory device like the ATtiny13a!! Serial communications is an important method for exchanging data. Great Cow BASIC makes the configuration and use very simple. Serial communications is easy - it is useful for debugging and to communicate key messages to the users. It can also be used for inter-microcontroller communications, albeit there are better methods like I2C and SPI.

GitHub Repo Evan Venn (Anobium…my mentor with respect to these articles) suggested to open a GitHub repository for the source code, and, I must admit, this was a good idea. If you want to download the sources instead of copy-pasting it, you can now check it out with git or an SVN client. See https://github.com/Anobium/Great-Cow-BASIC-Demonstration-Sources/tree/master/Publication%20Solutions/Full%20Circle for more information.

References serial communication https://www.teachmemicro.com/microcontroller-serial-communication/ Acknowledgement I wish to thank Evan Venn (Anobium) from the Great Cow BASIC Team for his insights and valuable hints.

Corrections In the last issue a formula got lost, for completeness: Serial Comms - A Few Definitions and Notes: by Michael Kennedy and Gord Campbell These notes focus on some of the main features of the common RS-232 implementations, but a few other variations are also mentioned. They’re intended to supplement the story in FCM #130 (etc) on Great Cow BASIC, by Boris. “RS-232” (Recommended Standard 232) is a popular communications system. Originally (1960), it was used for connections with old-style telephone/terminal/typewriter systems. The simplest RS-232 implementations handle two-way communications between just two devices (say, Dev-A and Dev-B). The cabling has just three wires: ground, data pulses going from Dev-A to Dev-B, and data pulses from Dev-B to Dev-A. The cable is normally up to about 15-20 metres, but could be up to a few hundred metres, max. The hardware at both ends could be microcomputers, or dedicated, relatively smart, RS-232 chips, or just suitable line drivers - where the entire implementation is handled in software.

The speed of the data-pulses must normally be set, in advance, on both devices, and must be based on how quickly both devices can transmit and receive the pulses, on the cable length and quality, the overall electrical environment, etc. Typically, it might be set at 300 baud, 1,200 baud, 2,400, 4,800, 9,600, 14,400, 19,200, or maybe even up to 115,200 baud and beyond. A “baud” refers to the width of each “bit/pulse” on the cable, so 4,800 baud is 4,800 bits per second. To send a single “byte” from Dev-A to Dev-B: • Dev-B must be ready to accept the byte (obviously!). • Dev-A sends out one “Warning” pulse, called a Start-Bit, to wake up Dev-B! • Dev-A then sends the byte’s bits. Usually eight, but sometimes maybe as few as five are adequate. • Dev-A might send a single Parity bit (Odd/Even/None). • Dev-A sends one, or one-and-half, or two, “Stop”-bits.

So, typically, a single byte might involve the transfer of about 10-12 bits/pulses. And in that case, a speed of 4,800 baud might result in a maximum transfer of about 400-480 bytes per second - assuming there’s no wasted time between each “byte” - which would never be reached in reality! UART: The above approach is termed “Asynchronous”, because there can be an indeterminate amount of time between bytes. The devices are termed UARTs (Universal Asynchronous Receiver and Transmitter). SIMPLEX/DUPLEX: Where data pulses are allowed on only one of the two data-wires at any one time, this is defined as Half-Duplex. If Dev-A may send data to Dev-B, and Dev-B may send data to Dev-A, at the same time, this is Full-Duplex. There’s also a “Simplex” approach, where only one device does all the sending, and the other all the receiving - with just a single “data”-wire, for example, a wireservice sending stories to a newsroom.

Further, less common, variations on RS-232… USARTs: Two wires could be used to send data-bits from Dev-A to Dev-B, and two more wires for the data-bits from Dev-B to Dev-A. The second wire (of each pair) contains clock pulses - that match the data-bits on the first wire. Then, the extra Start/Stop bits may not be needed for each byte, and it may not be necessary to “lock” the two devices into matching speeds - because the clock pulses determine the widths of the data-pulses. This approach should result is slightly higher communications speeds and higher quality. The devices at both ends are termed USARTs (Universal Synchronous and Asynchronous Receiver and Transmitter); they can handle both protocols. Additional Control wires: In some implementations, extra wires are used ([D]CD Carrier Detect, RTS Request to Send, CTS Clear to Send, DTR Data Terminal Ready, DSR Data Set Ready, RI Ring Indicator, RTR Ready To Receive, etc), which are used by each device to tell the other device that they are Busy, Ready, Unavailable, etc. Often called “Handshaking” or “Flow-Control” signals.

RS-422, Longer cables: Slightly different devices and cabling arrangements can be adopted where longer cable runs, and/or higher speeds, are needed. The cable contains two wires for each of the data-pulses runs, and two more wires for each of the clock-pulses - like standard twisted-pair LAN cables. RS-485, Multiple devices: Different ICs can be deployed where, for example, more than two (maybe 10, 20, 30…) devices can share the same cable(s), and, for example, all of them can talk with a single “server/master” device. Error Handling!: If you’re writing “serial” software, and/or taming serial hardware, for private educational or entertainment purposes, then you probably won’t be over-worried if a few errors arise now-and-then. For example, if you’re sending data, serially, to a display, or controlling a few LEDs, etc, you might chose to not bother if the device is present or not, or powered on, or fully “reset” after a power-on, or ready to send/receive serial data, or that its serial configuration matches ours, or that it’s faulty, or has a hundred other issues….

However, if your RS-232 app is used in an MRI/CAT-scanner, and it’s controlling doses of radiation, positions of motors, etc, and you’re the patient, then you’ll definitely have to handle all of the above conditions! Then, you’ll probably have to use some of the additional hand-shaking signals/wires that I mentioned above, and you’ll probably have to introduce a whole “protocol” and timings to control all your comms. Eg, when a sender/transmitter wishes to send some data to a receiver, then, minimally: • Both devices would use the available control-wires to ensure that both are ready-and-willing to communicate. • Dev-A says: “Hello, I wish to send you an alert/reading… Are you ready, and can you take it now?”. • Dev-B: Yes, send it on. • Dev-A: Here it is….. xxxxx…. • Dev-B: Got that, 123 bytes in total, checksum=xxx, thank you. • Dev-A: Excellent – thank you, over-and-out.

At all of the above stages: • The sender of each packet might have timeouts running, to check if the transmission choked… • The receiver would have timeouts running, to ensure that the packet arrived on time, and fully… • All those hand-shaking lines would be continually checked, at both ends, to ensure that nobody cut a cable, or switched the power off… • If minor errors arose, retries would probably be attempted, automatically, for a while… • The handling of all major/catastrophic errors would have to be very carefully designed, and implemented, and tested. So, to ring that bell, or turn on that emergency light, or rotate that stepper motor, a single “Print…..” statement might evolve into a very complicated 500-line “LED_On()” function! ;-)

Finally: For lots of good, general, details, see: https://en.wikipedia.org/wiki/RS-232. And do check all the other 18,000,000 websites ;-) If you’re implementing RS-232 comms on a specific device (UART, uP, CPU, etc), then look up the details in the manufacturer’s datasheets of those devices. Normally, the devices will work exactly as per the specs. However, if you’re stressing the devices, and/or writing low-level drivers, etc, you might sometimes observe “inexplicable” results. When stressed, some of these devices have nasty bugs, so you should run some web searches, and, hopefully, others will have posted explanations and suggestions. Good Luck! Michael Kennedy and Gord Campbell

issue130/tutoriel3.1519890197.txt.gz · Dernière modification : 2018/03/01 08:43 de d52fr