MeeBlip Anode “Italian Way”: monophonic synthesizer with OLED display (and an overclocking option)

Goooooood evening dear makers! (and, in this case, I hope also musicians! 😉 )

It’s toooooo much time that I work on my projects without new posts, and I apologize for this.

The fact is that I have -as you know- many activities in parallel to making open source *ware projects: my work (I work in the frame of space projects for artificial satellites, for example I uploaded a little part of me on JUNO, and especially on the Italian part of Juno: the JIRAM instrument), my music (I play in some bands, and I also produce a lot of solo music: check it out  and download all at www.marcolastri.net ) … and obviously my family!!! 🙂

So, since time is short… and life is too short, let’s start.

We can start from this beautiful project: Meeblip Anode.

It is a great monophonic synthesizer based on ATMEGA32P, with a really great sound, very deep and powerful.

…Have a look to demos on Youtube for the proof of what I’m writing.

I loved the MeeBlip Anode sound from the first time I heard it. In Italy we call this feeling “Amore al primo ascolto”…. 😀

And to me, the greatest thing of MeeBlip Anode is that this incredible project is completely (hardware and software) open source!!! You can buy a pre-built one, but you can also self-produce it in order to play it with your band or to modify/hack it (or both the things, like me ! 😉 )

Well.  I obviously self-produced one prototype of Anode and I started to play it in my music projects, but I wanted to add some (in my opinion) important functionality to this great project.

The idea has been of my father Gualtiero which, looking me playing with Anode and modifying the position of potentiometers, said to me: “It sounds very good… but… in which way you know the values for potentiometers?”

Woooow, thanks dad! It was the idea: add a numerical/visual indication of pots values using a display. An OLED display (because the OLEDs don’t have the backlight regulation…so less electronics to add! 😉 ).

And I decided to call this mod “Italian Way” because in Italy we always need visual information. For example think to our famous gestures when we (try to) talk in English to tourists to give them indication on the streets of our cities. 😀

So, I decided to proceed in the following way:

  1. Look in the electronic schematic if ATMEGA32P has some free GPIO to be used in order to command the display (at minimum 6  pins, which is the minimum for commanding the great part of displays)
  2. Since the Meeblip code is written in AVR assembler, download and study the datasheet (and instruction set) of the ATMEGA32P. I was a good assembler programmer once upon a time…but now I am a little older, so… 😉
  3. Find a good AVR driver or set of subroutines for commanding display, written in assembler
  4. Decide which synth values to display on the OLED!
  5. Modify these subroutines in order to display in quasi-realtime, and integrate them in the original code
  6. Modify the original Meeblip code in order to use the display subroutines.

Well…the work has been long (long, long, very long and again looooooooong) and hard (hard, very hard… etc.).

But I think it has been a great work! 🙂

I uploaded all the code on GitHub. I dont know if I well done all the process, but this is the first time with GitHub for me…. 😉

For the project I realized a new branch from the official one. So you can download all my code from: https://github.com/garretlabs/meeblip-anode/tree/meeblip_anode_italian_way

The GPIO pins to be used

I had been lucky: the MeeBlip Anode has some free (and not connected) GPIO on the microcontroller, so they can be freely used to command a display.

They are reported in the following photo:

20160415_182624

I decided to use an OLED display by Newhaven ( Mouser code 763-NHD-0420DZW-AG5), which will use 4 pins for data (+ 2 pins for Enable and RS) chosen from PB0, PB1, PB2, PB3, PD2, PD5 and PD6 (plus 5V and GND).

The mapping used for the connection between  the display and the ATMEGA32P has been the following:

  • Display pin 1 (Vdd): VCC
  • Display pin 2 (Gnd): GND
  • Display pin 6 (data 0): PB0
  • Display pin 7 (data 1): PB1
  • Display pin 8 (data 2): PB2
  • Display pin 9 (data 3): PB3
  • Display pin 4 (RS): PD5
  • Display pin 5 (E): PD6

So… I solded the pins of ATMEGA32P to display pins using a 9 pins male/female connection (such as a simple serial connection). The result has been the following:

20160415_133043-1

The datasheet and code study

Simple step…but very tricky! 🙂

Well, during this step I downloaded the Atmel Studio 6 (freely available) and I wrote some example code, I used the debug function on the simulator and then I created a project based on the Meeblip Anode original code downloaded from Github (and obvioulsy I succesfully recompiled it).

