Due resistenze in parallelo

Qualche anno fa mi trovai nella necessità di provare un circuito elettronico con una resistenza di un valore non standard. Iniziai a fare i calcoli per usare due resistenze di valore standard in parallelo per ottenere il valore desiderato, ma mi resi conto che ci sarebbe voluto meno tempo a scrivere un programmino in FreeBasic che a usare la calcolatrice. Così realizzai il programmino che trovate di seguito. Molto recentemente, un amico e collega di lavoro si è trovato nella stessa necessità ed allora mi sono ricordato di aver affrontato il problema in passato. Così, gli ho passato il programma e lui l’ha usato ricavando il valore desiderato in un attimo. A questo punto, ho pensato che questo programmino potrebbe essere utile anche ad altri ed ho deciso di pubblicarlo sul mio sito, dopo aver aggiunto un po’ di commenti sul listato, per renderlo più chiaro. Ecco il listato completo:

Come vedete nel listato, nelle righe da 9 a 11, ci sono 12 valori di resistenze “standard” da 1 a 8.2 Ohm. I valori standard, in effetti, sono di più, ma io ho inserito solo quelli che uso abitualmente e che ho nei cassetti del laboratorio. Ovviamente, il valore (per esempio) 1.5 vale per tutti i moltiplicatori, così è lo stesso per 1.5 Ohm, 15 Ohm, 150 Ohm, 1500 Ohm, eccetera. Se volete inserire altri valori, aggiungeteli alla tabella e poi modificate gli indici dei FOR usati nel programma per fare i calcoli comprendendo tutti gli elementi della tabella. Ecco un esempio del programma in funzione:

Notate che, essendo il programma molto semplificato, troverete alcuni valori ripetuti due volte, come nell’immagine precedente per la linea: Req= 13,62 ; infatti il valore calcolato è lo stesso sia per R1=18 R2=56, sia per R1=56 ed R2=18. Modificando opportunamente il programma, si possono eliminare queste ripetizioni, se si vuole.

L’algoritmo usato è elementare, direi quasi banale. Si eseguono, semplicemente, tutte le combinazioni di due resistenze di valore “standard” e quando il risultato è “vicino” a quello desiderato, questo viene stampato. La precisione del risultato è determinata nella linea 34 del sorgente FreeBasic. Modificandola (attualmente è 1/20), si potranno ottenere valori in un intervallo più vicino a quello desiderato (se possibile), oppure in uno più ampio.

Se non volete scrivere “a mano” tutto il programma e compilarlo con FreeBasic, potete scaricare il file ResCalc.zip che contiene sia il file sorgente che l’eseguibile già compilato. Il checksum MD5 del file è 3793386218F12756721CB98290BBDE40. Assicuratevi che sia esattamente questo! Se non lo è, buttate via il file: è corrotto, incompleto o non è quello originale. Per scompattare il file .zip, usate il programma 7Z e la password: eficara. Anche se il programma è davvero elementare, ho voluto pubblicarlo ugualmente, perché può comunque essere un buon esercizio per chi sta iniziando a programmare in Basic. Buon divertimento 🙂

63 e “io sono ancora qua” (e già)

Niente articoli tecnici, oggi. Pubblico una foto fatta con il mio smartphone Huawei lo scorso marzo a Trani. C’è il mare dopo la tempesta, tornato calmo. La foto è ridimensionata (l’originale è troppo “pesante”), ma non ritagliata. Il mio figlio maggiore, che è uno che “ne capisce”, mi ha detto che è una bella foto e allora la pubblico su questo blog dove normalmente si vedono solo schemi di circuiti e primi piani di prototipi.

La pace e l’emozione di un momento. Mi sembra giusto condividerle con chi frequenta le mie pagine. Ciao

A m I – a smart music composer (?)

Last update: 2018 Sep 23 – Added final version working folder (C sources)

A lot of (nerd) humour in this title 🙂 It can be read in two ways. The first is: “Am I a smart music composer ?” (the answer is: no) and the second is: “Artificial musical Intelligence – a smart music composer”. In practice, the purpose of this small project is to test an algorithm able to randomly generate a “decent” music. It could be easily done with a PC, using its huge HW / SW resources, but I want to do it with a very small microcontroller circuit based on STM8S001J micro, using my own firmware written in C language.

The software project is splitted in two parts: the first is “the player”, the part that just plays a melody stored in the microcontroller’s memory; the second is the algorithm that generates such melody in a random way. Let’s start from the first part, the “music player”.

First of all, we must build the circuit and test the music player firmware. The schematic is very simple (see below)

Differences from the prototype picture: R6 is 330R on the prototype and R3 was added to reduce sound level while recording the song with PC audio software.

You can download the schematic in PDF format from this link. The circuit is very simple and can be easily built on a prototype board. The piezo buzzer LS1 has low audio volume (it’s just a local “monitor”), but you can take the audio signal from J2 connector and send it to an amplifier. I decided to create a very small ADSR (Attack-Decay-Sustain-Release) in order to have a sound like a “ding” and not the usual “beep”. The I/Os PC5-PC4-PC3 (pin 7) are used all together to give the current necessary to charge the 100uF capacitor used in ADSR. The envelope of such ADSR circuit has the shape that you can see in the next image. There is a screenshot of the Audacity open-source software used to record the default song “Happy Birthday to you” produced by the test firmware.

If you want to hear such recording, try this:

Here is how such “song” is stored in the microcontroller’s memory. In this first section, the notes and their durations are stored as a constants array (FLASH memory), but in the final version the random song will be generated in a RAM array. The player, however, will act in the same way. The duration of every note is expressed in 50mS steps. The note “0” is a pause.

If you want to build this circuit, and improve or modify the first version of the firmware, click the link AmI for the full project folder, with C sources, ready to be edited, compiled and debugged using the free Cosmic-C and STM tools (read my previous articles on this subject). The working folder is zipped, so use the 7Z program with password eficara to extract it. The two buttons “like” and “unlike”, in this test firmware, are used just to start and stop the sequence. Note that the stop button is sampled only at the end of a note, so you must press and hold it down up to the end of a note to stop the song.

The algorithm and how it improves itself

Artificial musical Intelligence: what do we need to create a machine that can autonomously produce an acceptable music or melody ? First of all, we must implement a random numbers generator. This is the heart of the algorithm and simulates that magical element that we have no control over, like fate or destiny. After this, we have to set some rules that will be picked up randomly and used to generate a sequence of notes and pauses. Finally, the most important element: the feedback. The machine needs a feedback to improve itself. The feedback, in this case, is supplied by the human that listens to the music (you) via two buttons. Such buttons are labelled “like” and “unlike”. After listening to the music, you can press “like” if you appreciated the composition, or “unlike” if it was nearly horrible; or, you can simply refuse to press any button to say “not bad, but nothing special”. The result of such feedback is that the implemented rules will change their importance. All the rules, at beginning, start with the same importance, so all of them have the same probability to be extracted by the fate (the random number generator). If we press “like” after listening to the freshly composed melody, the rules involved in such creation will increase their importance, so they will have more probability to be used in the next composition. As opposite, if you press “unlike”, all the used rules will decrease their importance, so the probability to be used in the next composition is reduced. Well, what happens if one rule reaches the “zero” probability (in practice, if it can’t be extracted anymore)? Well, in such case the system will generate a new random rule that will substitute the one just erased. The new rule will start with a probability of 50%. Note that the new rule is really very “casual” and may contain some bad notes combination (or a touch of genius, who knows). All the probabilities of the rules and the rules themselves are stored in the non-volatile memory of the micro (Eeprom) in order to be available after a new power-on of the device. The device, when powered-on, will start composing a new melody (this is a very fast process), then will start to play that melody. After playing the whole melody, the program will wait 5 seconds for a feedback (button pressed) then will restart from the beginning, with a new melody. When you are tired to listen to such melodies, just turn OFF the device…

The rules

Rules are important. They permit to follow an ordered path in the chaos induced by random numbers. Here is an example of the first melody generated by the circuit using just the random numbers generator, without any rule:

