Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pm:prj2022:arosca:picomacropad [2022/05/06 22:19]
pavel_vlad.mateescu created
pm:prj2022:arosca:picomacropad [2022/05/28 00:12] (current)
pavel_vlad.mateescu [Download]
Line 2: Line 2:
 ===== Introducere ===== ===== Introducere =====
  
-<note tip> +Un Macropad programabil cu scopul de a eficientiza lucrul ​pe calculator. 
-Prezentarea ​pe scurt proiectului vostru+Am plecat de la dorinta de controla mai eficient functionalitati ale laptopului meu in timp ce lucrez precum
-  * ce face +  * Control audio pentru device-uri in/out; 
-  * care este scopul lui +  * Performare task-uri repetitive prin simpla apasare a unui buton; 
-  * care a fost ideea de la care aţi pornit +  * Posibilitatea ​de extindere ​astfel ​de functionalitati;​  
-  * de ce credeţi că este util pentru ​alţii şi pentru voi +Acest proiect ​este util pentru ​minimizarea timpului mort 
-</​note>​+
 ===== Descriere generală ===== ===== Descriere generală =====
  
-<note tip> +{{:pm:prj2022:​arosca:​block_diagram.png?​nolink&​500|}}
-O schemă bloc cu toate modulele proiectului vostru, atât software cât şi hardware însoţită de o descriere a acestora precum şi a modului în care interacţionează. +
- +
-Exemplu de schemă blochttp://​www.robs-projects.com/​mp3proj/​newplayer.html +
-</​note>​+
  
 ===== Hardware Design ===== ===== Hardware Design =====
  