The display driver written in AVR assembler and his

I found a really good set of subroutines written in AVR assembler for ATMEGA328 (but it is working also on ATMEGA32P) to command displays using 4 wires. This is the complete code from which I started.

I created the file LCD.inc, and I added it to the Atmel Studio project. Obviously I changed the GPIO assignments in order to match to GPIOs used in my situation. I also added some modification regarding the fact that I would like to display values taken from the RAM of the microcontroller and not from the program memory (as is in the driver). This is the fundamental modification, at line 786 of file LCD.inc:

;lpm     temp_lcd, Z+   ; ///ML: removed since this instruction read from Program Memory
ld    temp_lcd, Z+      ; ////ML: get a character from RAM

And I also added some ad-hoc subroutine to be used in the frame of the modified MeeBlip code. They are the main ones:

  • MYLCD_PREPARE_GUI is the subroutine which prepare the display inserting the fixed labels (they wont change during normal operation of synth).
  • MYLCD_UPDATE is the main subroutine used to refresh the display (pots values and switches status). It refreshes tha display on every 100 milliseconds.
  • MYLCD_CLEAR is used to clear all the display

Note also that in order to display numeric values in the display, a conversion between the values and his correspondent string should be done. For this I found online a very simple subroutine which is called in order to have the values to display in ascii format. This is the subroutine contained in the file SimpleASCIIConversion.inc:

HEX_2_ASCII:
bcd: 
   ldi r18, -1 + '0' 
_bcd1: 
    inc r18 
    subi r16, 100 
    brcc _bcd1 
    ldi r17, 10 + '0' 
_bcd2: 
    dec r17 
    subi r16, -10 
    brcs _bcd2 
    sbci r16, -'0' 
ret 

Well…  now we can include and use the file LCD.inc inside the original MeeBlip code.

Synth values to display on the OLED

I chose to display the values directly tied to the potentiomenters position and to switches positions. But it is only an idea: you can decide to display also other parameters. 😉

In this hand-made drawing you can see the Anode panel with the names of global variables tied to pots and to switches.

20160725_073555-1

Under each switch you can see the switch number to refer in the code. Under each potentiomenter (in the [] parentheses) you can see the name of the variables used to memorize the pot values.

Note that the pot on the bottom-left is used for two purposes (waveform and width), depending on the position of switch 3. The real variable names for this pot are the following (I know, the drawing is not updated to the last revision of my code…. but I loved to report it in my post 😉  ): WAVETABLE and PULSE_KNOB_LIMITED.

So in the code I managed this in order to display the right values depending on the siwtch position. You can see in file LCD.inc at the labels DISPLAY_WAVETABLE_VAL and DISPLAY_SWEEP_VAL. The choice of the path is done at lines 301 to 303, analyzing the current (and saved in a temporary variable) position of the switch 3.

The other variables names to display reported in the drawing should be OK…. I hope! In any case you can refer to the code, which ever says the truth! 🙂

Integration with Meeblip original code

I included the file LCD.inc after the inclusion of file “subroutines.inc”.

I defined some variable in variable_definition.inc:

///ML 20x4 lcd strings (4 rows of 20 chars+'\0')
my_LCDstring4: .byte 21
my_LCDstring3: .byte 21
my_LCDstring2: .byte 21
my_LCDstring1: .byte 21

//ML temporary variable in RAM
temp_in_RAM: .byte 1

After this, in the main program, the LCD is initialized using:

rcall LCD_START
//---start delay routine
push r18
push r19
push r20
; Generated by delay loop calculator
; at http://www.bretmulvey.com/avrdelay.html
;
; Delay 8 000 000 cycles
; 500ms at 16.0 MHz

    ldi  r18, 41
    ldi  r19, 150
    ldi  r20, 128
L1: dec  r20
    brne L1
    dec  r19
    brne L1
    dec  r18
    brne L1

pop r20
pop r19
pop r18
//----end wait routine---
rcall MYLCD_CLEAR
//prepare LCD gui (not to be refreshed at each basic cycle!)
rcall MYLCD_PREPARE_GUI

Then, the display refresh routine is called at each cpu cycle using:

rcall MYLCD_UPDATE

Note that, since the memory occupation has been increased, I had modified  some “rcall” instruction in “call”. You will find these changes searching for this comment:

//ML--->>changed rcall in call to avoid error " relative branch out of reach"