In this test project, the rules are 8. The random number generator selects one of such rules for 8 times. At end of this operation, the resultant melody will be played. Every rule contains four “events”. An event is a note or a pause. The rules are arbitrarily chosen by me and I’m not a musician ! Anyway, when one of my initial rules will reach a zero probability, it will be regenerated by random numbers, so my own fingerprint will disappear in a short time. Every event is expressed in 4 bits. These are all the values:

0 = pause               8 = repeat last note
1 = 1 semitone over     9 = 1 semitone under
2 = 2 semitones over   10 = 2 semitones under
3 = 3     "      "     11 = 3     "       "
4 = 4     "      "     12 = 4     "       "
5 = 5     "      "     13 = 5     "       "
6 = 6     "      "     14 = 6     "       "
7 = 7     "      "     15 = 7     "       "

When there is a new event, it is applied starting from previous one (so, it’s a displacement). For example, if last note played was F and the selected value is 4, the new note played will be A (higher frequency); if the value is 9, the new note will be E (lower frequency) and if the value is 8, the new note will be equal to the last played note, so F again. If the value is 0, the new note will be a pause, so no sound, but the value of last played note will be retained in order to be used in next event. With 4 events for rule and each event defined in 4 bits, we  need one word (16 bits) for rule, but one note doesn’t have just a frequency, but also a duration. So there is a second part of the rule that contains such information. The duration just requires 2 bits, so the 4 events are contained in a single byte. These are the available duration values:

00 = 1/8 (4 * 50ms)
01 = 1/4 (8 * 50mS)
10 = 2/4 (16 * 50mS)
11 = 1/4 + 1/8 (12 * 50mS) 

The rules are stored in Eeprom, starting from address 0x4010. Here is an example of the Eeprom area mapping: (notes in yellow, duration in blue)

In order to test the rules, I used a program written by me in Visual Basic Express 2005 for Windows, many years ago. This is the screenshot of the application:

If you want to try with this small application, download the midimio.zip file from my website (look at the page PC Music). It’s a very small and simple program, but it is enough to write simple melodies. To compose a melody, use the checkboxes to select the note and the duration, then click the red button to save the event. The arrows at the sides of the red button move back and forward in the melody. When all the melody has been entered, you can play it with the buttons at the top right of the screen (play, stop, begin, end). The musical instrument can be changed modifying the value in the box “Strumento“. Your PC must be able to play MIDI, to use this program. Note that there are no editing functions ! If you want to modify an event, just use the arrows to move to such event and replace it with a new one, selecting it with the checkboxes, then click the red button. To clear all, restart the program. You can save / reload melodies using the “File” menu tab.

Probabilities

I said that the algorithm changes the probabilities of the rules. I used a simple way to do this. Imagine a dice: it has 6 faces with 6 numbers, so the probability for each number is 1/6. What happens if I modify one face changing its value from 1 to 5, for example ? If I am in Las Vegas, probably I will finish my days in jail ! No, no. This is just an example… In this case the probabilities of the number 5 are 2/6 (and 0 for the number 1) so, even though the dice still have 6 faces, we modified the probabilities of the numbers. In this program we have the numbers from 0 to 7 repeated 4 times, and our “dice” has 32 faces. The random numbers generator (RNG) gives us a number from 0 to 31 and the program checks if the selected “face” is present (bit at 1) or absent (bit at 0). If absent, the RNG is called again, until it finds a 1 bit. So, the rules with more bits at 1 have higher probabilities to be extracted. Here is an example:

Initial status: the rules from 0 to 7 all have two bits each set, so all of them have the same probability (2 of 4, or 50%)

bit position 33222222 22221111 11111100 00000000
             10987654 32109876 54321098 76543210
bit status   11111111 11111111 00000000 00000000

Now, suppose we have pressed “unlike” after a melody that used the rules 6, 2 and 0. In such case, the table will be modified as:

bit position 33222222 22221111 11111100 00000000
             10987654 32109876 54321098 76543210
bit status   10111010 11111111 00000000 00000000
              ^   ^ ^

It’s evident that the rules 6,2 and 0 now have less chances to be extracted. Another example here: we pressed “like” after a melody where rules 7,4 and 1 have been used. The table will be modified as follow:

bit position 33222222 22221111 11111100 00000000
             10987654 32109876 54321098 76543210
bit status   10111010 11111111 10010010 00000000
                               ^  ^  ^

In this case, the rules 7,4 and 1 have more chances to be extracted. So, every “like” and “unlike” will change the probabilities of the rules of 1 of 4, so 25%. The initial values for the rules are set to 2 of 4, or 50%. When all the bits for a rule are filled (all at 1), no additional increment can be done, while if all bits for a rule are erased (all at 0), a new rule will be randomly generated, with 50% of probability (2 of 4 bits). The 4 bytes (32 bits) containing this table are stored, like the rules, in non-volatile memory (Eeprom).

Random Numbers Generator

There are many algorithms to generate (pseudo) random numbers. In this experiment I used a very simple one, taken from an IC used in some old keyboards: the MM5837 Digital Noise Source. You can easily find the datasheet on the Internet.The operation principle is simple. There is a 17 bits shift register and the input is computed with a simple xor of the bits 17 and 14. One mandatory rule is that the initial value of the shift register MUST be different from zero. Here is my personal version of the algorithm:

As you can see, I used two 16 bits shift registers slrand[0] and slrand[1] with two different feedbacks. The first uses bits 14 and 11 as shift input, while the second uses bits 15 and 10. As additional randomness, I used the last bit of previous generated random value to select which register must be used to update the output. The function doesn’t return a value, but just modifies the global variale rand that is used in various parts of the program. The function is continuously called in the main loop of the program to randomize the rumber more often. The output range of the byte rand is 0 to 255.

The shift registers must be initialized with a non-zero value. I used this small function for the initialization. The function is called the first time one button is pressed to start the song generation and takes the seed from the timer TIM4, that is started immediatly after the reset.

End of job: results

After many tests, the music produced by the machine is still bad (in my opinion). May be the music needs some “magic” part that isn’t available on logic circuits, or the algorithm must be improved. Here are two tables containing the rules and the probabilities at the first launch of the program  and after some feedback given by me pressing the “like” or “unlike” buttons (rules in yellow, probabilities in blue):

Initial condition of Eeprom

Eeprom modified by the algorithm

If you want to try by yourself, load the zipped file AmI_2.zip, decompress it using the 7Z program with password: eficara and then you will have the full project folder, with the C sources and the .S19 files. In the sub-folder named “release” there are the files: AmI.s19 to burn the program area of the microcontroller and the file rules.s19 to burn the eeprom area of the micro. If you want to start from more advanced rules and probabilities (based on my feedbacks), use the third file newrules.s19 to burn the eeprom area. The option bytes are untouched, leave them as they are in a new STM8S001J device.

Look at the main program, executed after reset:

Once started, the program makes a special sound high-to-low and low-to-high (Glide) to inform you that is waiting for a key pressure. When you press a key, the random number generator is initialized and the main starts, generating a new melody. Look at the SongPlayer state machine and what happens when the generated song ends:

If you press PLUS1 (like), the program calls the routine that increments the probabilities for the used rules (UpgradeProbs). If you press MINUS1 (unlike) the called routine is the one that diminishes the probabilities of the rules used (DowngradeProbs) and eventually generates a new rule if the probabilities reached zero. Finally, if you don’t press any key in the 5 seconds time, the probabilities are not modified. Note that if you press both the keys, you will have first an increment, then a decrement… I did it just for testing purposes. You can use the swim interface to read the eeprom and observe the variations in the rules and in the probabilities after giving your feedback (the micro will be reset).

Here is a melody generated with the eeprom data taken from the file newrules.s19 :

Obviously, the melody will be different if you run your own device, ‘cause it’s a collection of random rules. Have fun experimenting ! Bye.

STM8S UART test in Single Wire (half duplex) mode

