
Introdução
Arduino é uma plataforma de hardware de código aberto popular, conhecida por sua simplicidade, facilidade de uso e abertura. Ele fornece uma rica coleção de funções de biblioteca e códigos de exemplo, tornando-o acessível mesmo para indivíduos sem experiência em programação. Além disso, a comunidade Arduino é altamente ativa, permitindo fácil acesso a uma ampla variedade de tutoriais, documentação e suporte de projetos.
A série Milk-V Duo agora suporta o desenvolvimento do Arduino. Você pode usar diretamente o Arduino IDE e, após uma configuração simples, começar a utilizá-lo.
A CPU da série Duo adota um design de núcleo grande, onde o firmware do Arduino é executado no núcleo pequeno, enquanto o núcleo grande é responsável pela comunicação com o IDE do Arduino. Ele recebe o firmware do Arduino e o carrega no pequeno núcleo para execução. Ao mesmo tempo, o sistema Linux no grande núcleo também funciona normalmente.
1. Instale o Arduino
Arduino IDE oferece suporte a três sistemas operacionais: Windows, Linux e macOS. De acordo com o sistema que você está usando, acesse o site oficial do Arduino para baixar o pacote de instalação correspondente para instalação. A versão mais recente atual é 2.3.2 e é recomendado usar a versão mais recente.
Adicione o Duo ao Arduino
Abra o Arduino IDE, selecione Preferences
no menu File
e adicione o endereço do arquivo de configuração do Duo na aba Additional boards manager URLs
Settings
:
https://github.com/milkv-duo/duo-arduino/releases/download/config/package_sg200x_index.json
Faça download do endereço do arquivo json mais recente em Releases .
Se você configurou outros endereços de placa de desenvolvimento antes, separe-os com vírgulas ou clique no ícone no lado direito da barra de endereço para abrir a janela e siga as instruções para adicioná-los.
Após configurar, selecione menu Board
no menu Tools
, abra o Boards Manager
, procure por SG200X e clique em Install
.
Neste ponto, o ambiente de desenvolvimento Duo no Arduino IDE foi instalado. Agora você pode escrever e testar o código.
Teste o pisca LED
Atualmente, o sistema de cartão SD do Duo precisa gravar firmware compatível com Arduino. Faça download do firmware com o prefixo arduino
da versão mais recente do firmware.
Consulte Inicialize o Duo para instalar o sistema de cartão SD.
No caso
arduino-milkv-duo256m-sd-v1.1.2-2024-0801.img.zip
Use um cabo USB para conectar o Duo ao computador e o Duo ligará automaticamente.
O firmware padrão do Duo, o sistema Linux de núcleo grande, controlará o piscar do LED integrado. Isto é conseguido através do script de inicialização. Agora vamos usar o Arduino de núcleo pequeno para acender o LED. Precisamos desabilitar o script de LED piscando no Linux de núcleo grande. No terminal Execute in do Duo:
mv /mnt/system/blink.sh /mnt/system/blink.sh_backup && sync
Ou seja, renomeie o script de LED piscando. Após reiniciar o Duo, o LED não piscará mais:
reboot
Neste momento, haverá um dispositivo serial adicional na “Porta” do “Gerenciador de Dispositivos” do computador.
Na interface principal do Arduino IDE, clique em Select Board
e, em seguida, clique em Select other board and port...
Procure por "duo", selecione Duo Dev Module
para Duo, selecione Duo256 Dev Module
para Duo256M, selecione a porta serial correspondente na porta e clique em OK.
Abra o programa Examples
> 01.Basics
> Blink
de teste no menu File
do Arduino IDE. A função deste programa é piscar o LED integrado do dispositivo Arduino. In Duo Também é compatível. Pode ser necessário instalar o pyserial para fazer o upload e, em seguida, vamos clicar no botão Upload
para testar:
Neste momento, você pode ver o LED da placa Duo piscando em intervalos de 1 segundo.
2. Duo Arduino pin resource
Duo
SPI PWM I2C UART GPIO NAME PIN PIN NAME GPIO ADC 1 GP0 1 40 VBUS 2 GP1 2 39 VSYS GND 3 38 GND PWM7 GP2 4 37 3V3_EN PWM6 GP3 5 36 3V3(OUT) PWM5 UART3_TX GP4 6 35 PWM6 UART3_RX GP5 7 34 GND 8 33 GND SPI2_SCK PWM9 I2C3_SDA GP6 9 32 GP27 SPI2_MOSI PWM8 I2C3_SCL GP7 10 31 GP26 ADC1 SPI2_MISO PWM7 I2C1_SDA GP8 11 30 RUN SPI2_CSn PWM4 I2C1_SCL GP9 12 29 GP22 GND 13 28 GND PWM10 I2C2_SDA 14 GP10 14 27 GP21 27 PWM11 I2C2_SCL 15 GP11 15 26 GP20 26 PWM4 GP12 16 25 GP19 25 PWM5 GP13 17 24 GP18 24 GND 18 23 GND 19 GP14 19 22 GP17 22 20 GP15 20 21 GP16 21 0 LED
SPI | PWM | I2C | UART | GPIO | NAME | PIN | PIN | NAME | GPIO | ADC |
---|---|---|---|---|---|---|---|---|---|---|
1 | GP0 | 1 | 40 | VBUS | ||||||
2 | GP1 | 2 | 39 | VSYS | ||||||
GND | 3 | 38 | GND | |||||||
PWM7 | GP2 | 4 | 37 | 3V3_EN | ||||||
PWM6 | GP3 | 5 | 36 | 3V3(OUT) | ||||||
PWM5 | UART3_TX | GP4 | 6 | 35 | ||||||
PWM6 | UART3_RX | GP5 | 7 | 34 | ||||||
GND | 8 | 33 | GND | |||||||
SPI2_SCK | PWM9 | I2C3_SDA | GP6 | 9 | 32 | GP27 | ||||
SPI2_MOSI | PWM8 | I2C3_SCL | GP7 | 10 | 31 | GP26 | ADC1 | |||
SPI2_MISO | PWM7 | I2C1_SDA | GP8 | 11 | 30 | RUN | ||||
SPI2_CSn | PWM4 | I2C1_SCL | GP9 | 12 | 29 | GP22 | ||||
GND | 13 | 28 | GND | |||||||
PWM10 | I2C2_SDA | 14 | GP10 | 14 | 27 | GP21 | 27 | |||
PWM11 | I2C2_SCL | 15 | GP11 | 15 | 26 | GP20 | 26 | |||
PWM4 | GP12 | 16 | 25 | GP19 | 25 | |||||
PWM5 | GP13 | 17 | 24 | GP18 | 24 | |||||
GND | 18 | 23 | GND | |||||||
19 | GP14 | 19 | 22 | GP17 | 22 | |||||
20 | GP15 | 20 | 21 | GP16 | 21 | |||||
0 | LED |
Duo256M
|
---|
3. EXEMPLO DE CÓDIGO
Este programa implementa o pino físico 20 do Duo para emitir níveis altos e baixos ciclicamente com um intervalo de 1 segundo, e observar o fenômeno através de um LED externo.
O método de conexão é o seguinte. O pólo negativo do LED é conectado ao terra do Duo (por exemplo, pino 18), e o pólo positivo é conectado em série com um resistor de 1K e depois conectado ao pino 20:
Código de teste:
#define TEST_PIN 20 //0,1,2,14,15,19,20,21,22,24,25,26,27
// the setup function runs once when you press reset or power the board
void setup() {
pinMode(TEST_PIN, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(TEST_PIN, HIGH); // turn the TEST_PIN on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(TEST_PIN, LOW); // turn the TEST_PIN off by making the voltage LOW
delay(1000); // wait for a second
}
EXEMPLO DE UART
A porta serial UART UART3 usa um pino físico 6/7
por padrão. Ao depurar o programa Arduino, você pode imprimir informações de depuração por meio desta porta serial.
O método de conexão é o seguinte. O computador pode usar um cabo de porta serial USB para TTL. O nível lógico é 3,3V e a taxa de transmissão é 115200. O RX do cabo da porta serial é conectado ao PIN 6 UART3_TX do Duo. O TX do cabo da porta serial está conectado ao PIN 7 UART3_RX do Duo. A porta serial O GND da linha é conectado a qualquer GND do Duo, como o pino 3:
Código de teste:
void setup() {
Serial.begin(115200);
}
void loop() {
Serial.printf("hello world\r\n");
delay(1000);
}

Após a execução, você pode ver a string "hello world" impressa a cada 1 segundo na ferramenta de porta serial do computador:
hello worldhello world
Além disso, a porta serial padrão usa a interface UART3 do Duo, portanto Serial3
também pode ser usada no programa:
void setup() {
Serial3.begin(115200);
}
void loop() {
Serial3.printf("hello world\r\n");
delay(1000);
}
EXEMPLO DE I2C
Os recursos da interface I2C do Duo e Duo256M são diferentes e precisam ser usados de acordo com o diagrama de recursos de pinos anterior.
I2C0 envia dados para I2C1 (Duo)
A conexão de hardware é a seguinte. Conecte os pinos SDA e SCL de I2C0 e I2C1 correspondentemente e, em seguida, conecte a porta serial ao computador para visualizar as informações de impressão de acordo com o método no exemplo UART acima.
A função Wire
no Duo é mapeada para I2C0 por padrão, ou seja, Wire
é equivalente a Wire0
.
Código de teste:
#include <Wire.h>
void receive(int a) {
Serial.printf("receive %d bytes\n\r", a);
while(a--) {
Serial.printf("%d \n\r", Wire1.read());
}
}
void setup() {
Serial.begin(115200);
Wire1.begin(0x50);
Wire1.onReceive(receive);
Wire.begin();
Serial.printf("test slave\n\r");
Wire1.print();
}
byte val = 0;
void loop() {
Wire.beginTransmission(0x50); // Transmit to device number 0x50
Serial.printf("send %d \n\r", ++val);
Wire.write(val); // Sends value byte
Wire.endTransmission(); // Stop transmitting
Wire1.onService();
delay(1000);
}

Resultado dos testes:
test slave
Wire1: 1
[iic_dump_register]: ===dump start
IC_CON = 0x22
IC_TAR = 0x55
IC_SAR = 0x50
IC_SS_SCL_HCNT = 0x1ab
IC_SS_SCL_LCNT = 0x1f3
IC_ENABLE = 0x1
IC_STATUS = 0x6
IC_INTR_MASK = 0x224
IC_INTR_STAT = 0
IC_RAW_INTR_STAT = 0x10
[iic_dump_register]: ===dump end
send 1
receive 1 bytes
1
send 2
receive 1 bytes
2
send 3
receive 1 bytes
3
send 4
receive 1 bytes
4
I2C1 envia dados para I2C2 (Duo256M) )
Observe que o Duo256M não possui I2C0.
A conexão de hardware é a seguinte. Conecte os pinos SDA e SCL de I2C1 e I2C2 correspondentemente e, em seguida, conecte a porta serial ao computador para visualizar as informações de impressão de acordo com o método no exemplo UART acima.
A função Wire
no Duo256M é mapeada para I2C1 por padrão, ou seja, Wire
é equivalente a Wire1
.
Código de teste:
#include <Wire.h>
void receive(int a) {
Serial.printf("receive %d bytes\n\r", a);
while(a--) {
Serial.printf("%d \n\r", Wire2.read());
}
}
void setup() {
Serial.begin(115200);
Wire2.begin(0x50);
Wire2.onReceive(receive);
Wire.begin();
Serial.printf("test slave\n\r");
Wire2.print();
}
byte val = 0;
void loop() {
Wire.beginTransmission(0x50); // Transmit to device number 0x50
Serial.printf("send %d \n\r", ++val);
Wire.write(val); // Sends value byte
Wire.endTransmission(); // Stop transmitting
Wire2.onService();
delay(1000);
}
Resultado dos testes:
test slave
Wire2: 1
[iic_dump_register]: ===dump start
IC_CON = 0x22
IC_TAR = 0x55
IC_SAR = 0x50
IC_SS_SCL_HCNT = 0x1ab
IC_SS_SCL_LCNT = 0x1f3
IC_ENABLE = 0x1
IC_STATUS = 0x6
IC_INTR_MASK = 0x224
IC_INTR_STAT = 0
IC_RAW_INTR_STAT = 0x10
[iic_dump_register]: ===dump end
send 1
receive 1 bytes
1
send 2
receive 1 bytes
2
send 3
receive 1 bytes
3
send 4
receive 1 bytes
4
EXEMPLO DE SPI
A conexão de hardware é a seguinte. Faça um curto-circuito no MOSI e MISO do SPI, ou seja, pino 10 e pino 11, e a seguir conecte a porta serial ao computador de acordo com o método do exemplo UART acima para visualizar as informações de impressão.
Código de teste:
#include <SPI.h>
char str[]="hello world\n";
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
SPI.begin();
}
byte i = 0;
void loop() {
// put your main code here, to run repeatedly:
// digitalWrite(12, 1);
SPI.beginTransaction(SPISettings());
Serial.printf("transfer %c\n\r", str[i]);
char out = SPI.transfer(str[i++]); // spi loop back
SPI.endTransaction();
Serial.printf("receive %x \n\r", out);
i %= 12;
}
Resultado dos testes:
receive a
transfer h
receive 68
transfer e
receive 65
transfer l
receive 6c
transfer l
receive 6c
transfer o
receive 6f
transfer
receive 20
transfer w
receive 77
transfer o
receive 6f
transfer r
receive 72
transfer l
receive 6c
transfer d
receive 64
transfer
Exemplo de uso de PWM
A conexão de hardware é a seguinte. Conecte o GP4 do DUO ao terminal negativo do LED.
Código de teste:
void setup() {
pinMode(6, OUTPUT);
}
void loop() {
for(int i = 128; i < 255; i++)
{
analogWrite(6,i);
delay(50);
}
for(int i = 255; i > 128; i--)
{
analogWrite(6,i);
delay(50);
}
}
Após compilar e gravar, você pode observar o efeito de respiração da luz LED.
EXEMPLO DE ADC (3.3V)
A conexão de hardware é a seguinte. Conecte o GP26 do DUO ao pino de sinal do potenciômetro e conecte os outros dois pinos aos polos positivo e negativo da fonte de alimentação, respectivamente.
Código de teste:
int adc_get_val = 0;
void setup() {
pinMode(0,OUTPUT);
}
void loop() {
adc_get_val = analogRead(31);
digitalWrite(0,HIGH);
delay(adc_get_val);
digitalWrite(0,LOW);
delay(adc_get_val);
}
Após compilar e gravar, você pode observar que a frequência de piscar do LED integrado muda conforme a posição do potenciômetro muda.
EXEMPLO DE USO DA CAIXA POSTAL (MAILBOX) - COMUNICAÇÃO ENTRE NUCLEOS
Compile e grave o código a seguir no pequeno núcleo do Arduino. Este programa pode ler as informações enviadas pelo núcleo grande (large core) da MailBox e imprimi-las na porta serial. Para fiação da porta serial, consulte o exemplo de uso de UART neste capítulo.
#include "mailbox.h"
struct valid_t {
uint8_t linux_valid;
uint8_t rtos_valid;
} __attribute__((packed));
typedef union resv_t {
struct valid_t valid;
unsigned short mstime; // 0 : noblock, -1 : block infinite
} resv_t;
typedef struct cmdqu_t cmdqu_t;
/* cmdqu size should be 8 bytes because of mailbox buffer size */
struct cmdqu_t {
uint8_t ip_id;
uint8_t cmd_id : 7;
uint8_t block : 1;
union resv_t resv;
unsigned int param_ptr;
} __attribute__((packed)) __attribute__((aligned(0x8)));
void showmsg(MailboxMsg msg) {
cmdqu_t *cmdq;
Serial.print("Get Msg: ");
Serial.println(*(msg.data), HEX);
cmdq = (cmdqu_t *)msg.data;
Serial.printf("cmdq->ip_id = %d\r\n", cmdq->ip_id);
Serial.printf("cmdq->cmd_id = %x\r\n", cmdq->cmd_id);
Serial.printf("cmdq->block = %d\r\n", cmdq->block);
Serial.printf("cmdq->para_ptr = %x\r\n", cmdq->param_ptr);
*(msg.data) = 0;
}
void setup() {
Serial.begin(115200);
mailbox_init(false);
mailbox_register(0, showmsg);
mailbox_enable_receive(0);
Serial.println("Mailbox Start");
}
void loop() {
}
Compile o programa de teste mailbox_test e execute-o em Linux de grande porte. O programa de teste foi armazenado no armazém duo-examples. Você pode consultar o README para compilação.
Após a execução, a saída do grande núcleo do Linux:
C906B: cmd.param_ptr = 0x2
C906B: cmd.param_ptr = 0x3
Impressão de porta serial de núcleo pequeno:
Mailbox Start
Get Msg: 19300
cmdq->ip_id = 0
cmdq->cmd_id = 13
cmdq->block = 1
cmdq->para_ptr = 2
Get Msg: 19300
cmdq->ip_id = 0
cmdq->cmd_id = 13
cmdq->block = 1
cmdq->para_ptr = 3
4. EXEMPLOS DE SENSORES
Fonte L9110H_test: https://github.com/milkv-duo/duo-arduino-examples/tree/master/L9110H_test
Para o exemplo de código do chip do driver do motor DC L9110H, conecte os fios de acordo com os comentários do código e, em seguida, queime e execute. O motor funcionará em ciclos de aceleração e desaceleração graduais e reverterá a aceleração e desaceleração graduais.
L9110H_test
Fonte LCD1602_test: https://github.com/milkv-duo/duo-arduino-examples/tree/master/LCD1602_test
Necessário adicionar LIB
Exemplo de código para a tela da interface LCD1602 I2C. Conecte os fios de acordo com os comentários do código e depois queime e execute. A tela exibirá uma string.
LCD1602
Fonte LCD2004_test: https://github.com/milkv-duo/duo-arduino-examples/tree/master/LCD2004_test
LCD2004
Exemplo de código para a tela da interface LCD2004 I2C. Conecte os fios de acordo com os comentários do código e depois queime e execute. A tela exibirá uma string.
Buzzer
fonte buzzer_test: https://github.com/milkv-duo/duo-arduino-examples/tree/master/buzzer_test
Exemplo de código para o módulo de campainha, conectado de acordo com os comentários do código e gravado para funcionar. A campainha toca três frequências diferentes de bipes em um loop.
HC-SR04
Fonte hc_sr04_test: https://github.com/milkv-duo/duo-arduino-examples/tree/master/hc_sr04_test
Exemplo de código para módulo sensor de medição de distância ultrassônico HC-SR04. Após gravar e executar o exemplo de código, a placa imprimirá os dados de distância medidos na porta serial.
RC522
Fonte rc522_test: https://github.com/milkv-duo/duo-arduino-examples/tree/master/rc522_test
Exemplo de código para módulo de leitura e gravação RFID RC522. Após gravar e executar o código, a placa fará um loop para verificar se o cartão de identificação foi lido. Se o cartão de identificação for detectado, ele imprimirá as informações do tipo e número do cartão na porta serial.
SSD1306
Fonte ssd1306_test: https://github.com/milkv-duo/duo-arduino-examples/tree/master/ssd1306_test
Requer instalação das LIB
Adafruit_BusIO.zip
Adafruit_GFX_Library.zip
Adafruit_SSD1306.zip
Exemplo de código para módulo de tela OLED SSD1306. Após a fiação de acordo com os comentários e gravação do código, a tela exibe uma animação dinâmica dos olhos.
5. API DO ARDUINO
Digital I/O
digitalWrite()
digitalRead()
pinMode()
Analog I/O
analogRead()
analogReadResolution()
analogWrite()
analogWriteResolution()
Wire(I2C)
begin()
beginTransmission()
endTransmission()
requestFrom()
write()
available()
read()
onReceive()
onRequest()
Questões: suporte@smartcore.com.br
Referências
Sobre a SMARTCOREA SMARTCORE FORNECE CHIPS E MÓDULOS PARA IOT, COMUNICAÇÃO WIRELESS, BIOMETRIA, CONECTIVIDADE, RASTREAMENTO E AUTOMAÇÃO. NOSSO PORTFÓLIO INCLUI MODEM 2G/3G/4G/NB-IOT, SATELITAL, MÓDULOS WIFI, BLUETOOTH, GPS, SIGFOX, LORA, LEITOR DE CARTÃO, LEITOR QR CCODE, MECANISMO DE IMPRESSÃO, MINI-BOARD PC, ANTENA, PIGTAIL, BATERIA, REPETIDOR GPS E SENSORES.
Digital I/O
digitalWrite()
digitalRead()
pinMode()
Analog I/O
analogRead()
analogReadResolution()
analogWrite()
analogWriteResolution()
Wire(I2C)
begin()
beginTransmission()
endTransmission()
requestFrom()
write()
available()
read()
onReceive()
Nenhum comentário:
Postar um comentário