Well, that’s (mainly all)!

Recompiling the code and burning the binary on the ATMEGA32P you should obtain (after a screen reporting the name and the version of the synth) something like this:

20160719_191421

I’m sorry for the bad picture…but I was so excited! 🙂

The tests using the synth have been all successful, that is:

  • MIDI IN is OK (no MIDI note is lost during play)
  • Audio is OK (the notes produced with the working display have the same waveforms of them produced by the original Meeblip Anode firmware, I tested it with oscilloscope)
  • The interaction with the pots and switches are OK (the refresh of values on the display is very fast respect to the actions on the pots and switches).

So…it seems that a refresh rate of 100 milliseconds should be a good choice for ATMEGA32P computational load!

This is my MeeBlip Anode “Italian Way”, and now, after this great ordeal, I am ready for a (big) glass of Italian grappa. 🙂

I recall here the link to the code in GitHub: https://github.com/garretlabs/meeblip-anode/tree/meeblip_anode_italian_way

…Bonus Easter Egg (for die-hard geeks only): overclock it!

I am an old style geek… some years ago one of my hobbies was to overclock the CPUs of my computers.

I know that ATMEGA32P can be connected to a crystal with maximum frequency of 16Mhz (following the datasheet). But…I love the risk (hmmmm…. only on electronics things! 😉 ) so I wanted to connect him to a 20Mhz crystal.

With some basic code modification, you can have your overclocked Meeblip Anode “Italian Way”.

These are the modifications.

Firstly in the anode.asm file we change the cpu frequency:

.SET cpu_frequency = 20000000 //ML changed the CPU frequncy to 20Mhz

The other basic modification is the Timer 0  initilization (which is the hearth of the MeeBlip sound generation):

;initialize Timer0:

      //ldi     r16, 49             ;\  ; Set sample rate to 40.00 kHz //ML---> commented, since we need a new prescaler value
      ldi     r16, 62                ;\  ; Set sample rate to 40.00 kHz: ML---> we use 62 if the clock is 20Mhz since 16Mhz:49=20Mhz:x... in this case we have always the note in tune!
      out     OCr0, r16           ;/ OCr0 = 49 (///ML---> 62 on overclocked version) gives 40000.00 Hz sample rate at 400 cycles per sample loop.
      ldi     r16, 0x0A           ;\ clear timer on compare,
      out     TCCr0, r16          ;/ set prescaler = CK/8

Note that I used the value 62 for r16, instead of theoretically correct value 61, since I used a software tuner to have the best sound (Tunafish for MacOSX) and trying the values around 61.
Then I add a warning also in the initialization of Timer 2 PWM controlling cutoff…

ldi      r16, 0b01100001     ; Phase correct PWM, no prescaler ///ML WARNING: verify if the soud is nice with 20Mhz clock, else adjust!!!

For me the sound is nice…. 😉

In the LCD.inc file you should finally set the new frequency:

.equ    fclk      = 20000000      ;///ML---->new  system clock frequency (for delays)

This should be all for this easter egg… but I think you should do many other improvements of the code!

I had no problem and I played (and I’m playing) with great satisfaction the overclocked synth in my home studio for several projects…. but note that nothing is guaranteed with this mod. So handle with care! 😀

 

Phhhhhheeeeewww (I can rebreath now :-D)….Well geek boys & girls, that’s really all for this time.

It was a long time without a post on Garretlabs, but with this one I think I paid my debt with DIY community and to Garretlabs readers!

Bye bye folks… and keep always in touch with Garretlabs!

Advertisements

Raspberry PI: A remote controlled relay using SMS messages

Hi my dear female & male microelectronics geeks!

This time I will build an interesting object: a remote controlled relay using a Raspberry PI as SMS messages receiver and parser (and -obviously- as relay phisical controller).

I will use this stand-alone (sub)system with my meteo station system. If you want to read more about the meteo station, in the previous posts I described the I2C communication between the acquisition board (Arduino UNO) and the station controller, the model (hardware and software) of the acquisition board.
In this post we will PLAY WITH THE HIGH VOLTAGE, so… pay attention,please. 🙂
Rememeber that when we use the high voltage..the only safe thing you can consider is the GROUND, so… again, pay attention please! 🙂

Why high voltage? Well… it’s simple.
Because I would like to power on/off my meteo station via remote commands (since at the end of this “technical adventure” I will install my meteo station in a very beautiful place, but a little far from my home).
In order to do that, I would like to use a simple (sub)system, consisting of one Raspberry PI (for this purpose you can use also the less expensive model A, but in my project I will use again a Model B.Yeah, you know I love this board …but I assure you I’m preparing some surprise also with my new Olinuxino A20! 😉 ), one Itead 2-way Relay Module (bought as usual from Robot Italy), one multiple power connector bought (…from my father) at the cheapest general-purpose shop in my little city (it is called “Risparmio Casa”, in English it should be something like “Savings -for the- House”), and, last but not least, one USB 3G dongle (I used an old Huawey K3715 compatible E169, marketed by Vodafone, with a TIM sim inside) which I will use as “mobile phone” in order to receive SMS messages.

In this case I will not use it as “internet 3G dongle” because:

  1.  I want to command the power on/off even if the 3G signal is not present
  2.  Sending single SMS messages is cheaper than a flat 3G connection (in Italy, I don’t know if the situation is the same in other countries)
  3. The power consuption is lower if the dongle is not connected to 3G

Ok, let’s go with the experiment! 😉

Commanding the relay using Python

I took the inspiration for this step , from this post of the italian blog “Raspibo.org”
Let’s install something!

#sudo apt-get update
#sudo apt-get install python-rpi.gpio
#sudo apt-get install python3-rpi.gpio

Well, after this you can connect Raspberry and the Itead relay module .

GPIO18 will be used as command signal for relay, plus you will connect the Raspberry 5V/GND pins to the module Vcc/Gnd pins. This is the Fritzing schema:

Arduino rele controller_bb

Then you can modify the multiple power connector in the following mode: remove a part of external protection from the cable (pay attention in this operation, please!), then cut the 220V brown wire and connect the terminals to COM and NO pins of the relay module. NC shall be not connected. Blue and yellow/green wires shall arrive directly to the power connector.

Ok, now we can test the relay (with the 220V power NOT connected, for the moment).

Firstly we must write a script in order to initialize to LOW the GPIO18 pin at Raspberry startup. The script will be:

#!/usr/bin/env python
import Rpi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT, initial=GPIO.LOW)

 Then, you can save it where you want, and you must to change the mode in order to declare the script as executable:

#chmod +x initialize_GPIO18_script.py

…But the very important thing is to add the following line to /etc/rc.local:

sudo /path_to_initialize_GPIO18_script/initialize_GPIO18_script.py

and execute a reboot of the board.

After the reboot, the GPIO18 will be correctly initialized, so you could test the relay functionality. In order to close the relay you will write the following script:

#!/usr/bin/env python
import Rpi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)
GPIO.output(18, GPIO.HIGH)

and in order to open the relay you will write the following script:

#!/usr/bin/env python
import Rpi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)
GPIO.output(18, GPIO.LOW)

Note that all the executions of GPIO-related scripts will be possible only using “sudo” before the commands.

Well… if your scripts work well, open the relay (=led powered off on the Itead module): this is the safer state.

Now it’s the moment to connect the multiple power connector to the 220Volts plug on the wall….but, REMEMBER THAT THIS OPERATION CAN BE DANGEROUS AND YOU MUST USE ALL AVAILABLE PROTECTIONS in order to reduce risks. Remember that you are now playing with HIGH VOLTAGE, so PAY ATTENTION.

To test the relay behavior now you connect a lamp (or something else) to the multiple power connector and use the above scripts to power on/off it.

…..Aufffff, I hope all worked well, and you haven’t burnt your home! 😉


Connecting the USB 3G dongle and configuring it in order to receive (and send) SMS messages

Ok, now a little more relaxed activity: we must receive SMS messages using a 3G dongle and we must to parse them in order to command the relay.

I’ve done the following steps in order to make all things work without problems (after maaaaaaaany experiments, overall tied to the files/directories permissions and to users execution policies…. 😦 ).

1. Power Off your Raspberry
2. Connect the USB 3G dongle, then power on the Raspberry. My dongle is correctly recognized by Raspbian as 3G modem on /dev/ttyUSB0 [IMPORTANT NOTE: some USB dongle -i.e. Huawey E1820- is recognized by Raspian as CD-ROM… so you should use some “howto” regarding the utility usbmodeswitch in order to correctly recognize the modem inside the dongle]
3. Install gammu and gammu-smsd. Gammu is used to send SMS message, gammu-smsd is the daemon used to receive the SMS.