I received an answer from an STM engineer after my question in the forum at this link: https://community.st.com/thread/46397-stm8s001j3-uart-remap . The question was about the loss of UART_RX if remapping the TX on the pin 5 (PA3). The answer confirmed my opinion about a mistake in documentation, but the engineer suggested the use of the UART in single-wire half-duplex mode, where only the UART_TX pin is used. So, I tested this operative mode and it worked. Then, I decided to publish the full project folder (schematics and C sources) in order to expand my tutorial about the STM8S microcontroller (hope it helps).

The working prototype

Using a single wire UART means that you must “mix” the output and input line to have your communication. In the microcontroller such mixing circuit is inside the chip, but if you want to use (for example) an USB-Serial converter standard to drive the micro, you will add some hardware. Not so much: just a diode and a resistor. Look at the schematic here below:

The diode used in this case is the BAT43, a Schottky diode with low forward voltage drop. This is necessary in order to have a “zero” level inside the microcontroller VIL limits. Note that such “mixer” isn’t very good if you plan to use the serial interface at very high speed, ‘cause the “high” level comes from the pull-up (10K) only, being the serial line “open drain” like. So, the rising time of the signal depends upon the capacitive loads on the line. Using a transmission speed of 115200 BPS, means that every bit is about 8.7 uS long and the internal sampler of the UART takes 3 samples at the ideal center of the bit. I recommend to use transmission speeds not higher than 19200 BPS. In this experiment I used the quite good 9600 BPS (104 uS per bit) with 8 data bit, one stop bit, no parity.

The firmware in C language is available in a fully working folder with all the necessary files to edit / compile / debug the experiment. Please read the starting point for setting-up the working environment at my previous article here.

The program is very simple. You can use any terminal program on your PC as the controller part, setting the communication speed as mentioned before. You have just two valid commands: AT0<cr> to turn OFF the led on the microcontroller board or AT1<cr> to turn it ON. In both cases you will receive an answer “OK”<cr><lf>. Every different input will produce an answer like “Error”<cr><lf>. The max length of the command string is 4 characters. Look at the terminal window:

Firmware description

First of all, we have to set the options bytes in the STM8S001J microcontroller. We connect the SWIM interface and run the ST programmer. We now modify the AFR1 and AFR0 bits in order to remap the UART_TX on pin PA3 (pin 5). The options can be written from the C program in the micro (it’s almost like write to the EEPROM), but for this test we just use the STM programmer, before loading the test program in the microcontroller. This is the screenshot of the modified option bits:

click the image to enlarge

With the microcontroller’s options programmed in this way, we can try to start debugging the test program. The folder that contain all the files can be downloaded from this link: SingleWire.zip. Please expand the zip file using the program 7Z and the password: eficara.

Now, some details about the C source. First of all, we have to set the port PA3 to be output open-drain. When the serial TX transmits a “zero” the line is pulled down from the internal mosfet; when the TX sends a “one” the line is “open”, so the high level is supplied by the pull-up resistor (10K, see schematic). Here are the C source lines:

After this, we set the UART registers to have 9600,N,8,1 protocol in Single wire, half-duplex mode. In such mode, the micro uses only the I/O PA3 for both TX and RX.

Now we create a function to transmit a character on the serial port. Note that every character sent will be received in the same time ! So, I set a flag called echo that will be used in RX interrupt to discard the data just received (such echoed data will not be stored in RX queue).

It’s better to take a look at the RX interrupt to clarify the concept. The serial RX interrupt will save the received data in a circular buffer. If the echo flag is set, the received data is NOT stored, so it is filtered out.

The data stored in the circular RX buffer will be used to fill the command buffer that is asynchronously handled in the main program as part of TimedEvents.

If head and tail pointer of the circular buffer are different, there is some data pending, so the data is taken from the buffer and the tail index is incremented. The received data is then compared with 0x0D (the CR) and if it’s equal, the received command can be executed. Note that the program also tries to execute the program if the buffer is filled (command too long). The command execution is very simple (this is just a proof of concept !). Look at the parser:

So, the accepted commands are “AT0” and “AT1” followed by CR,  that respectively turn OFF and ON the led on PB4. You can read all of the program on the main.c and stm8_interrupt_vector.c files in the project folder. Hope it will be interesting for you. Have fun!

GATC_note – convert text to DNA

Modified: 2018 Jun 30

Many years ago I saw a movie named “GATTACA”. The film was based on a novel where a man with some “defects” in his DNA was excluded from the crew of a stellar mission (due to such defects). That man, using a trick (exchanging his DNA with another one coming from a friend genetically perfect, but unable to walk after an accident) finally was accepted and started his journey to the stars.

Why “GATTACA” ? The answer is simple: the DNA has only 4 elements (I don’t know their exact names, try Google search for full information) named A, C, G, T. Such four elements, sequentially disposed on a “string”, are able to describe THE LIFE. The DNA is like a program with all the instructions to build the life in its wide range of forms.

When I discovered that just 4 letters are used for the “strings of life”, I immediatly thought about a byte. In one byte (8 bit) I can save four symbols. Many years later (three years ago) I realized a small Internet connected device and decided to use a special coding to transmit the data from the microcontroller to the webserver and so I encoded every byte as a string of 4 characters “A”,”C”,”G”,”T” sending the packet as simple ASCII string. Obviously, the byte array was small and was previously encoded with my own key. It was just an experiment, easy to implement in the microcontroller C program and in the receiving PHP script on the server.

Well, last week I have seen on TV that some scientist are studying the way to save huge amount of information on molecular support, using the DNA structure! So, we will have many terabytes of data on a very small organic  support. I don’t know when it can be ready for the public, but is a very exciting idea for data storing. I just can’t imagine how a “reader” for such data can be realized, but in the meantime I decided to write a small App for Android to “translate” a text in “DNA code” form. This is the App icon:

The App is simply a text editor that can convert from text to “DNA code” and viceversa pressing a button. It’s funny and you can save some “sensitive” data on your smartphone with this special encoding. Note that the coding / decoding algorithm is VERY easy and any “decent” programmer will break and decode the text in few minutes, so don’t use this way to store your precious bank accounts! It’s just a funny way to save the data with a “futuristic” look.

Here is the screenshot of a text written in the edit box:

And now, look what happens when I press the button “GATC it !”:

The operation is reversible: if I tap again the button “GATC it!” the “DNA code” reverts to normal text. There are buttons to save / load the files to / from the smartphone’s memory. The files are saved in the program directory that is named GATC_note/. You can save or retrieve files to / from the directory connecting the smartphone to the computer as an USB memory. Note that the files are in Android format, so the line terminator is simply LF and not CRLF as in Windows Notepad.

Modified in GATC_note V0.2 >> Note the “double colon” at the end of the “DNA code”: this is appended by the program as a marker in order to recognize that the text is “GATC code”. I changed such marker from “Black Star” (Unicode 9733 decimal) of previous release to “double colon” in order to make easier editing GATC text (for experiments). I added also a check for the text length (in GATC mode) ‘cause such text must be multiple of 4 in length (4 GATC symbols = 1 Byte). Finally, I modified the text entry in order to avoid that the keyboard can overlap the text (in case of long strings).

Using just one byte for character has a limit: not all the characters in the edit text can’t be decoded. Only the characters with code from 0 to 255 can be represented with 4 characters ACGT. In case of characters out-of-bounds, the program will set a message dialog asking you if you want to accept the limits (changing the extra characters in blanks) or if you refuse to exchange. This is the screenshot of the dialog:

The “load” and “save” buttons are used to save and load files. You can save files in text or DNA format. The only difference is that ANY file that ends with the “black star” is considered as “DNA”, otherways is a text file. Pressing a file name for long time calls the “delete” procedure and you can decide to erase a file from your smartphone’s memory.

The App has been published on my Google Play developer page at this link: https://play.google.com/store/apps/details?id=robotop.gatcnote. It’s absolutely free and without any advertisement. If you find some error or if you wish for new features to add, send me a message. I will try to improve / debug the program in my free time.

If someone has a true DNA to convert with the program and then discovers that the converted data contains some useful instructions to develop a special anti-gravitational machine, please invite me (for free) to the first interstellar journey on a starship that uses such new technology, thank you.

IrSwitch: remote switch uses any TV controller (IR)