-<note tip> +Lista componente
-Aici puneţi tot ce ţine de hardware design+  * Rasberry Pi Pico 
-  * listă de piese +  * Display OLED 128x64 pixels 
-  * scheme electrice (se pot lua şi de pe Internet şi din datasheet-uri,​ e.g. http://​www.captain.at/​electronic-atmega16-mmc-schematic.png) +  * Rotary Encoder 
-  * diagrame de semnal ​ +  * 10 Kailh Box Jade mechanical switches 
-  * rezultatele simulării +  * Hand made 2 layer copper etched pcb 
-</​note>​+  * 10 12k SMD 1206 resistors 
 +  * 2 10k SMD 0805 resistors 
 +  * 1 10k Through Hole resistor 
 +  * 10 10nf SMD 0805 capacitors 
 +  * Pin headers and wires 
 + 
 +{{:​pm:​prj2022:​arosca:​picomacropad1.jpeg?​nolink&​350|}}{{:​pm:​prj2022:​arosca:​picomacropad_pcb_pavel-vlad_mateescu.jpg?​nolink&​350|}} 
 + 
 +{{:​pm:​prj2022:​arosca:​picomacropad_sch_pavel-vlad_mateescu.jpg?​nolink&​700|}} 
  
 ===== Software Design ===== ===== Software Design =====
  
 +Codul a fost dezvoltat folosind limbajul CircuitPython in Thonny.
 +Biblioteci externe:
 +  * Adafruit Framebuf
 +  * Adafruit SSD1306
 +  * Adafruit HID
 +  * Adafruit ImageLoader
  
-<note tip> +Codul citeste semnale ​de la cele 10 butoane si de la codorul rotativinclusiv butonul acestuia
-Descrierea codului aplicaţiei (firmware):​ +
-  * mediu de dezvoltare (if any) (e.g. AVR StudioCodeVisionAVR) +
-  * librării şi surse 3rd-party (e.g. Procyon AVRlib) +
-  * algoritmi şi structuri pe care plănuiţi să le implementaţi +
-  * (etapa 3) surse şi funcţii implementate +
-</​note>​+
  
-===== Rezultate Obţinute =====+Pentru a programa functionalitatea celor 10 butoane, trebuie definita o matrice de 5x2 cu functionalitatea pentru foecare butoane. Functionalitatea butoanelor este preluata din biblioteca Adafruit HID.
  
-<note tip> +Pentru controlul OLED-ului se foloseste biblioteca Adafruit SSD1306 si Adafruit ImageLoader. Se pot scrie mesaje caracter cu caracter, se pot incarca imagini sau se pot seta pixeli arbitrar pe o matrice de 128x64 pixeli.
-Care au fost rezultatele obţinute în urma realizării proiectului vostru. +
-</​note>​+
  
 +<code python>
 +import rotaryio
 +import board
 +import digitalio
 +import displayio
 +import adafruit_imageload
 +import usb_hid
 +from adafruit_hid.consumer_control import ConsumerControl
 +from adafruit_hid.consumer_control_code import ConsumerControlCode
 +import time
 +from digitalio import DigitalInOut,​ Direction, Pull
 +from adafruit_hid.keyboard import Keyboard
 +from adafruit_hid.keycode import Keycode
 +import busio
 +import adafruit_ssd1306
 +
 +#display
 +i2c = busio.I2C(board.GP27,​ board.GP26)
 +display = adafruit_ssd1306.SSD1306_I2C(128,​ 64, i2c)
 +
 +
 +# left encoder
 +buttonL = digitalio.DigitalInOut(board.GP6)
 +buttonL.direction = digitalio.Direction.INPUT
 +buttonL.pull = digitalio.Pull.UP
 +
 +encoderL = rotaryio.IncrementalEncoder(board.GP7,​ board.GP8)
 +
 +cc = ConsumerControl(usb_hid.devices)
 +
 +button_stateL = None
 +last_positionL = encoderL.position
 +
 +# keyboard
 +
 +led = DigitalInOut(board.LED)
 +led.direction = Direction.OUTPUT
 +led.value = True
 +
 +kbd = Keyboard(usb_hid.devices)
 +cck = ConsumerControl(usb_hid.devices)
 +
 +
 +pins = [
 +    board.GP13,
 +    board.GP12,
 +    board.GP11,
 +    board.GP10,
 +    board.GP16,
 +    board.GP17,
 +    board.GP18,
 +    board.GP19,
 +    board.GP20,
 +    board.GP21,
 +]
 +
 +MEDIA = 1
 +KEY = 2
 +META = 3
 +
 +# functionality of each layer
 +keymap_layers = [{
 +    (0): (KEY, [Keycode.ONE]),​
 +    (1): (KEY, [Keycode.TWO]),​
 +    (2): (KEY, [Keycode.THREE]),​
 +    (3): (KEY, [Keycode.FOUR]), ​  
 +    (4): (META, [Keycode.CAPS_LOCK]),​
 +    (5): (KEY, (Keycode.SHIFT,​ Keycode.GUI,​ Keycode.M)),​
 +    (6): (KEY, [Keycode.FIVE]),​
 +    (7): (KEY, [Keycode.SIX]),​
 +    (8): (KEY, [Keycode.SEVEN]),​
 +    (9): (KEY, [Keycode.EIGHT]), ​  
 +},
 +{
 +    (0): (KEY, [Keycode.NINE]),​
 +    (1): (KEY, [Keycode.ZERO]),​
 +    (2): (KEY, (Keycode.SHIFT,​ Keycode.NINE)),​
 +    (3): (KEY, (Keycode.SHIFT,​ Keycode.ZERO)), ​  
 +    (4): (META, [Keycode.CAPS_LOCK]),​
 +    (5): (KEY, (Keycode.SHIFT,​ Keycode.GUI,​ Keycode.M)),​
 +    (6): (KEY, (Keycode.SHIFT,​ Keycode.THREE)),​
 +    (7): (KEY, (Keycode.SHIFT,​ Keycode.FOUR)),​
 +    (8): (KEY, (Keycode.SHIFT,​ Keycode.SEVEN)),​
 +    (9): (KEY, (Keycode.SHIFT,​ Keycode.EIGHT)), ​  
 +}]
 +
 +keymap = keymap_layers[0]
 +
 +layer = True
 +mute = False
 +
 +# display layers based on keyboard layer
 +def change_layer(mute):​
 +    global keymap
 +    if layer:
 +        display.fill(0)
 +        keymap = keymap_layers[not layer]
 +        display.text("​layer ​ 1 2 3 4", 0, 0, 1)
 +        if mute == True:
 +            display.text("​unmute 5 6 7 8", 0, 32, 1)
 +        else:
 +            display.text("​mute ​  5 6 7 8", 0, 32, 1)
 +        display.show()
 +    else:
 +        display.fill(0)
 +        keymap = keymap_layers[not layer]
 +        display.text("​layer ​ 9 0 ( )", 0, 0, 1)
 +        if mute == True:
 +            display.text("​unmute # $ & *", 0, 32, 1)
 +        else:
 +            display.text("​mute ​  # $ & *", 0, 32, 1)
 +        display.show()
 +
 +switches = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
 +
 +for i in range(10):
 +    switches[i] = DigitalInOut(pins[i])
 +    switches[i].direction = Direction.INPUT
 +    switches[i].pull = Pull.UP
 +
 +switch_state = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
 +
 +# init
 +change_layer(mute)
 +
 +while True:
 +    # left encoder
 +    current_positionL = encoderL.position
 +    position_changeL = current_positionL - last_positionL
 +    if position_changeL > 0:
 +        for _ in range(position_changeL):​
 +            cc.send(ConsumerControlCode.VOLUME_DECREMENT)
 +        #​print(current_positionL)
 +    elif position_changeL < 0:
 +        for _ in range(-position_changeL):​
 +            cc.send(ConsumerControlCode.VOLUME_INCREMENT)
 +        #​print(current_positionL)
 +    last_positionL = current_positionL
 +    if not buttonL.value and button_stateL is None:
 +        button_stateL = "​pressed"​
 +    if buttonL.value and button_stateL == "​pressed":​
 +        cc.send(ConsumerControlCode.MUTE)
 +        button_stateL = None
 +
 +    # keyboard
 +    for button in range(10):
 +        if switch_state[button] == 0:
 +            if not switches[button].value:​
 +                try:
 +                    if keymap[button][0] == KEY:
 +                        if button == 5:
 +                            mute = not mute
 +                            change_layer(mute)
 +                        kbd.press(*keymap[button][1])
 +                    else:
 +                        if button == 4:
 +                            layer = not layer
 +                            change_layer(mute)
 +                        else:
 +                            cck.send(keymap[button][1])
 +                except ValueError: ​ # deals w six key limit
 +                    pass
 +                switch_state[button] = 1
 +
 +        if switch_state[button] == 1:
 +            if switches[button].value:​
 +                try:
 +                    if keymap[button][0] == KEY:
 +                        kbd.release(*keymap[button][1])
 +
 +                except ValueError:
 +                    pass
 +                switch_state[button] = 0
 +
 +    time.sleep(0.01) ​ # debounce
 +</​code>​
 +===== Rezultate Obţinute =====
 +
 +Am dobandit skill-ul de a face un PCB de mana.
 +Am produs un tool pe care il voi folosi in timpul lucrului de zi cu zi
 ===== Concluzii ===== ===== Concluzii =====
  
 +Rezultatul proiectului este un punct bun de inceput prototiparea unui produs care poate fi adus pe piata
 ===== Download ===== ===== Download =====
  
-<note warning>​ +{{:pm:​prj2022:​arosca:​picomacropad_surse_pavel-vlad_mateescu.zip|}}
-O arhivă (sau mai multe dacă este cazul) cu fişierele obţinute în urma realizării proiectuluisurse, scheme, etc. Un fişier README, un ChangeLog, un script de compilare şi copiere automată pe uC crează întotdeauna o impresie bună ;-).+
  