#sudo apt-get install gammu 
#sudo apt-get install gammu-smsd

4. Configure the file /etc/gammu-smsdrc in the following way:

port = /dev/ttyUSB0
connection= at19200
[...]
logfile = /home/pi/log-gammu.txt
service = file 
RunOnReceive = sudo /home/pi/Script_relay/sms_relay.py
[...]
inboxpath= /home/pi/Script_relay/inbox_sms/

5. Save the file, then add the user “gammu” to “sudoers” group of your Raspberry, using the tool visudo:

#sudo visudo

It will open /etc/sudoers.rc…so you append the following line to the file :

gammu ALL=(ALL) NOPASSWD: ALL

[NOTE: you can report /home/pi/Script_relay/sms_relay.py instead of ALL, for security reasons]

6. Save the file and Reboot you Raspberry. The gammu-smsd daemon starts automatically at the end of boot process.
7. Verify that in /home/pi/gammu-log.txt there arent’t strange errors (tied to communication between Raspi and the dongle). I encountered these errors when I installed gammu-smsd without the dongle already connected. Anyway, in this case you can remove the installation and you can reinstall gammu-smsd:

#sudo apt-get –purge autoremove gammu-smsd
#sudo apt-get gammu-smsd

8. Create the filesystem used by the gammu-smsd configuration:

#mkdir /home/pi/Script_relay
#mkdir /home/pi/Script_relay/inbox_sms
#chmod 777 /home/pi/Script_relay/inbox_sms

[NOTE: I imposed the simple mode 777 in order to permit to “gammu” user to save the SMS messages in this folder -and it’s work-, but you can use some more secure access]

9. Create the code for /home/pi/Script_relay/sms_relay.py in the follwing way:

#!/usr/bin/env python
import Rpi.GPIO as GPIO
import sys
GPIO.setmode(GPIO.BCM)
#note we don't initialize the initial value of GPIO18, we use the current status
GPIO.setup(18, GPIO.OUT)
#the filename of the SMS is passed as argument to the script from the RunOnReceive gammu-smsd option 
filename=str(sys.argv[1]) 
complete_filename="/home/pi/Script_relay/inbox_sms/"+filename 
sms_file=open(complete_filename,"r") 
message=sms_file.read(160) #note that a not-parted SMS can be maximum 160 characters 
if (message.find("poweron")<>-1): 
     GPIO.output(18, GPIO.HIGH) 
elif (message.find("poweroff")<>-1): 
     GPIO.output(18, GPIO.LOW)

That’s all folks!

If all worked correctly, sending now to the dongle telephone number a SMS containing the keyword poweron you will see that the relay will be powered on, and sending an SMS containg the keyword poweroff you will see that the relay will be powered off.

…It’s a magical thing, don’t you think that? 😉

wpid-20140520_063754.jpg

Finally…the complete relay controller

Possible improvements to the project (I give you them as exercises 🙂 )

1. Send a SMS message to a number (it should be the number of the phone which commanded the power on/off)when the relay has been powered on/off. You should modify the sms_relay.py adding a call to the gammu command line tool (find one of the many examples on internet for the usage). Note that the tool must be configured (his configuration file is /home/pi/.gammurc) with the following data:

port = /dev/ttyUSB0
connection= at19200

…But for this functionality there is a little (=big 😦 ) problem: gammu-smsd blocked the /dev/ttyUSB0, so….what could be a possible solution?

2.  Add to the /etc/gammu-smsdrc file one filter in order to accept SMS message only from YOUR phone. This is not difficult, there is a configuration parameter to add in the file (with the “white-listed” numbers)… you can find it in the gammu-smsd user guide! 🙂

 

Ok boys and girls, today we used the high voltage… you know that for a software and/or microelectronics engineer this is like a bungee-jumping. 😀

So, now I need only a good grappa an an italian horror (or thriller) movie of the ’70-’80 on my television.

Do you like Lucio Fulci movies?

A relaxing movie now...

A relaxing movie now…”The New York ripper” by Lucio Fulci

I know he is very famous all around the world (…except than in Italy 😦 ).

My Fulci preferred movie is “The New York Ripper” (italian title: “Lo Squartatore di New York”)…. I need a very relaxing night, after this dangerous and stressing post! 😉

Bye bye, see you soon!