Seleção de utilidades para o hobby eletrônico no AliExpress

Sabe aqueles vídeos ou fotos de pessoas que realizam diversas montagens nos protoboards com aqueles fios bonitinhos, usando aqueles módulos pequenos e úteis ou placas padrão? Então. Lembro-me que achava que nunca conseguiria ter tudo aquilo. Porém depois de descobrir o AliExpress lá atrás devagar fui comprando pequenas utilidades sem gastar mais que R$ 50,00 por entrega (já que algumas levam algumas semanas para chegar). Se eu tivesse comprado no Brasil estaria perdido, falido esta hora.

Então segue um lista que acho útil e talvez você não conseguiu achar por não saber os nomes.

 

male-to-male-color-breadboard-cable-jump-wire-font-b-jumper-b-font-for-font-b_220x220 free-shipping-straight-curve-font-b-tweezers-b-font-eyelash-extension-tool-eyelash-makeup-beauty-stainless_220x220 usb-font-b-logic-b-font-font-b-analyzer-b-font-100m-max-sample-rate-16channels_220x220

Três ferramentas de extrema utilidade. 40 Fios com terminais por U$ 2,40. Pinças de boa qualidade. E um analisador lógico indispensável para depurar saidas de MCUs. Checar 6 canais de PWM sem um destes é loucura…

2015-new-mb102-power-supply-module-3-3v-5v-breadboard-board-830-point-65pcs-font-b_220x220

Os pacotes se bem achados são muito econômicos. E esse é o grande diferencial do AliExpress. Isto tudo ai sai por somente U$ 5,60. O módulo de fonte pode ser alimentado por USB ou a fonte de 9V do Arduino. Tem LED, 3.3v/5v e chave liga-desliga. O módulo foi feito para se encaixar perfeitamente no protoboard.

with-the-bootloader-font-b-nano-b-font-3-0-controller-compatible-for-font-b-arduino_220x220

Por menos de U$ 3,00 você leva esse Arduino Nano e pode transformá-lo em gravador ISP e conectar direto na protoboard. Tem a mesma capacidade dos Arduinos normais porém menor e prático.

20pcs-5x7-4x6-3x7-2x8-cm-double-side-copper-prototype-font-b-pcb-b-font-font_220x2201 qfn-tqfp-font-b-lqfp-b-font-qfp-16-80-pin-0-5mm-pitch-to-dip_220x220

Uma hora um projeto tem que ficar definitivo. E estas placas ajudam muito. Feitas em fibras são ótimas. Também as adaptadoras de CIs SMDs são extremamente úteis.

1pcs-usb-to-font-b-ttl-b-font-uart-module-ch340g-ch340-3-3v-5v-font_220x220

Úteis para qualquer desenvolvedor para MCUs. Estes módulos de comunicação serial também servem para alimentação 3.3.V/5V baixa corrente. Ligue o terra o positivo e RX com TX e pronto você tem uma forma de debugar seus programas. Compre uns 5 desses porque qualquer besteira sua e adeus módulo.

ac-100v-240v-converter-adapter-dc-9v-1a-font-b-power-b-font-font-b-supply_220x220 new-high-quality-5v-2a-v8-us-micro-usb-charger-charging-adapter-font-b-power-b_220x220

Seleção de fontes. A primeira de 9V para o Arduino e a ultima para o Raspberry Pi com 5V/2A.

free-shippin-5pcs-lot-font-b-atmega328p-b-font-pu-font-b-atmega328p-b-font-dip_220x220 the-original-5pcs-font-b-attiny85-b-font-20pu-font-b-attiny85-b-font-20pu-font_220x220 1pcs-stm32f103c8t6-arm-font-b-stm32-b-font-minimum-system-development-board-module-for-arduino_220x220

Quanto é um ATMEGA328P no Brasil? Que tal pelo mesmo preço comprar 5? E o Attiny85? E por ultimo os STM32 são uma boa pedida para começar a programar para ARM e arquiteturas 32 bits. Todos sem dúvida irão precisar de um gravador.  No caso dos Atmel o Arduino Nano já mostrado acima serve. Para o STM32 o STLINK pelo mesmo preço grava STM8 e STM32.

 

Bom espero que tenha sido útil. Montar uma bancada aos poucos com diversos CIs equipamentos vai lhe trazer um diferencial no desenvolvimento, aprendizado rico e economizar muita grana se tiver paciência e comprar na China. Agora o AliExpress aceita pagamentos por Boleto facilitando para os jovens sem conta em banco.

O meu carrinho vive cheio de coisas no site. É uma perdição.

 

Script MQL5 para exportar preços históricos de um ativo em CSV

