adamples / VU_meter

Stereo VU meter using OLED screens and AVR microcontroller
GNU General Public License v3.0
120 stars 31 forks source link

Programming #6

Open shtv-electro opened 4 years ago

shtv-electro commented 4 years ago

Hello. Tell me how to program a project (I am using Atmega328P (Arduino nano), 16MHz, OLED1306). I am not familiar with Python language, and would like more detailed instruction. Thanks

adamples commented 4 years ago

Hi, if you know how to flash your arduino with hex file you can use the ones from this zip: https://github.com/adamples/VU_meter/releases. It doesn't require Python.

shtv-electro commented 4 years ago

Hey. I flashed a hexadecimal file, the screen is black. Tried to flash the standard code of the display and it works. Maybe your code is not the address of the display? I want you ask do code under displays 1306 with addresses: 0x3C; 0x3C. Atmega328p, 16 MHz.

adamples commented 4 years ago

Hi, it won't work since display addresses need to be different. If you're able to change address of one of them (probably by resoldering some resistor on board) then I can compile hex file for you.

DamianRaistrick commented 4 years ago

Hi Adam Really excellent project! I'm attempting to get this to work on a couple of SH1106 displays with addresses 0x3c and 0x3d. I've managed to edit the config.h file to reflect the addresses and make the main.hex file (using terminal on my mac). I have managed to upload to an Arduino Uno using HexUploader but nothing appears on the displays. I've tested the displays using the adafruit and U8Glib example code and they work fine on on I2C. Is there anything else I should be adjusting before making the hex file for these displays? Many thanks Damian

Juroo5 commented 3 years ago

Hello, I'm joining DamianRaistrick's previous question. I'm trying to run a program on an Arduino Nano (Atmega328P). I have displays with the SD1309 controller (exactly these https://www.aliexpress.com/item/33024448944.html?spm=a2g0s.9042311.0.0.27c64c4dNouTa4) The displays are connected in I2C mode to arduino (PC5 -> SCL, PC4 -> SDA) . On one, the address is changed by changing the CS level. With the I2C scanner the addresses are 0x3C and 0x3D. In the makefile I changed : BOARD? = WZ10 to BOARD? = ARDUINO_UNO In config file I changed :

define OLED_DRIVER (OLED_DRIVER_SD1309)

...

define DISPLAY_A_ADDRESS (0x3C)

define DISPLAY_B_ADDRESS (0x3D)

... After uploading the program (with generated HEX and AVRDUDESS), nothing will appear on the displays. It's possible that arduino I2C scanner (scanner in arduino example sketchs) see different address than this program ? Or is there something I missed ? Can you help me? Thank you.

adamples commented 3 years ago

Hi! One common problem is that those displays even when using the same driver designation are not always exactly the same. I think this one may need reset signal during initialization. Have you tried displaying something using other libraries/arduino sketches? If so, which library and how did you connect the reset line?