After my recent tutorial (in Italian language) for the STM8S microcontroller, I decided to realize a small device using the STM8S001J (8 pins) microcontroller, in order to expand the tutorial itself. This device has a practical application: I don’t live anymore in a B&B, but in a “residence” and I’m going to solve the problems that I face in this new location. The first problem to solve is that I don’t have any switch close to my bed to turn off the lights when I go to sleep. So, I decided to make a remotely controlled switch. Well, I don’t want to build also a remote controller, so I used the one that currently works for the TV.

This remote switch is based on IR reception from any TV controller that has a protocol like the NEC or equivalent. The schematic is very simple as you can see in the picture here below (click this link to download the schematic in PDF format):

The question is: how can I control my switch without disturbing my TV (or viceversa) ? I don’t want to read a specific keycode coming from TV remote; I just want to detect that one key has been pressed (or released), I don’t mind what key.

The algorithm is very simple. Look at these steps:

– define “key pressed” event as an IR burst detected for at least 3mS (the NEC protocol has 4.5mS header, even in repeated keycode). After the header there is the data, followed by a pause (no signal) for at least 20mS.
– define “key released” event as the absence of any “key pressed” event for a certain time.

This part of the algorithm is executed in the TIM4 interrupt (1mS tick). The IRIN is the input connected to the IR receiver TSOP4838 that gives a low output when a 38KHz burst is received.

The next steps are executed in the main program (TimedActions) every 256mS:
– wait for “key pressed” event

If the “key pressed” event arises, the red led turns ON, the state machine goes to the next state and a time counter of 8 * 256 mS is started. In such time no others “key pressed” events must occur or the time counter will be restarted.

– wait for “key release” event

– start a “time window” of 8 * 256mS (with red led blinking) where you can press a key to toggle the remote switch

If a key is pressed in this time, the relay toggles and the state machine immediatly changes to the next step. In any case, this step terminates with the red led off and a delay of 4 * 256mS in which no events are taken.

– close the “time window” and restart from idle

That’s all. The remote switch will be activated by any key pressed on your TV remote control. The red led light will turn on and stay on for all the time you continuously press the key. When you release the key, the red led will blink for 2 seconds and any key pressed in such time will toggle the relay. If you don’t press any key while the led is blinking, the command will be aborted and the cycle will start again. I assumed that when you use the remote control for the TV, you often press the key for a short time (as for program change) or repeatly (such in volume control). Using the “time window” after key released is a good way to activate the remote switch without disturbing the TV and viceversa. If you have on your TV remote control some “special key” that hasn’t any relevant effect on the video, use it ! Obviously, if the TV is turned off, you can use any button excluding the “ON” 🙂 that will turn on the TV set !

The full project folder is available for download from here: IrSwitch. Please, use the 7Z program with password: eficara to decompress it. Look at the STM8 tutorial for the working environment. You have the C sources, so you will be able to improve, modify or completely change the algorithm that I developed for my specific situation. Have fun !

Sviluppare in C per STM8

Di recente ho fatto una ricerca in Internet per trovare il microcontrollore più economico. Tale ricerca è stata effettuata sui siti dei maggiori distributori professionali di componenti elettronici ed il risultato è stato chiarissimo: il micro più economico (per quantità da produzione) è lo STM8.

Le versioni disponibili sono tante, ma rimanendo sul principio del “very cheap”, ho selezionato due modelli. Il primo è lo STM8S001J3M3 (8 pin) e il secondo lo STM8S103F3P6 (20 pin). Per vostra informazione, il secondo si trova anche montato su delle piccole schede di sviluppo, di manifattura Cinese, disponibili on-line a 1 Euro! Sì, con 1 Euro comprate una scheda di sviluppo che comprende: il microcontrollore, una presa microUSB per l’alimentazione, un regolatore di tensione a 3.3V, un pulsantino di reset e un paio di leds. La scheda ha inoltre i connettori “strip” a passo 2.54mm per collegare le vostre periferiche agli I/O disponibili.

Per poter caricare e testare i vostri programmi sul microcontrollore, avete poi bisogno dello strumento hardware che svolge le funzioni di programmer / debugger. Bene, questo strumento (che potete trovare cercando: ST-Link V2) si compra on-line, sempre di produzione Cinese, a meno di 2 Euro! Sì, programmare e fare debug in real-time per meno di 2 Euro! E’ incredibile. Io iniziai la mia carriera sul sistema di sviluppo Intel nel 1977 e ricordo che il “blue box” costava quanto un’automobile di media cilindrata… Se siete curiosi di vedere com’era fatto, potrete trovarlo in una foto del mio ufficio di progettazione (nel 1979) a destra di un me stesso assai più giovane e magro 🙂 Quell’oggetto che sembra un PC, ma non lo è, perché il PC ancora non esisteva, è in effetti il sistema di sviluppo Intel per microprocessori 8080/8085.

Torniamo ad oggi: ho comprato il modulo con il microcontrollore e quello con il programmatore, ma poi ho deciso di montare anche un circuitino tutto mio su una scheda per prototipi. La ragione di questa decisione è la necessità di testare il micro più piccolo, quello con soli 8 pin, che dovrà andare a sostituire modelli analoghi in alcuni miei progetti di produzione industriale.

Il sistema di sviluppo completo. Programmer/Debugger e microcontrollore STM8S001J3M3

Il microcontrollore piccolo (STM8S001J3M3) ha alcune limitazioni e presenta dei rischi. Se programmato con impostazioni errate delle porte di I/O, diventa irrecuperabilmente bloccato e non più riprogrammabile! Questo problema non si presenta con il modello a 20 pin e più avanti vedremo perché.

Gli strumenti software

Ora che abbiamo tutto il necessario per quanto riguarda l’hardware, possiamo pensare al software. Anche in questo caso avremo delle liete sorprese. Tutto (e dico tutto) è disponibile gratuitamente! Abbiamo a disposizione l’ambiente di sviluppo (IDE) e il software per caricare il programma sul microcontrollore forniti direttamente dalla ST e il compilatore C (completo e senza limitazioni) fornito dalla Cosmic. Per scaricare i pacchetti software è necessaria una registrazione, ma è gratuita. Quindi, facciamo i conti: 1 Euro per il modulino di test, 2 Euro per il programmatore e zero Euro per il software di sviluppo… Con 3 Euro possiamo scrivere software in C ed effettuare il debug in real-time. Beh, non è caro! 🙂

Ecco i link che vi propongo per leggere la documentazione (abbondante) e scaricare il software:

-sito principale con le informazioni ed i vari documenti disponibili: http://www.st.com/en/development-tools/stm8-software-development-tools.html

-pagina di download del programmatore STVP-STM8: http://www.st.com/content/st_com/en/products/development-tools/software-development-tools/stm8-software-development-tools/stm8-programmers/stvp-stm8.html

-pagina di download dell’ambiente di sviluppo IDE STVD-STM8: http://www.st.com/content/st_com/en/products/development-tools/software-development-tools/stm8-software-development-tools/stm8-programmers/stvd-stm8.html

-pagina di download del compilatore C di Cosmic: http://cosmicsoftware.com/download_stm8_free.php

Come anticipato, per poter effettuare i downloads sarà necessaria una rapida registrazione gratuita sia sul sito ST che sul Cosmic.

Oltre al software scaricato, conviene procurarsi subito tre PDF molto utili. Il primo è il datasheet del componente e si chiama stm8s001j3.pdf; il secondo è la lista dettagliata dei registri delle periferiche e si chiama RM0016.pdf; il terzo è il manuale di programmazione con le istruzioni assembler e si chiama PM0044.pdf. Inserendo i nomi elencati in un motore di ricerca, troverete i link per il download. Probabilmente l’ultimo file non vi servirà per scrivere applicazioni “normali”, ma se volete capire bene come funziona un micro (qualsiasi micro), date sempre una lettura approfondita alle sue istruzioni assembler, ai modi di indirizzamento, eccetera.

Installazione