Inaugurando assuntos na área de finanças segue um script que fiz para exportar informações de algum ativo no Metatrader5 para o formato CSV.
Uso isto para em seguida importar no python e fazer estudos estatísticos.
O script é um INDICADOR, logo você terá que adicionar ele à janela do ativo escolhido como indicador.
Esse script é muito simples. A cada tick ele será executado, assim é bom usar ele poucas vezes para não sobrecarregar o metatrader.
O nome de saída será ATIVO-xxxxx.csv e normalmente encontra-se no diretório MQL5/Files.
O arquivo deverá ser colocado em MQL5/Indicators para que o Metatrader reconheça como um indicador adicionável.

A imagem do post é um histograma dos valores de minima do candle posterior no caso de alta e vice versa feito com arquivo csv gerado por este script e importado em python. O ativo no caso é o Mini Indice. É interessante notar que na baixa os recuos (máxima do candle posterior) ocorrem com menos frequência e intensidade e que a maioria dos recuos ficam em torno de 50-100 nos candle de altas  10-50 pontos nos de baixa.

#include <Arrays\List.mqh>


int OnInit()
{

return(INIT_SUCCEEDED);
}

int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{


string S = Symbol() + "-" + Period() + ".csv";

int file_handle=FileOpen(S,FILE_READ|FILE_WRITE);
FileWrite(file_handle,"low,high,open,close");


for(int i = 1; i < rates_total; i++)
{


FileWrite(file_handle,low[i]+","+high[i]+","+open[i]+","+close[i]);

}

FileClose(file_handle);

return(rates_total);
}

Como exibir cotações de ações Ibovespa ou mundiais no Conky

conky-desktop

Exibir cotações de qualquer ativo ou moeda no Conky suportado pelo Yahoo Finance  ou para qualquer outro uso em Python é fácil através do módulo yahoo-finance.

Sem perda de tempo, instale o módulo yahoo-finance:


sudo pip install yahoo-finance

Faça alguns testes no terminal python:

>>> from yahoo_finance import Share
>>> VivaOMoro = Share('PETR4.SA')
>>> print VivaOMoro.get_open()
8.51

Se apareceu o preço então o módulo funciona. O seguinte script será usado para que o Conky exiba as informações sobre os ativos:

#!/usr/bin/python

from yahoo_finance import Share
from math import *

codigos = ['^BVSP', 'DOW', 'PETR4.SA', 'ETER3.SA']

for i in codigos:
	share = Share(i)
	percent = format ( 100 *  (  (  float(share.get_price())  / float (share.get_prev_close())   ) -1  ),'.2f')
	print (format(i,'10') +" " + format(float(share.get_price()),'10.2f')  + " " + percent + "%")

Salve em algum lugar e torne-o executável com chmod +x NOMEDOSCRIPT. E finalmente para  que o conky exiba as cotações usaremos o comando execpi no arquivo .conkyrc:


${font "Courier New"  MS:bold:size=8}${alignc}
${execpi  1 /CAMINHOPROSCRIPT/NOMEDOSCRIPT.py}

Veja que coloquei propositalmente a linha de formatação de fonte para lhe encorajar a usar fonte fixa ajudando, assim, no alinhamento, entretanto ainda não ficou excelente o alinhamento então sugestões serão bem vindas.

O numero 1 logo depois de execpi é o tempo de atualização em segundos. Muito baixo sem dúvida afinal se você estiver interessado em atualizações com menos de 12h provavelmente não esta interessado em ver cotações no Conky mas no MetaTrader por exemplo. É útil para Swing trade ou Position.

Para incorporar mais ativos acrescente o código correspondente na linha codigos = [‘^BVSP’, ‘DOW’, ‘PETR4.SA’, ‘ETER3.SA’] entre aspas simples com virgula. Veja que o Yahoo usa código levemente diferente do que estamos acostumados então vá ao site e pesquise pelos códigos.

Com algumas alterações no script é possível colocar o valor de uma carteira investida … e quem sabe um dia desses eu adapte o script Lua (que faz os círculos) para mostrar um gráfico …. um dia desses ….

E por falar em Conky …

Fica a dica que o Conky apesar de leve e consumir pouca memória diminui a durabilidade da bateria do notebook pois ‘acorda’ frequentemente a CPU. Uma sugestão é ou diminuir o tempo de refresh quando em modo bateria ou matar o processo de vez. Afinal é só um processo ‘cosmético’.

Ponteiros em 7 arquiteturas – de z80 a ARM

Eu admito que somente entendi ponteiros quando fiz a ponte entre código em C e Assembly. Ponteiros são complicados mesmo. É um disfarce de alto nível para o baixo nível da máquina. Ponteiros devem ser usados com cuidado em muitos aspectos; como no problema de alocação dinâmica e liberação da memória alocada, múltiplas instâncias do mesmo endereço, problemas de endianess, acessos não autorizados ou em áreas indesejadas …

Por curiosidade gerei o código assembly  do código em C abaixo para 7 processadores ou microcontroladores sendo eles: HCS08, STM8, Z80, X86-64,  ARM, ColdFire e AVR.

 int *a,*b;
 char *c;
 int i = 10;