Also in config.h it should be OLED_DRIVER_SSD1309, not OLED_DRIVER_SD1309. Address should be 0x78 and 0x7a (R/W bit is included in address here, so it's the same as 0x3C/0x3D using other convention).

Juroo5 commented 3 years ago

Hi! Thank you for the quick reply. For the reset pin I connected a 22uf capacitor between RES and GND and a 10k resistor between VCC and RES. Yes, I tested these displays on the example of Adafruit SSD1306 library : https://photos.app.goo.gl/9cgTZD8fZcefB1yZA It's of course OLED_DRIVER_SSD1309, I'm sorry for the bad typing. In the end, it works! Well thank you ! The problem was the addresses, I correct them to 0x78 and 0x7a and it works.

cghercoias commented 3 years ago

Hi Adam,

I just found your project and I must say it is impressive. I have just one SH1106 display and I wanted to try your code. I did compile successfully the code on my Mac, changing in the makefile. But the display does not lit. It is wired just GND, VCC, SDA and SCL. I did test the display with the Adafruit example code for this display and works fine. When I upload the main.hex does not lit anymore. The address on the back of the display (where the resistor is soldered) is 0x78. However, in the Adafruit example is 0x3C and works. In the config.h is 0x78 and 0x7A. I did try and compile the main.hex with 0x3C for DISPLAY_A_ADDRESS and 0x3D for DISPLAY_B_ADDRESS and still didn't show anything on the display. I don't know where to look anymore.

In Makefile I've changed: .. BOARD? = WZ10 to BOARD? = ARDUINO_UNO ..

Here is the result of "make all" :

catalin@DadMacPro VU_meter-master % make all avr-gcc -mmcu=atmega328p -DF_CPU="16000000UL" -MD -MP -Wall -Werror -std=c99 -ffunction-sections -fdata-sections -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -frename-registers -g -Wa,-ahlmsd=build/RELEASE/i2c_hw.lst -O2 -DNDEBUG -c -o build/RELEASE/i2c_hw.o src/i2c_hw.c avr-gcc -mmcu=atmega328p -DF_CPU="16000000UL" -MD -MP -Wall -Werror -std=c99 -ffunction-sections -fdata-sections -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -frename-registers -g -Wa,-ahlmsd=build/RELEASE/i2c.lst -O2 -DNDEBUG -c -o build/RELEASE/i2c.o src/i2c.c avr-gcc -mmcu=atmega328p -DF_CPU="16000000UL" -MD -MP -Wall -Werror -std=c99 -ffunction-sections -fdata-sections -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -frename-registers -g -Wa,-ahlmsd=build/RELEASE/oled.lst -O2 -DNDEBUG -c -o build/RELEASE/oled.o src/oled.c avr-gcc -mmcu=atmega328p -DF_CPU="16000000UL" -MD -MP -Wall -Werror -std=c99 -ffunction-sections -fdata-sections -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -frename-registers -g -Wa,-ahlmsd=build/RELEASE/display.lst -O2 -DNDEBUG -c -o build/RELEASE/display.o src/display.c avr-gcc -mmcu=atmega328p -DF_CPU="16000000UL" -MD -MP -Wall -Werror -std=c99 -ffunction-sections -fdata-sections -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -frename-registers -g -Wa,-ahlmsd=build/RELEASE/progmem_image_sprite.lst -O2 -DNDEBUG -c -o build/RELEASE/progmem_image_sprite.o src/progmem_image_sprite.c avr-gcc -mmcu=atmega328p -DF_CPU="16000000UL" -MD -MP -Wall -Werror -std=c99 -ffunction-sections -fdata-sections -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -frename-registers -g -Wa,-ahlmsd=build/RELEASE/needle_sprite.lst -O2 -DNDEBUG -c -o build/RELEASE/needle_sprite.o src/needle_sprite.c avr-gcc -mmcu=atmega328p -DF_CPU="16000000UL" -MD -MP -Wall -Werror -std=c99 -ffunction-sections -fdata-sections -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -frename-registers -g -Wa,-ahlmsd=build/RELEASE/adc.lst -O2 -DNDEBUG -c -o build/RELEASE/adc.o src/adc.c avr-gcc -mmcu=atmega328p -DF_CPU="16000000UL" -MD -MP -Wall -Werror -std=c99 -ffunction-sections -fdata-sections -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -frename-registers -g -Wa,-ahlmsd=build/RELEASE/calibration.lst -O2 -DNDEBUG -c -o build/RELEASE/calibration.o src/calibration.c avr-gcc -mmcu=atmega328p -DF_CPU="16000000UL" -MD -MP -Wall -Werror -std=c99 -ffunction-sections -fdata-sections -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -frename-registers -g -Wa,-ahlmsd=build/RELEASE/main.lst -O2 -DNDEBUG -c -o build/RELEASE/main.o src/main.c avr-gcc -mmcu=atmega328p -DF_CPU="16000000UL" -MD -MP -Wall -Werror -std=c99 -ffunction-sections -fdata-sections -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -frename-registers -g -Wa,-ahlmsd=build/RELEASE/main -O2 -DNDEBUG -mmcu=atmega328p -static -Wl,-Map=build/RELEASE/map.map,--cref -Wl,--section-start=.eefixed=0x810080 -Wl,-gc-sections build/RELEASE/utils.o build/RELEASE/fault.o build/RELEASE/benchmark.o build/RELEASE/ring_buffer.o build/RELEASE/i2c_hw.o build/RELEASE/i2c.o build/RELEASE/oled.o build/RELEASE/display.o build/RELEASE/progmem_image_sprite.o build/RELEASE/needle_coordinates.o build/RELEASE/needle_sprite.o build/RELEASE/adc.o build/RELEASE/calibration.o build/RELEASE/main.o build/RELEASE/background.o build/RELEASE/background_flipped.o build/RELEASE/peak_indicator.o build/RELEASE/watermark.o -o build/RELEASE/main avr-objcopy -R .eeprom -R .eefixed -O ihex build/RELEASE/main build/RELEASE/main.hex avr-objcopy -j .eeprom --change-section-lma .eeprom=0 -j .eefixed --change-section-lma .eefixed=0x80 -O ihex build/RELEASE/main build/RELEASE/main.eep avr-objcopy: --change-section-lma .eeprom=0x0000000000000000 never used catalin@DadMacPro VU_meter-master %

Here is how I am burning the main.hex file on the ArduinoNANO

catalin@DadMacPro VU_meter-master % /Users/catalin/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/bin/avrdude -C/Users/catalin/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf -v -patmega328p -carduino -P/dev/cu.usbserial-1410 -b115200 -D -Uflash:w:build/RELEASE/main.hex:i

avrdude: Version 6.3-20190619 Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/ Copyright (c) 2007-2014 Joerg Wunsch

     System wide configuration file is "/Users/catalin/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf"
     User configuration file is "/Users/catalin/.avrduderc"
     User configuration file does not exist or is not a regular file, skipping

     Using Port                    : /dev/cu.usbserial-1410
     Using Programmer              : arduino
     Overriding Baud Rate          : 115200
     AVR Part                      : ATmega328P
     Chip Erase delay              : 9000 us
     PAGEL                         : PD7
     BS2                           : PC2
     RESET disposition             : dedicated
     RETRY pulse                   : SCK
     serial program mode           : yes
     parallel program mode         : yes
     Timeout                       : 200
     StabDelay                     : 100
     CmdexeDelay                   : 25
     SyncLoops                     : 32
     ByteDelay                     : 0
     PollIndex                     : 3
     PollValue                     : 0x53
     Memory Detail                 :

                              Block Poll               Page                       Polled
       Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
       ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
       eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
       flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
       lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
       hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
       efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
       lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
       calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
       signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

     Programmer Type : Arduino
     Description     : Arduino
     Hardware Version: 3
     Firmware Version: 4.4
     Vtarget         : 0.3 V
     Varef           : 0.3 V
     Oscillator      : 28.800 kHz
     SCK period      : 3.3 us

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e950f (probably m328p) avrdude: safemode: lfuse reads as 0 avrdude: safemode: hfuse reads as 0 avrdude: safemode: efuse reads as 0 avrdude: reading input file "build/RELEASE/main.hex" avrdude: writing flash (5762 bytes):

Writing | ################################################## | 100% 1.03s

avrdude: 5762 bytes of flash written avrdude: verifying flash memory against build/RELEASE/main.hex: avrdude: load data flash data from input file build/RELEASE/main.hex: avrdude: input file build/RELEASE/main.hex contains 5762 bytes avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.77s

avrdude: verifying ... avrdude: 5762 bytes of flash verified

avrdude: safemode: lfuse reads as 0 avrdude: safemode: hfuse reads as 0 avrdude: safemode: efuse reads as 0 avrdude: safemode: Fuses OK (E:00, H:00, L:00)

avrdude done. Thank you. ...

adamples commented 3 years ago

So the addresses in config should be 0x78/0x7a. 0x3c and 0x3d is the same address written in different convention (it's just right-shifted by 1 bit). Did you try to connect two displays or just one? It's not clear from your question. This project requires two with different addresses, otherwise it won't display anything.

cghercoias commented 3 years ago

0x3C | 0 0 1 1   1 1 0 0 0x3D | 0 0 1 1   1 1 0 1

0x78 | 0 1 1 1   1 0 0 0 0x7A | 0 1 1 1   1 0 1 0

I see that now, it is right-shifted. How come I didnt see that before. :-) I connected only one display, SH1106. I will try with two SSD1306 as I dont have two SH1106s. Thank you so much

cghercoias commented 3 years ago

I made it work with 2 SSD1306s. Had to modify the address of one of them by cutting a pad and solder it to VCC. According to SSD1306 PDF document ( SSD1306.pdf - page 20 ) :

"The slave address is following the start condition for recognition use. For the SSD1306, the slave address is either “b0111100” or “b0111101” by changing the SA0 to LOW or HIGH (D/C pin acts as SA0)." SSD1306_MOD

So, I did a little surgery on one display, D/C pin aka SA0 is pin 15 has to be connected to VCC to change the address from 0x3C to 0x3D: SSD1306_0x3D_MOD

Final result: VU_Meter_2x_SSD1306

THANK YOU SO MUCH ADAM !!!

Merry Christmas and a Happy New Year! Stay safe!

adamples commented 3 years ago

Very glad to hear it worked for you, Marry Christmas to you too!

cghercoias commented 3 years ago

Now I have another issue. The needles don't move. I've applied a signal from my laptop headphone jack on both A0 and A1 (inserted 1uF electrolytic capacitor on each channel to decouple any DC component, if present) and the only thing that sometimes happens is PEAK blinks. Looking at your electronics diagram, I noticed you've connected ARef to 3.3V. So I placed a jumper between 3.3V and ARef (behind those resistors) and the needles jumped to max and stayed there. I'm able to watch with the osciloscope the audio signal getting to A0 and A1, I can vary the amplitude from 0 to 1.5V. I did not connect anything to the A2 and A3 for PEAK. What am I missing?
Also, not in the picture above, I've inserted a logic level converter between Arduino A4 and A5 (SDA and SCL) and the OLED display. I know you mentioned it and saw it myself with the scope how the signals were pulled down to 3.3V when I connected the diplays directly to Arduino. I used one of these 4 channel -- https://www.adafruit.com/product/757

adamples commented 3 years ago

Well, if you're using different analog circuitry at the inpuit it will require some hacking on your part. The program is expecting AREF to be 3.3V and voltage when there is no signal at the input should be 2.5V (there is 2.5V reference source on the schematic, MCP1525 IIRC). When needle is at 0VU the voltage at the input should go down to about 1.1V. You can find the code in calibration.h/c.