Per prima cosa installiamo il compilatore Cosmic C. Ad installazione avvenuta vedremo che abbiamo a disposizione sia il compilatore per STM8 (completo e senza limiti) che quello per STM32. Quest’ultimo, però, ha un limite di 32K (sufficienti, comunque, per molte applicazioni). Si noti che il compilatore installato ha anche un suo IDE (chiamato IDEA-STM8) e potrebbe quindi essere usato come strumento di sviluppo completo, senza usare i software ST. Io ho deciso di usare l’IDE ST, ma è stata solo una scelta personale. Nulla vieta di utilizzare l’ambiente Cosmic, ma gli esempi che pubblicherò di seguito sono stati scritti per quello ST.

Oltre ad aver fatto la registrazione al sito Cosmic, dovremo ora ottenere la licenza (gratuita) per il compilatore. Per far ciò dobbiamo andare nella cartella dove è installato il compilatore e cercare il programma apposito:

C:\Program Files\COSMIC\FSE_Compilers\CXSTM8\LmregFSE.exe

Ovviamente, il percorso è valido se il programma è stato installato su C:\Program Files. Lanciando l’applicazione, troveremo dei campi da riempire.

Inseriamo quindi i nostri dati e clicchiamo il pulsante On the Web. Riceveremo quindi sulla nostra email un file di licenza da copiare nella directory di installazione del compilatore (notate che ho salvato anche il file lic-data che contiene i dati inviati per ottenere la licenza, giusto per avere un riferimento futuro).

Se non eseguiamo questa operazione oppure se copiamo il file di licenza su di un altro computer, all’atto della compilazione di un sorgente in C riceveremo questo errore (cliccare l’immagine per ingrandire):

Quindi, se cambiamo PC e reinstalliamo il compilatore, dovremo eseguire nuovamente la fase di richiesta della licenza.

Ora installiamo i due software ST che abbiamo scaricato in precedenza e cioè il programmatore e l’IDE. Qui non dovremo effettuare alcuna richiesta di licenza. Al termine di tutte le installazioni troveremo sul nostro desktop tre nuove icone.

Lanciamo l’IDE (icona centrale) e iniziamo a prendere confidenza con l’ambiente. Nella figura sottostante vediamo il programma aperto sullo spazio di lavoro (workspace) chiamato Test. In genere, per progetti semplici come sono quelli da pochi KB di codice, io uso lo stesso nome sia per lo spazio di lavoro che per il progetto. Proviamo quindi ad aprire il tab Project e selezioniamo dalla lista la voce Settings.

Si aprirà quindi la finestra delle impostazioni. Nella figura successiva è mostrato il primo tab (General) relativo alla configurazione Release, cioè quella finale, destinata alla produzione. In alto a sinistra (dove c’è scritto Settings for: Release) è possibile cambiare la selezione in Debug, quella che sarà utilizzata nella fase di sviluppo del programma.

Possiamo lasciare gran parte delle impostazioni standard, limitandoci a scegliere solo il tipo di microcontrollore da usare (tab MCU Selection), permettendo così al sistema di utilizzare i valori di default ad esso collegati.

Hardware

Ora possiamo iniziare con l’hardware. Lo schema del circuito minimo è quello visibile nella figura sottostante (cliccare l’immagine per ingrandirla).

Come vedete, è davvero molto semplice e si può montare su una scheda per prototipi, utilizzando per il microcontrollore un adattatore da SO8N a DIL, reperibile on-line a costo minimo. Se invece vi dilettate di fotoincisione, potete usare il piccolo PCB che ho disegnato.

Il PDF in scala 1:1 per effettuare la fotoincisione (singola faccia, lato rame) può essere
scaricato da questo link (file Top.pdf)

Come si vede dallo schema elettrico, i (pochi) pin di I/O disponibili sono assegnati a più porte del micocontrollore. Questo significa che i pin sono fisicamente collegati a più I/O in parallelo.Questo non è un problema al momento del reset, in quanto tutte le linee di I/O del micro si settano automaticamente come inputs ad alta impedenza. Ovviamente, se durante la fase di inizializzazione dell’I/O del nostro programma mettiamo due linee parallelate in stato di Output push-pull e diamo ad una il valore “basso” e all’altra “alto”, facciamo una gran brutta cosa! Bisogna quindi fare attenzione. Da un certo punto di vista, il fatto di avere delle linee di I/O parallelate può essere un vantaggio: per esempio, possiamo ottenere da un pin di output una corrente maggiore se pilotiamo contemporaneamente due o più porte. Se usiamo il pin 7 e settiamo le porte PC3, PC4 e PC5 come outputs push-pull (pilotando le linee contemporaneamente tutte alte o basse), potremo ottenere una corrente tripla, rispetto a quella di una singola porta.