void main(void)
 {

a = &i;
 b = a;
 *b = *b + 5;
 c = (char *) &i;
 *c = *c + 5;
 c = c + 5;

while (1);

}

E vamos aos códigos. É bom lembrar que diferenças irão ocorrer não somente pela arquitetura mas pelos compiladores usados. Um exemplo é o SDCC que para somar 5 não utilizou instrução de soma mas cinco incrementos para o Z80, provavelmente pela contagem de ciclos.

ColdFire – O mais limpo dos códigos

_main:
; main:
lea _i(a5),a0
move.l a0,_a(a5)
;
; 13: b = a;
;
move.l _a(a5),d0
move.l d0,_b(a5)
;
; 14: *b = *b + 5;
;
movea.l d0,a0
addq.l #5,(a0)
;
; 15: c = (char *) &i;
;
lea _i(a5),a0
move.l a0,_c(a5)
;
; 16: *c = *c + 5;
;
movea.l _c(a5),a0
mvs.b (a0),d0
addq.l #5,d0
move.b d0,(a0)
;
; 17: c = c + 5;
; 18:
; 19: while (1);
;
addq.l #5,_c(a5)
;
; 19: 1);
;
bra.l *+0</pre>

Z80 – Se aproveita de seus registradores de 16 Bits e acesso indireto

_main::
 61 ;ponteiros.c:9: a = &i;
ld de,#_i+0
ld (_a),de
 64 ;ponteiros.c:10: b = a;
ld hl,(_a)
ld (_b),hl
 67 ;ponteiros.c:11: *b = *b + 5;
ld hl,(_b)
push hl
ld c,(hl)
inc hl
ld b,(hl)
pop hl
inc bc
inc bc
inc bc
inc bc
inc bc
ld (hl),c
inc hl
ld (hl),b
 82 ;ponteiros.c:12: c = (char *) &i;
ld (_c),de
 84 ;ponteiros.c:13: *c = *c + 5;
ld hl,(_c)
ld a,(hl)
add a, #0x05
ld (hl),a
 89 ;ponteiros.c:14: c = c + 5;
ld hl,#_c
ld a,(hl)
add a, #0x05
ld (hl),a
inc hl
ld a,(hl)
adc a, #0x00
ld (hl),a
 98 ;ponteiros.c:16: while (1);
00102$:
jr 00102$

STM8 – O registrador x de 16 bits e as instruções de carga 16 bits ajudam muito


1 ; C Compiler for STM8 (COSMIC Software)
 2 ; Parser V4.10.2 - 02 Nov 2011
 3 ; Generator (Limited) V4.3.7 - 29 Nov 2011
 15 bsct
 16 0000 _i:
 17 0000 000a dc.w 10
 50 ; 7 main()
 50 ; 8 {
 52 switch .text
 53 0000 _main:
 57 ; 10 a = &i;
 59 ldw x,#_i
 60 ldw _a,x
 61 ; 11 b = a;
 63 ldw x,#_i
 64 ldw _b,x
 65 ; 12 *b = *b + 5;
 67 ldw x,_i
 68 addw x,#5
 69 ldw _i,x
 70 ; 13 c = (char *) &i;
 72 ldw x,#_i
 73 ldw _c,x
 74 ; 14 *c = *c + 5;
 76 ld a,_i
 77 add a,#5
 78 ld _i,a
 79 ; 15 c = c + 5;
 81 ldw x,#_i+5
 82 ldw _c,x
 83 L12:
 84 ; 17 while (1);
 86 jra L12
 140 xdef _main
 141 xdef _i
 142 switch .ubsct
 143 0000 _c:
 144 0000 0000 ds.b 2
 145 xdef _c
 146 0002 _b:
 147 0002 0000 ds.b 2
 148 xdef _b
 149 0004 _a:
 150 0004 0000 ds.b 2
 151 xdef _a
 171 end

HCS08 – Surpreso? Esse processador só tem um registrador index e um acumulador!


11: 
 12: a = &i;
 LDHX @i
 STHX a
 13: b = a;
 STHX b
 14: *b = *b + 5;
 LDHX ,X
 AIX #5
 TXA 
 PSHH 
 LDHX @i
 STA 1,X
 PULA 
 STA ,X
 15: c = (char *) &i;
 16: *c = *c + 5;
 ADD #5
 STA ,X
 17: c = c + 5;
 AIX #5
 STHX c
 L1E:
 19: while (1);
 BRA L1E
 21: }

X86-64 –