-Fişierele se încarcă pe wiki folosind facilitatea **Add Images or other files**. Namespace-ul în care se încarcă fişierele este de tipul **:​pm:​prj20??:​c?​** sau **:​pm:​prj20??:​c?:​nume_student** (dacă este cazul). **Exemplu:​** Dumitru Alin, 331CC -> **:​pm:​prj2009:​cc:​dumitru_alin**. 
-</​note>​ 
  
-===== Jurnal ​=====+===== Bibliografie/​Resurse ​=====
  
-<note tip> +**Resurse Software**
-Puteți avea și o secțiune de jurnal în care să poată urmări asistentul de proiect progresul proiectului. +
-</​note>​+
  
-===== Bibliografie/​Resurse ​=====+  * Adafruit'​s CircuitPython docs: https://​docs.circuitpython.org/​en/​latest/​shared-bindings/​index.html 
 +  * Adafruit'​s CircuitPython libraries catalog: https://​learn.adafruit.com/​welcome-to-circuitpython/​circuitpython-libraries 
 +  * I2C OLED tutorial: https://​lastminuteengineers.com/​oled-display-arduino-tutorial/​ 
 + 
 +**Resurse ​Hardware**. 
 + 
 +  * Raspberry Pi Pico datasheet: https://​datasheets.raspberrypi.com/​pico/​pico-datasheet.pdf 
 +  * Generic I2C OLED datasheet: https://​cdn-shop.adafruit.com/​datasheets/​SSD1306.pdf 
 +  * Generic Rotary Encoder description page: https://​components101.com/​modules/​KY-04-rotary-encoder-pinout-features-datasheet-working-application-alternative ​
  
-<​note>​ 
-Listă cu documente, datasheet-uri,​ resurse Internet folosite, eventual grupate pe **Resurse Software** şi **Resurse Hardware**. 
-</​note>​ 
  
 <​html><​a class="​media mediafile mf_pdf"​ href="?​do=export_pdf">​Export to PDF</​a></​html>​ <​html><​a class="​media mediafile mf_pdf"​ href="?​do=export_pdf">​Export to PDF</​a></​html>​
  
pm/prj2022/arosca/picomacropad.1651864751.txt.gz · Last modified: 2022/05/06 22:19 by pavel_vlad.mateescu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0