Questo può essere molto utile, per esempio, per pilotare un mosfet di potenza. Il problema dei pin parallelati si fa sentire in modo pesante sul pin 8, non a caso il più parallelato di tutti. Ci sono ben 4 porte del micro collegate allo stesso pin e purtroppo è anche il pin di SWIM, cioè l’interfaccia di programmazione / debug, quella che ci permette di scaricare / debuggare il nostro firmware. Cosa succede se nel nostro programma assegniamo ad una delle porte PC6, PD1, PD3 e PD5 la funzione di output push-pull? Semplice: lo SWIM non funziona più e il micro è bloccato per sempre. Ho tentato mille manovre, sperando di recuperarlo (sì, ho fatto un errore anch’io) e non è stato possibile. Ho tentato anche di alimentare il micro sotto la tensione di brown-out per sfruttare il reset in tale condizione, ma non c’è stato niente da fare. Attenzione: se notate, la porta PD5 è usata anche come linea di trasmissione della UART e così se userete la porta seriale nel vostro programma, al momento del set-up del relativo registro di controllo automaticamente bloccherete il micro e dovrete dissaldarlo e buttarlo via (è quello che è successo a me).
La ST suggerisce (fatelo) di inserire all’inizio del programma, proprio al reset, una pausa di circa 5 secondi prima di fare qualsiasi operazione di inizializzazione di porte e registri. In questo tempo lo SWIM funzionerà di sicuro e quindi vi sarà possibile riscrivere un programma opportunamente corretto, in caso di errori. Ovviamente è una cosa un po’ limitativa, perché 5 secondi di attesa al power-on sono inaccettabili per qualsiasi progetto industriale, ma quando questo sarà completamente testato, potrete rimuovere la pausa iniziale di 5 secondi, con la consapevolezza, però, di avere un micro OTP (One Time Programmable). Un vero peccato, specie perché la UART a bordo di un micro così piccolo ed economico è un bel “plus”. Si noti che la UART può essere “rimappata”su un altro pin (il 5, connesso a PA3). Infatti, dovendo usare la UART, la mia idea è stata subito quella di rimappare su PA3 lo UART1_TX eliminando così il problema della sovrapposizione con lo SWIM. Il remap si può eseguire tramite i registri di configurazione (con il programmatore) e quindi credevo di aver risolto i miei problemi. Purtroppo, dopo aver fatto il remap, il segnale di UART1_TX era presente (trasmissione dei caratteri OK), ma la ricezione sul pin 1 (PD6) non funzionava assolutamente. Ho provato in mille modi, cercando di capire perché nessuno dei “flag” relativi alla ricezione seriale o agli errori venisse settato, nonostante le impostazioni fossero corrette (e confermate dai segnali che uscivano regolarmente da TXD). Alla fine sono andato sul forum della ST e lì ho trovato altra gente col medesimo problema. Ho aggiunto la mia esperienza e le mie considerazioni (https://community.st.com/thread/46397-stm8s001j3-uart-remap e https://community.st.com/thread/47302-stm8s001the-uart-of-alternate-function-after-remapunable-to-receive), chiedendo che qualcuno degli esperti tecnici ST intervenisse per dare una risposta, ma non si è fatto vivo nessuno.  Per quanto ne so, al momento, il remapping della UART non funziona. Aggiornamento del 29/06/2018: un tecnico della ST ha risposto al quesito confermando la mia ipotesi. Il pin RX viene anch’esso rimappato, ma su un I/O non accessibile. La UART potrebbe quindi essere utilizzabile solo in modo single-wire / half-duplex. Per usare la UART sul pin “naturale”,  dovete quindi considerare che il ritardo iniziale di 5 secondi DEVE essere inserito, prima di effettuarne l’abilitazione, oppure butterete via un sacco di microcontrollori.
In fase di produzione, quando il ritardo di 5 secondi al power-on sarà inaccettabile, suggerisco di inserire nella routine di ricezione seriale, la decodifica di un comando “speciale”, per esempio +++ e Ctrl-C. Quando il programma riceverà questa sequenza, dovrà disabilitare la UART e rimanere in un loop infinito. In questa condizione sarà possibile usare di nuovo lo SWIM e riprogrammare il micro. E’ uno sporco trucco e sarebbe molto meglio se il remapping venisse risolto o se la porta PD5 venisse mappata altrove (per esempio sul pin 6), ma questo significa aspettare una nuova maschera del chip (se pure qualcuno della ST si convincesse a farla).

Il primo programma

Iniziamo con il primo programma, un classico “led blinker” che ci permette di testare alcune funzioni base, tra cui l’interrupt del Timer 4. L’intera cartella di progetto si può scaricare da questo link. Il file è zippato; per decomprimerlo usare il programma 7Z e la password: eficara.

Mettete la cartella scompattata in una directory di lavoro, per esempio documenti/progetti STM8. Al suo interno troverete questi files:


Cliccate sul file Test.stw e il sistema vi chiederà (dato che l’estensione .stw non è associata) con quale programma volete aprire il file. Allora andate sul percorso evidenziato nella figura sotto e scegliete l’IDE della ST.

A questo punto l’IDE si aprirà e subito vi verrà richiesto dove si trova il file di licenza del compilatore C Cosmic.

Cliccando next si aprirà un dialogo di navigazione dei files e voi andrete a specificare la cartella License che abbiamo visto in precedenza. Fornito il percorso verso il file di licenza, tutto è pronto all’uso. Colleghiamo quindi ad una porta USB il nostro programmatore / emulatore compatibile ST-Link V2. Verrà subito riconosciuto dal sistema e il driver verrà scaricato da internet. Associamo quindi il debugger all’IDE cliccando sul tab Debug Instrument.

Ora siamo pronti. Nella finestra a sinistra troviamo i files sorgenti in C che sono inclusi nel progetto e che sono main.c e stm8_interrupt_vector.c. Clicchiamo sull’uno e sull’altro ed entrambi verrano aperti nella finestra di edit a destra, con due differenti tabs. A questo punto lanciamo la compilazione cliccando il “compila tutto”.

Se tutto è stato impostato correttamente, non avremo errori di compilazione. Ora colleghiamo il nostro circuito di test all’emulatore ST-Link. Useremo i 3 fili GND, SWIM e 3.3V (oppure 5V). In questo modo il circuito verrà alimentato direttamente dall’emulatore. Si noti che l’emulatore ST-Link V2 “vero“, quello di serie fornito dalla casa madre, NON ha l’uscita di tensione attiva, anzi, presume che il circuito sia alimentato dall’esterno. Questo è certamente più corretto, in quanto la circuiteria interna deve “adattarsi” alla tensione di alimentazione del DUT (Device Under Test). Nel nostro caso, abbiamo speso poco e ci accontentiamo di una soluzione tecnica meno precisa…

Avviamo quindi il debug cliccando l’apposita icona.

La versione del programma appena compilata verrà trasferita nel microcontrollore. Al termine del trasferimento potremo avviare l’esecuzione del firmware cliccando l’apposito pulsante (run).

Aspettiamo i famosi 5 secondi che precedono l’esecuzione del programma vero e proprio e poi vedremo lampeggiare il LED sul circuito. Se lampeggia, è tutto a posto. Potremo d’ora in poi sviluppare le nostre applicazioni utilizzando questo bell’ambiente di lavoro completamente gratuito.

Analisi del file sorgente in C

Diamo ora una rapida scorsa al listato dei files sorgenti in C, iniziando da main.c:

Qui vediamo alcune definizioni che uso per mantenere la compatibilità con altri compilatori (per altri microcontrollori) che uso abitualmente. Per esempio, definisco _CLI() come _asm(“SIM”) perché con altri microcontrollori uso questa istruzione per disabilitare gli interrupts; così posso passare più facilmente da un listato scritto per un micro ad un altro modificando solo i define iniziali. Stesso discorso vale per BYTE e WORD al posto di unsigned char e unsigned int. Si tratta quindi di una mera “traduzione”.

Qui ho indicato il file di header da includere. Questo contiene tutte le definizioni relative allo specifico microcontrollore. Bisogna stare attenti al file che si include: se si usa il generico iostm8s.h, per esempio, i registri del timer TIM4 risultano all’indirizzo sbagliato e quindi il timer non funzionerà!

Qui ho definito una costante che userò nel caricamento di un registro del timer TIM4 per ottenere un “tick” di 1mS.

Qui ho definito una variabile bit (boolean) che corrisponde al bit 4 del registro PB_ODR, che è in pratica la PortB (out). In questo modo potrò usare il simbolo RLED per fare riferimento alla linea di I/O.

Qui ho definito due variabili BYTE che userò nel programma. La keyword “volatile” sta ad indicare che il compilatore non dovrà fare ottimizzazioni su di esse. Conviene usare sempre questa modalità per variabili che vengono usate sia in interrupt che nel main (contatori, flags, eccetera).

Ecco il “corpo” dell’interrupt relativo al timer TIM4. La funzione viene eseguita con un timing di 1mS. Notate la riga 49, dove il flag relativo all’interrupt attivo viene resettato. Se non lo si resetta, il programma continuerà ad eseguire interrupts a valanga! Nelle istruzioni successive si incrementa un contatore e quando il nuovo valore vale 0 (incremento da 255 +1), viene settato il flag “flag250ms” che verrà usato nel main successivamente. Questo è solo un esempio d’uso, la stessa funzione può essere realizzata in mille modi!

Questa è la funzione chiamata ciclicamente dal main. Il suo nome è TimedEvents perché abitualmente creo una serie di task non bloccanti, ognuno dei quali si occupa di eseguire le proprie operazioni e quindi rientra al main. In questo caso, la funzione ritorna senza fare nulla se il flag250ms non è settato. In caso contrario, il flag viene resettato e viene eseguito il compito “a tempo” (cambio di stato del Led rosso). Si notino le istruzioni _CLI() prima e _SEI() dopo il reset della variabile flag. Per ogni variabile utilizzata sia nel main che nell’interrupt è necessario fare in modo che non ci possano essere scritture in interrupt mentre il main ne sta eseguendo un’altra. Insomma, è un modo come un altro per dare un accesso esclusivo o protetto ad una variabile.

Ecco il “main” vero e proprio. Al reset del micro, si parte da qui. Notiamo una serie di istruzioni ASM che servono per effettuare il famoso ritardo di circa 5 secondi. Il codice avrebbe potuto essere scritto in C, ma ho voluto mostrare come sia possibile utilizzare il compilatore anche per scrivere piccole parti in assembler. Nello specifico, troviamo due loop annidati l’uno dentro l’altro. All’inizio, vengono salvati sullo stack i registri X (16 bits) ed A (8 bit); poi in X viene caricato il valore immediato 0xFFFF e in A il valore 50, quindi il registro A viene decrementato finché non diventa 0 e a questo punto si decrementa il registro X e si torna a settare A col valore 50, fino a quando anche X non arriva a zero. A questo punto i valori iniziali di X ed A vengono recuperati dallo stack e il ritardo è finito. Si passa quindi alla prossima istruzione del codice C.

Nelle linee subito dopo il ritardo iniziale settiamo i valori per i registri che ci interessano. Alla linea 84 forziamo il clock del sistema dall’iniziale 16MHz/8 (2MHz) al più veloce 16MHz/1. Poi impostiamo le porte; non tocchiamo la PortA, la PortC e la PortD perché sono già messe in input automaticamente al reset. Sulla PortB forziamo PB4 a diventare un output, perché ci sarà collegato un led. Attenzione, le linee che possono diventare segnali IIC bus, non sono push-pull, ma open-drain. Dopo l’I/O settiamo infine il timer TIM4 in modo da prendere come prescaler il valore 128 (2 alla 7) e lo forziamo a resettarsi al valore TOP1MS, con il risultato di avere un overflow  (e quindi un interrupt) ogni 1mS.

Infine, ecco il “magro” main loop. Nelle applicazioni “serie”, all’interno del while(1) si mette un reset del watchdog, per fare in modo che le varie funzioni (o i vari tasks) richiamati, siano sotto controllo. Infatti, se una di esse non ritorna al main nel tempo impostato per il watchdog, il micro si resetta e riprende il suo normale ciclo. Ovviamente, è utile tener traccia di questi errori salvando (magari in EEPROM) le condizioni per cui si è avuto un watchdog reset. In un programma ben strutturato, il loop principale sarà sempre una serie di chiamate alle funzioni “concorrenti”, il più semplice possibile.

Vediamo ora l’altro file sorgente che fa parte del progetto: lo stm8_interrupt_vector.c

Alla linea 1 viene definito un nuovo “tipo” di variabile, che è un puntatore alla funzione di interrupt. Poi viene definita una struttura che ci dice che un vettore di interrupt è composto da un byte (il codice ASM relativo alla call interrupt) seguito dall’indirizzo di memoria in cui la funzione è allocata. Ancora dopo, viene definita una funzione di interrupt “fittizia”, che sarà usata per riempire la tabella dei vettori di interrupt nei punti che non usiamo (tutti gli interrupts non utilizzati). Inserendo, in fase di debug, un breakpoint sul “return” (linea 10), potremo accorgerci se qualcosa di imprevisto accade. Per esempio, se abbiamo abilitato un interrupt su un pin di I/O e non abbiamo scritto la relativa procedura, avremo un breakpoint che ci avvisa dell’errore. Infine abbiamo la definizione di _stext() che è la funzione chiamata al reset e che contiene il codice di inizializzazione aggiunto dal compilatore C in base al modello di compilazione richiesto e per ultimo un riferimento alla funzione di interrupt _TIM4_OVF che abbiamo visto sul main. Dato che questa funzione è esterna al modulo stm8_interrupt_vector.c, viene appunto definita come “extern” e sarà il linker ad assegnare l’indirizzo giusto, al termine della compilazione.

E finalmente ecco i “vettori” di interrupt. In pratica, dall’indirizzo 0x8000 (il vettore di reset) a 0x807C (riservato ad irq29) abbiamo una serie di [0x82 0xnn 0xnn 0xnn] dove 0x82 è l’istruzione di call interrupt e i restanti 3 bytes sono l’indirizzo in cui la routine è stata allocata. Un interrupt da timer TIM4, per esempio, provocherà un cambio del program counter dalla locazione corrente verso l’indirizzo 0x8064 con conseguente chiamata della funzione di interrupt. Chiaramente, la chiamata di un interrupt ha come differenza da una chiamata di subroutine qualsiasi, il salvataggio automatico di alcuni registri essenziali, che vengono poi rimessi a posto al termine della routine stessa (anche il return di un interrupt è diverso dal return di una subroutine).

Conclusioni

Faccio presente che tutto ciò che ho scritto (a parte i problemi di blocco del microcontrollore) vale anche per gli altri modelli di STM8, basta cambiare le impostazioni del compilatore (scegliendo il tipo adatto nell’IDE) e il file di header selezionato nel sorgente main.c. In futuro, nel mio tempo libero, aggiungerò altri esempi (un po’ più elaborati) di firmware scritto in C per la serie STM8.

A presto…

Invention #6: the (c) WaterShadow

This device is composed by an orange box of 36x24x12 cm. On the top of the box there is a solar cell, capable of charging the internal batteries and powering the electronic circuit inside; in the bottom part there are two small but powerful electric motors with propellers and two ultrasonic sensitive microphones. The internal part of the box is almost all available to the user: you can put in it your car’s keys, documents, usb keys, cellphone, bath towel etcetera. The all box is fully waterproof, thanks to neoprene seals. Another fundamental part of this invention is the wrist bracelet with special ultrasonic emitting capsule. When you want to swim and you have precious things, and you don’t want to leave them abandoned on the beach, put all inside your WaterShadow box and wear the bracelet. Then go into the water and take with you the orange box. When in the water, the box will follow you everywhere, using his double ultrasonic microphones for tracking your emitting bracelet. Have a nice swim and forget any problems.

Special notes:
1) If you swim too slowly, the WaterShadow can overtake you, and sometimes can play an “hurry up” with the embedded loudspeakers.
2) Some californian scientist asserts that the ultrasonic beep emitted by the bracelet can attract male sharks, but I can calm down you, it’s not true. It can attract only female whales.