{
 push %rbp
 mov %rsp,%rbp

 a = &i;
 movq $0x0,0x0(%rip)  
 b = a;
 mov 0x0(%rip),%rax 
 mov %rax,0x0(%rip) 
 *b = *b + 5;
 mov 0x0(%rip),%rax 
  mov 0x0(%rip),%rdx 
 mov (%rdx),%edx
 add $0x5,%edx
 mov %edx,(%rax)
 c = (char *) &i;
 movq $0x0,0x0(%rip) 

 *c = *c + 5;
 mov 0x0(%rip),%rax 
 mov 0x0(%rip),%rdx 
 movzbl (%rdx),%edx
 add $0x5,%edx
 mov %dl,(%rax)
 c = c + 5;
 mov 0x0(%rip),%rax 
 add $0x5,%rax
 mov %rax,0x0(%rip) 

 while (1);
 jmp 65

ARM – É um RISC …


push {fp} ; (str fp, [sp, #-4]!)
add fp, sp, #0 
//a = &i;
ldr r3, [pc, #116] 
ldr r2, [pc, #116] 
str r2, [r3]
//b = a;
ldr r3, [pc, #104] 
ldr r3, [r3]
ldr r2, [pc, #104] 
str r3, [r2]
//*b = *b + 5;
ldr r3, [pc, #96] 
ldr r3, [r3]
ldr r2, [pc, #88] 
ldr r2, [r2]
ldr r2, [r2]
add r2, r2, #5
str r2, [r3]
//c = (char *) &i;
ldr r3, [pc, #72] 
ldr r2, [pc, #60] 
str r2, [r3]
//*c = *c + 5;
ldr r3, [pc, #60] 
ldr r3, [r3]
ldr r2, [pc, #52] 
ldr r2, [r2]
ldrb r2, [r2]
add r2, r2, #5
and r2, r2, #255 
strb r2, [r3]
//c = c + 5;
ldr r3, [pc, #28] 
ldr r3, [r3]
add r3, r3, #5
ldr r2, [pc, #16] 
str r3, [r2] 
//while (1);
b 80 

AVR – Infelizmente o processamento ficou todo em registradores


push r28
push r29
in r28, 0x3d ; 61
in r29, 0x3e ; 62 
// a = &i;
ldi r24, 0x00 ; 0
ldi r25, 0x00 ; 0
sts 0x0000, r25
sts 0x0000, r24
// b = a;
lds r24, 0x0000
lds r25, 0x0000
sts 0x0000, r25
sts 0x0000, r24
// *b = *b + 5;
lds r24, 0x0000
lds r25, 0x0000
lds r18, 0x0000
lds r19, 0x0000
mov r30, r18
mov r31, r19
ld r18, Z
ldd r19, Z+1 ; 0x01
subi r18, 0xFB ; 251
sbci r19, 0xFF ; 255
mov r30, r24
mov r31, r25
std Z+1, r19 ; 0x01
st Z, r18
// c = (char *) &i;
ldi r24, 0x00 ; 0
ldi r25, 0x00 ; 0
sts 0x0000, r25
sts 0x0000, r24
// *c = *c + 5;
lds r24, 0x0000
lds r25, 0x0000
lds r18, 0x0000
lds r19, 0x0000
mov r30, r18
mov r31, r19
ld r18, Z
subi r18, 0xFB ; 251
mov r30, r24
mov r31, r25
st Z, r18
// c = c + 5;
lds r24, 0x0000
lds r25, 0x0000
adiw r24, 0x05 ; 5
sts 0x0000, r25
sts 0x0000, r24

// while (1);
rjmp .+0

Afinal o que é um ponteiro? É simplesmente uma posição de memória que guarda um endereço que contém algum dado.

São dois endereços: Um é a variável que contém o dado, o outro contém o endereço desta variável.

Assim b = &i diz ao processador para guardar no endereço b o endereço de i. Logo b e i estão apontando para o mesmo dado. Mas b não é igual a i. A variável i é um endereço que contém um dado e o ponteiro b é um endereço que contém um endereço que contém um dado.

Veja em HCS08

// a = &i
LDHX @i
STHX a
Carrega o endereço de i em HX e posteriormente guarda o valor de HX em a

Veja que em STM8

// *b = *b + 5
67 ldw x,_i
68 addw x,#5
69 ldw _i,x

O compilador decidiu por não usar o ponteiro b para acessar i pois ele percebeu que b ainda contém o endereço de i e usou diretamente o endereço de i. Normalmente o correto seria carregar o valor de b em x e então indiretamente ‘(x)’ carregar o valor endereçado por x no acumulador e finalmente efetuar a soma.

Foi exatamente o que o Z80 iria fazer

ld hl,(_b)
push hl
ld c,(hl)
inc hl
ld b,(hl)
pop hl
inc bc
inc bc
inc bc
inc bc
inc bc
ld (hl),c
inc hl
ld (hl),b

Espero ter ajudado a compreender o que de fato é um ponteiro. Entretanto este post foi útil e agradável ao demonstrar as diferentes formas de acesso a memória em diferentes arquiteturas e principalmente as otimizações que compiladores diferentes fazem.

 

Sistemas Operacionais Modernos – [ Livros que você deveria ler ]

Inauguro esta série com este livro que qualquer programador de baixo nível (nível máquina) deveria ler. Sendo honesto é uma livro chato de se ler porém de grande valor. O autor Tanenbaum é aquele que Linus Torvalds no passado mandou aquela famosa mensagem sobre desenvolver um sistema livre e acabou por criar o Linux.

Já no começo do livro há uma narrativa bem humorada sobre a história do desenvolvimento de sistemas operacionais e suas definições. Um livro comum sobre a área apenas joga o assunto e nos trás a noção que tudo surgiu por mágica. Porém Tanenbaum de fato desenvolveu e acompanhou o desenvolvimento de sistemas operacionais e é honesto em nos mostrar que alguns algorítimos não surgiram do nada mas vieram para resolver um problema de usuários ‘espertinhos’ ou melhorar o desempenho de velhos leitores de fita por exemplo.

Em seguida cada parte de um sistema operacional é revelado com seus algorítimos, deficiências e vantagens. As vezes tanta honestidade te deixa confuso como por exemplo qual método de gerenciamento de processos é o melhor? Ou o que fazer com DeadLocks? E esse é o valor do Livro: Ao lê-lo todo você tem uma noção completa de um sistema operacional.

Eu li na biblioteca da faculdade um antigo que tinha como sistema de estudo o MS-DOS. Pulei este capitulo. Mas li o Amoeba e o Unix. Os atuais tem Windows, Linux e outros.

Ler este livro te elevará a níveis de conhecimentos preciosos como programador. Se você gosta de algorítimos, a história da informática, gosta de conhecer outras plataformas e desenvolve para sistemas embarcados este livro será de grande utilidade.

Ah! Esqueça PDF. Ele é um livro grande para ser lido inteiro. Compre o livro físico e leia com calma.

 

A era de ouro das revistas de eletrônica

Quando era adolescente juntava todo mês algumas moedas para comprar revistas de eletrônica. Minhas preferidas eram a Aprendendo e Praticando Eletrônica e a incomparável e didática Bê a Bá da Eletrônica e as temáticas da editora Fittipaldi.

Se tenho alguma? Poucas. Muitas amarelaram. Quando veio a internet ficaram esquecidas e depois de muitas mudanças algumas se foram, porém os ensinamentos ficaram.

E aqui fica a dica deste post: Neste site o sujeito publica scans das revistas de 80 e 90 e faz um ótimo trabalho. Recomendo!

http://www.blogdopicco.blogspot.co.id/2014/11/revistas-be-ba-da-eletronica.html

 

Android Box reiniciando ou desligando sozinho

Comprei um desses Android Box da China. São versáteis para jogar, assistir Youtube, Netflix e outras atividades tipicas do Android.
Entretanto o que comprei veio com um problema: Ele desligava sozinho quando o WiFi era muito exigido ou a GPU era usada.

Usando de analogia com o Raspberry Pi que tem um problema de performance quando a tensão caia abaixo de 4.97V imaginei que era problema de alimentação.Testei várias fontes e as fontes fracas faziam o aparelho se comportar muito mal. Mas nunca tive uma boa resposta mesmo com uma fonte de 2A.

Eis a solução:

IMG_20160320_095131514

Sim! Um capacitor eletrolítico de 1000uF que achei em sucatas ligado ao positivo e negativo. O capacitor menor eu tirei porque não fechava a caixa. Não sugiro ligar nos fios da fonte pois a impedância (mesmo que pequena) dos fios talvez atrapalhe.

E funciona que é uma beleza!

Outras causas

Porém alguns já relataram que não funcionou. Outro motivo relatado por Tiel (Abaixo nos comentários) é o excessivo aquecimento. Então neste caso um cooler ou dissipador mini para Raspberry PI colado no chip principal deverá ajudar.

Outro motivo comum de qualquer aparelho Android é aplicativos ruins instalados que corrompem o sistema. Neste caso forçar um ‘reset’ as configurações de fábrica deve ajudar. Saiba que tudo será apagado e o aparelho voltará a ficar como veio de fábrica. Normalmente este comando fica em Settings->Personal->Backup&Reset.

Onde adquirir?

As vezes as pessoas param aqui porque querem comprar um. Eu comprei o meu no famoso DX.com mas isso foi a alguns anos. Hoje o Aliexpress é a melhor opção pois tem preços melhores e aceita pagamento por boleto para quem não tem cartão de crédito (e da tempo de se arrepender!).

Veja os exemplos abaixo. O primeiro tem preço muito bom.

AliExpress.com Product – 2GB RAM+16GB ROM NEXBOX A95X Smart TV Box Amlogic S905X Quad core 64 Bit Android 6.0 4Kx2K 2.4GHz WiFi Media Player Set Top Box
AliExpress.com Product – GOTiT S805 TVBox+Royal IPTV 1950 Arabic African French Europe IPTV Channels Quad Core Smart 1G/8G Android KODI TV Set Top Box
AliExpress.com Product – KII Pro DVB-T2 + DVB-S2 Android 5.1 TV Box 2GB/16GB Amlogic S905 Quad-core Kodi 17.0 4K*2K 2.4G&5G Dual Wifi Bluetooth KIIpro

Este ai que comprei tem WiFi, Ethernet, GPU, entrada de MicroSD e saída HDMI e Video Composto e é esta saída que uso atualmente em uma TV analógica de tubo antiga. Outra boa aplicação é quando se viaja para algum lugar e você quer levar o Netflix junto.

sku_426763_6

Vídeo de válvula Termiônica feita a mão

Um célebre vídeo do francês Claude Paillard fazendo uma válvula do vidro à curva de teste no medidor de curvas. Para quem não sabe válvulas estão ai ainda como saídas de transmissores, radares e para alguns audiófilos. As válvulas tem uma curva de resposta que acrescentam harmônicas pares ao som tornando ele mais ‘rico’ e gostoso de se ouvir. Um Mosfet tem curva semelhante …. mas não vou entrar em polêmicas!

É de invejar tantos equipamentos e tanta habilidade.

Curta!

 

Orvibo Allone Versus Geeklink Thinker

Esqueça o Orvibo Allone. Comprei o aparelho para não somente usar nos aparelhos de casa como também para acender luzes e abrir portões. Não funciona. Ele não tem modo RF Learning Code.

Até que achei o maravilhoso: 

Universal GeekLink Thinker

Sim. Muito melhor. Ele realmente automatiza uma casa. Este aparelho tem um modo RF Learning que permite acender luzes e controlar portões que tenham a tecnologia Learning Code (código fixo).

E não é só isso ele embute muitas funções:

  • WiFi Router com Linux OpenWrt;
  • Conecta à internet com PPOE;
  • Tem dois Ethernet e um USB;
  • Modo de aprender códigos RF em 433Mhz/315Mhz 
  • Clonagem de controles remotos infravermelhos
  • IFTTT que significa IF This Then That (QBASIC!!?). O sistema de programação de regras
  • Monitoração remota pelo smartphone.
  • Ponte das cameras IP.

Achei um comprador no AliExpress com promoção que vem com o aparelho e uma camera IP por U$68,00. Bom preço.

Este aparelho nasceu do site de financiamento público Kickstarter e muitos outros estão nascendo por lá.

d298f63ee94925aa3f106c07b01e6660_original

E pensando bem eu tinha comprado o VoCore por lá (um micro linux com WiFi, USB e Ethernet e algumas GPIOS) e ele parado aqui pode fazer tudo isto que o GeekLink faz. Basta ligar os fios, conectores, e programá-lo … que trabalho!

STM32 no Linux

Programar Kits ou microcontroladores STM32 no Linux é perfeitamente possível graças ao GNU ARM Toolchain para tanto é necessário instalar este e outros pacotes primos como veremos neste post. Será mostrado aqui a instalação destes pacotes e um simples programa blink sem bibliotecas de suporte.

Há vários toolchains disponíveis para uC ARMs alguns que se utilizam das syscall de algum SO como o Linux e outros que não esperam nenhum Sistema Operacional por trás, programar assim é chamado comumente como ‘baremetal’.

Para debugar e gravar um STM32 será utilizado o ST-Util e o OpenOCD.

Instalando os pacotes

GCC + GDB + OpenOCD

Eu utilizo o ArchLinux mas não poderia discriminar o Ubuntu.
Para o Ubuntu:

sudo add-apt-repository ppa:terry.guo/gcc-arm-embedded
sudo apt-get update
sudo apt-get install gcc-arm-none-eabi
sudo apt-get install gdb-arm-none-eabi
sudo apt-get install openocd

ArchLinux users:

sudo pacman -S arm-none-eabi-binutils arm-none-eabi-gcc arm-none-eabi-gdb arm-none-eabi-newlib openocd stlink

Se tudo ocorreu corretamente teste a instalação abrindo um shell e digitando arm-none <TAB> isso fará o bash autocompletar a sequência e mostrar os executáveis instalados como nesta saída tipica:

arm-none-eabi-addr2line arm-none-eabi-gcc-4.7.4 arm-none-eabi-ld.bfd
arm-none-eabi-ar arm-none-eabi-gcc-ar arm-none-eabi-nm
arm-none-eabi-as arm-none-eabi-gcc-nm arm-none-eabi-objcopy
arm-none-eabi-c++ arm-none-eabi-gcc-ranlib arm-none-eabi-objdump
arm-none-eabi-c++filt arm-none-eabi-gcov arm-none-eabi-ranlib
arm-none-eabi-cpp arm-none-eabi-gdb arm-none-eabi-readelf
arm-none-eabi-elfedit arm-none-eabi-gdbtui arm-none-eabi-size
arm-none-eabi-g++ arm-none-eabi-gprof arm-none-eabi-strings
arm-none-eabi-gcc arm-none-eabi-ld arm-none-eabi-strip

Primeiro Programa

Antes de tudo vamos iniciar a configuração do vetor de interrupções, a routina de reset e alguns Defines para alguns registradores que iremos usar. Este programa foi feito para o kit STM32 Discovery F0. Com poucas modificações e entendendo o processo a migração para outros (M3/M4) será fácil.

O primeiro arquivo boot.h contém alguns typedefs e Defines para registradores de clock e GPIOs, declaração de váriaveis externas do arquivo de link, prototypes de funções e o vetor de interrupções (que neste caso só cobrirá as interrupções ARM). Também o Reset e SystemInit bem como as funções de tratamento de interrupções serão declaradas.

boot.h

// boot.h
#define uint32_t unsigned int
#define IO_Uint32 volatile unsigned int
typedef struct
{
IO_Uint32 ACR;
IO_Uint32 KEYR;
IO_Uint32 OPTKEYR;
IO_Uint32 SR;
IO_Uint32 CR;
IO_Uint32 AR;
IO_Uint32 RESERVED;
IO_Uint32 OBR;
IO_Uint32 WRPR;
} _FLASH;

typedef struct
{
IO_Uint32 CR;
IO_Uint32 CFGR;
IO_Uint32 CIR;
IO_Uint32 APB2RSTR;
IO_Uint32 APB1RSTR;
IO_Uint32 AHBENR;
IO_Uint32 APB2ENR;
IO_Uint32 APB1ENR;
IO_Uint32 BDCR;
IO_Uint32 CSR;
IO_Uint32 AHBRSTR;
IO_Uint32 CFGR2;
IO_Uint32 CFGR3;
IO_Uint32 CR2;
} _RCC;

typedef struct {
IO_Uint32 MODER;
IO_Uint32 OTYPER;
IO_Uint32 OSPEEDR;
IO_Uint32 PUPDR;
IO_Uint32 IDR;
IO_Uint32 ODR;
IO_Uint32 BSRR;
IO_Uint32 LCKR;
IO_Uint32 AFRL[2];
IO_Uint32 BRR;
} _GPIO ;

#define GPIOC ((_GPIO *) 0x48000800)
#define RCC ((_RCC *) 0x40021000)
#define FLASH ((_FLASH *) 0x40022000)

// Globais do arquivo do linker
extern void *_estack;
extern unsigned char _sidata;
extern unsigned char _sdata;
extern unsigned char _edata;
extern unsigned char _sbss;
extern unsigned char _ebss;
extern void main (void);

// Entry Point
void Reset (void);
// Default Interrupt Handler
void Default_Handler(void) __attribute__( ( interrupt ) );
static void HardFault_Handler( void )/* __attribute__( ( naked ) )*/;

__attribute__ ((section(".isr_vector")))
void (* const Vectors[])(void) = {
(void(*)(void)) &amp;_estack,
Reset,
Default_Handler, //NMI_Handler,
HardFault_Handler, //FaultHandler,
0,
0,
0,
0,
0,
0,
0,
Default_Handler, //SVC_Handler,
0,
0,
Default_Handler, //PendSV_Handler,
Default_Handler, //SysTick_Handler,
};

static void HardFault_Handler( void ){
__asm__("BKPT");
while (1);
}

#pragma weak _exit = Default_Handler
void Default_Handler(void) {
__asm__("BKPT");
while (1);
}

void SystemInit(void)
{
/* Reseta o RCC clock para  o padrão ------------*/
/* Set HSION bit */
RCC-&gt;CR |= (uint32_t)0x00000001;

/* Reset SW[1:0], HPRE[3:0], PPRE[2:0], ADCPRE, MCOSEL[2:0], MCOPRE[2:0] and PLLNODIV bits */
RCC-&gt;CFGR &amp;= (uint32_t)0x08FFB80C;

/* Reset HSEON, CSSON and PLLON bits */
RCC-&gt;CR &amp;= (uint32_t)0xFEF6FFFF;

/* Reset HSEBYP bit */
RCC-&gt;CR &amp;= (uint32_t)0xFFFBFFFF;

/* Reset PLLSRC, PLLXTPRE and PLLMUL[3:0] bits */
RCC-&gt;CFGR &amp;= (uint32_t)0xFFC0FFFF;

/* Reset PREDIV[3:0] bits */
RCC-&gt;CFGR2 &amp;= (uint32_t)0xFFFFFFF0;

/* Reset USART1SW[1:0], I2C1SW, CECSW, USBSW and ADCSW bits */
RCC-&gt;CFGR3 &amp;= (uint32_t)0xFFFFFE2C;

/* Reset HSI14 bit */
RCC-&gt;CR2 &amp;= (uint32_t)0xFFFFFFFE;

/* Desabilita todas as interrupções*/
RCC-&gt;CIR = 0x00000000;

FLASH-&gt;ACR = 0x00000011;

}
// O começo de tudo antes de main
__attribute__( ( naked ) ) void Reset (void) {

register unsigned char *src, *dst;

// Copia os dados da flash para a ram (const, static initialized variables)
src = &amp;_sidata;
dst = &amp;_sdata;
while(dst &lt; &amp;_edata) *dst++ = *src++;

// Inicializa o bss (C static variables non initialized)
dst = &amp;_sbss;
while(dst &lt; &amp;_ebss) *dst++ = 0;

SystemInit();
//__libc_init_array();
// ... and finally call main saving sp
__asm__("b main");

}

A função Reset inicializa a variáveis estáticas com zero, chama SystemInit e finalmente chama a função Main com um brunch para economizar RAM na pilha.

main.h

O segundo arquivo é o fluxo principal do programa onde esta a função Main. Este programa irá piscar os LEDs do kit nas portas PC9 e PC8. O tipo GPIO foi declarado anteriormente em boot.h.

#include "boot.h"

__attribute__( ( naked ) ) void main (void){

RCC-&gt;AHBENR |= ((unsigned int) 0x00080000); // Enable GPIOC otherwise a hardfault
GPIOC-&gt;MODER = 0x55555555; // Output mode for all PORTC

volatile register int i;

while (1) {

GPIOC-&gt;BSRR = 0x0000ffff;
for (i = 0; i &lt; 50000; i++); GPIOC-&gt;BSRR = 0xffff0000;
for (i = 0; i &lt; 50000; i++);

};

__asm__("b .");
};

Makefile e Link Script

Acabou? Não  Ainda faltam dois arquivos o MakeFile e o Script do Linker.

Este MakeFile é completo o que compilará, mostrará o tamanho do código, converterá ELF para BIN, irá gerar uma listagem em assembly e finalmente grava na flash o programa. Simplesmente execute o make no terminal de onde estão estes arquivos.

all:
arm-none-eabi-gcc -mcpu=cortex-m0 -gdwarf-2 -mthumb -nostdlib -mlittle-endian -Tlink.ld main.c -o main
arm-none-eabi-size main
arm-none-eabi-nm -S main
arm-none-eabi-objdump -d -M intel -S main &gt; bin.asm
arm-none-eabi-objcopy -O binary main main.bin
st-flash erase
st-flash --reset write main.bin 0x08000000
debug:
arm-none-eabi-gdb main -tui --eval-command="target extended-remote :4242"

E por fim o link  script. Lugar onde as posições de memória são definidos, o Entry Point e algumas globais usadas pelo Reset para inicializar a variáveis estaticas e constantes.

/* Entry Point */
ENTRY(Reset)

/* Highest address of the user mode stack */
_estack = 0x20001FFF; /* end of RAM */

/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0; /* Only usefull if you use alloc, malloc */
_Min_Stack_Size = 0x800;

MEMORY
{
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 64K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 8K
}

/* Define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} &gt;FLASH

/* The program code and other data goes into FLASH */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)

KEEP (*(.init))
KEEP (*(.fini))

. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} &gt;FLASH

/* Constant data goes into FLASH */
.rodata :
{
. = ALIGN(4);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
} &gt;FLASH

.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } &gt;FLASH
.ARM : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} &gt;FLASH

.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} &gt;FLASH
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} &gt;FLASH
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} &gt;FLASH

/* used by the startup to initialize data */
_sidata = LOADADDR(.data);

/* Initialized data sections goes into RAM, load LMA copy after code */
.data :
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */

. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} &gt;RAM AT&gt; FLASH

/* Uninitialized data section */
. = ALIGN(4);
.bss :
{
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)

. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} &gt;RAM

._user_heap_stack :
{
. = ALIGN(4);
PROVIDE ( end = . ); /* Necessary for newlibc */
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(4);
} &gt;RAM

/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}

.ARM.attributes 0 : { *(.ARM.attributes) }
}

Foi apresentado aqui como programar microcontroladores STM32 no Linux utilizando as ferramentas gratuitas disponíveis. Não utilizei o conjunto de bibliotecas oficiais da ST chamado Cube para demonstrar também como é um programar um uC sem este suporte.

Como evolução o leitor irá integrar o Cube e utilizar o CubeMX para facilmente inicializar o uC e partir para a programação em si.

Eu programo microcontroladores STM32 no Linux profissionalmente com estas ferramentas e integro tudo no Code:Blocks que é uma ótima alternativa aos ambientes caros como IAR e Keil. Eu não me adaptei muito aos derivados gratuitos do Eclipse porque não gosto de programas que demoram para inicializar …

EDIT: O WordPress vive mudando meu código postado transformando caracteres especiais em formato HTML Entity e não sei como mudar isso. Se alguém ai souber me ajude por favor porque se você copiar e colar os códigos daqui será necessário corrigir muita pontuação.