P.S. Have a nice April First and eat some mellons taken from my tree

Do you want to read more “Probably True” stories ? Take a look at my Probably True Corner

Domenica: imparare codici di radiocomandi sconosciuti

La scorsa domenica ho costruito un piccolo circuito per imparare i codici trasmessi da un radiocomando di cui non conoscevo le caratteristiche. Nel video trovate una breve descrizione del funzionamento. Il circuito è praticamente identico a quello che ho già pubblicato sul mio sito (RxMet1 – ricevitore per sensore esterno Hygro-Thermo a 433 MHz) e sulla rivista CQ elettronica nel 2007. La decodifica del protocollo del sensore umidità/temperatura fu allora molto più difficile, dato che non c’era alcuna informazione disponibile su internet (esisteva la descrizione di un protocollo precedente, ma era totalmente diverso). Quell’esperienza, però, mi è servita a produrre questo giocattolino perfettamente funzionante in un noioso pomeriggio domenicale.

WiFi to IR interface

Last update: 2018-02-25 15:30 (See the note at end)

Once again a project realized in the B&B during my free time, far from home. The circuit described here will be capable to drive almost any device that currently uses an IR remote control, by means of WiFi connection, as to say: with your smartphone. This time I want to show all the route from the idea to the running device. I had the idea some years ago (look at my previous articles regarding IR and WiFi), but I completely forgot it until today.

When I start a new project, there is the first step that I call: “sofa time”. I spend such time lying down on the sofa, without any computer, pen, document or tool. I just think about how to realize the project with the minimal effort.

After this time, I take a block-notes and draw with a pencil (or a pen) a very minimal schematic. In practice, it’s just a brief list of essential connections for the various components that I’m going to use. Here is such minimal schematic:

I don’t need a full schematic, at this time. I will draw it “seriously” with a CAD in the final steps. Well, now I can start building the prototype. First of all I search in my “junk box” what components are available and eventually I change the schematic in order to make it possible to be realized with available components. Usually my laboratory is very complete, but currently I have only few parts, being far from home. This is the prototype, wired on a proto board :

If you are curious to see how this circuit is wired, look at the bottom part :

Note the presence of some SMD components. Sometimes I put such components mixed with the through-hole parts for space saving or just to substitute missing parts of the required value. It’s a simple circuit, but requires soldering skills to be built !

Did you noticed that I used a 16MHz crystal? Did you also noticed that I used a linear 3.3V regulator for powering the microcontroller ATmega88 and the WiFi module ESP-01? Well, there is a mistake ! A 16 MHz crystal is out of specs at 3.3V as you can see in the next picture:

The diagram is taken from the ATmega88 datasheet and says that the maximum crystal frequency at 3.3V is about 13.3MHz, evaluated with dF=(20-10)MHz and dV=(4.5-2.7)V. The nearest value that I have in my junk box is 12.288MHz, then I’m going to replace the component onto the circuit (it will be an easy job).

I plan to power my circuit with a 5V wall adapter, probably a phone charger, but during the tests I will use a Li-Ion battery, just to limit the number of cables on my unfair working place. Note that the LM1117-3.3 IC does NOT stabilize very well with the power supply taken from a Li-Ion battery. Look at this picture taken from the component’s datasheet :

A fully charged battery has 4.2V voltage, so it’s under the minimal dropout at 100mA to have a stable 3.3V output. Consider that the ESP-01 can have current peaks greater than 250mA, so the regulator output may be unstable. This situation will degrade more when the battery discharges to 3.7V (its nominal voltage) and the residual charge is about 10% of the nominal capacity. I used a 100uF capacitor connected to the ESP-01 power lines in order to absorb part of the current spikes in WiFi transmission and if necessary I will increase such capacity. In the “real life” the circuit, powered with a 5V-700mA wall adapter, will work fine ; for this test version I can accept some limitations.

Here is the first version of the circuit schematic (still subject to change):

For a better view, you can download the drawing in PDF format from this link. The pinout for the wifi module ESP-01 in the schematic diagram corresponds to this figure:

Note: if you want to replicate this project, you must program the ESP-01 module to use a 9600 BPS communication speed. There is an AT version created with such default speed on this website: http://wiki.aprbrother.com/wiki/Firmware_For_ESP8266 ; go there and look for ai-thinker-0.9.5.2-9600.bin. You can also alter (in a permanent way) the current communication speed of your ESP-01 module using AT commands. There are two, that works depending upon the version of firmware installed. Try both of them; the first that gives answer “OK” is the right one.

For additional information and useful SW tools, take a look at my previous articles here:
Interfacciare il modulo ESP-01 con una porta USB
http://ficara.altervista.org/?p=3041
AT-commands tool
http://ficara.altervista.org/?p=3158

The firmware – Part 1

At this moment I don’t want to write an App to test the device, so the first version of the firmware contains a very basic webserver, just to check if I can connect to the device with my smartphone using the default browser. The first release of the firmware (about 3 KBytes) is available at this link. The file is zipped with password. Use the program 7Z with password: eficara to expand it. The zip contains the .hex file to program the micro and the following image for the fuses map:

When the microcontroller has been programmed, you can try to check if it works. First of all, connect your smartphone to the AP that is presented by the Esp-01 module. You will be informed, obviously, that you are NOT connected to the Internet:

Note that the last 6 characters of the AP SSID will differ from the ones showed in the image, being the representation of last 3 bytes of the MAC address of the module and also the ESP_  part can differ if there is another release of the AT firmware in the module.

After connecting your smartphone to the Esp-01 AP, you can open the default browser and navigate to the single page available on this minimal webserver implementation. Here is an example:The page is always located at 192.168.4.1 (the Esp-01 IP) /cmd.htm (the single implemented web page) and the command ?k= followed by 4 hexadecimal digits. You will receive an html page with the same hex digits. This is just for test purposes. Please note that the hex digits that you will use in your requests must be in capital letters, or you will receive wrong answers:IR protocols – Tools

Now I must indagate the IR protocols that I want to use in this device. Many, many years ago, I realized an IR protocol analyzer under MS-DOS using Borland C and some subroutines in Asm 8086. It worked  with direct I/O control of the pins of a COM port. Here is the hardware I used for IR protocol analysis:

At the left, the “receiver” part ; in the middle, a more recent wired prototype used with a microcontroller and at the right the “transmitter” part, from  the same MS-DOS tools suite.

Well, I will NOT present here such old MS-DOS programs because I have found on the internet a great page published by Ondřej Staněk at this link: http://www.ostan.cz/IR_protocol_analyzer/ that has a freely downloadable tool that is much more complete and powerful than mine. It works under Windows and the involved hardware is very simple to build. Here is a screenshot of the program running on my PC:

The software uses the MIC (audio) input of your PC / Notebook to capture the IR signals from a remote controller. You can use a simple photodiode like this :

My interface, mounted on a 3.5 mm stereo jack

Or, if you can’t find the photodiode, you can try with a normal IR emitter (LED) using this circuit. I made it ‘cause I haven’t any photodiode in my “mobile laboratory”, but I have an IR emitter (LED) mounted on a small proto-board. I tested this unconventional circuit on my notebook and after a couple of tries it worked (the previous screenshot was taken with this interface).

Another detector that uses a normal IR LED as receiver. Don’t consider the other components on the board. Those parts are from another circuit !

Here are some audio settings I used on my notebook in order to make it work:

Here is a list of some articles on my website about the IR remote controls:

WM8650 tablet as remote control for Sony TV
http://ficara.altervista.org/?p=497
Using Android tablet as SIRC remote control (#2)
http://ficara.altervista.org/?p=859
General purpose infrared remote control receiver with RS232 output
http://ficara.altervista.org/?p=1221
Usare lo smartphone come telecomando TV
http://ficara.altervista.org/?p=2426
Un altro telecomando TV per smartphone Android
http://ficara.altervista.org/?p=2908

The firmware – Part 2

Well, I finished this project or, better, this “proof of concept”. It works, I can control my TV using the browser of my smartphone. The IR protocols used here are NEC and RC5. Due to the low power of IR led, driven directly by uC Port with a single resistor, the distance from the device to the TV (or other apparatus) will be 1 meter max. Add a transistor interface if you want long distance.

Note (Feb, 25 2018): I tested the circuit in the picture below and the distance now is over 3.5 meters. I can’t test if it works over 3.5 meters ‘cause my B&B room is very small !

One reader from Hackaday proposed to use multiple output pins in parallel to drive the IR LED with more power.  It’s a good idea, but the software needs to be modified ‘cause I used the SBI I/O,#bit and CBI I/O,#bit instructions respectively to turn OFF (remember, negative logic for LED) and ON the port bit.

Part of the C source (commented ASM listing) – Section: Nec protocol – Xtal: 12.288MHz – Interrupts: disabled

Controlling multiple port bits at the same time needs the OUT I/O,R instruction. Using the OUT instruction also involves to get the port status (in order to save other bits not used for IR led) and save it to 2 different registers, one to be used when you want low level on the IR outputs and the other when you want high level, without affecting the “non IR led” bits. Such approach changes the number of clock cycles needed to generate the 38KHz (Nec) and 36KHz (RC5) frequencies.  This is absolutely not difficult to realize, but at this moment I closed my test firmware, so the transistor solution is simpler.

At power-on (reset) the microcontroller automatically sends one command for testing the NEC and RC5 protocol as you can see in the Main procedure.

After sending the test commands, the main procedure loops in the wifi section (function: Parameters) waiting for commands from any browser. The same IR code used in the test procedure can be sent with the smartphone, with the same  effect.

The command 0x0408 (address, 0x04, cmd 0x08) turns on  or off the TV in my B&B room 🙂 This is the screenshot of the IR tester, splitted in two parts ‘cause is a bit long:

In the Main procedure there is also a transmission of one RC5 code. This is the screenshot of the actual code set (RC5 is smaller)

Note that in order to send RC5 protocol IR commands, you must use another string in the browser. In place of: cmd.htm?k= you must use: cmd.htm?r= . This informs the firmware that the following 4 characters (hex) must be used as address and command for RC5 protocol, not for NEC. Please, remember that the standard RC5 protocol has 5 bits address (0x00..0x1F) and 6 bits command (0x00..0x3F). Codes out of the limits will be cut out with a simple “and” operation.

Finally, the new release of the firmware. It’s only 3034 bytes long. In the zip file you can find the .hex to burn the micro and a picture of the fuses configuration. Download the file from here and use the program 7Z to expand it. The password is: eficara.

Have fun !

Note (Feb,21 2018): this article was linked by Hackaday and then I’ve seen many comments there about the “unuseful” ATmega88 micro used in my circuit. Someone assumed (wrongly) that I used the Arduino IDE to create this project ! Well, there is a big misunderstanding. May be that someone leaves his opinion before reading the article or simply thinks that reading the article is just an option. Ok, I just want to make clear that I wrote all the firmware in C language (some ASM code was optimized to C) and without using any “pre-cooked” library for ESP-01 or IR functions. All the webserver via AT commands and the IR RC5 and NEC protocols are mine, not copied from other people’s works. I know that the Esp8266 itself is a fully programmable device, but my target was to use a preprogrammed part (Ai-Thinker ESP-01 module with AT firmware) and just control that part how it comes “out-of-the-box”, without any modification, to create my “proof of concept”. I also know that there is a Lubuntu virtual machine (VirtualBox) with the complete environment to develop C language applications for the ESP8266. I have such VM enabled and working on my desktop computer, at home.