Eu construo esses seqüenciadores de música .
Só que não é exatamente um sequenciador, é uma interface física para um sequenciador. O sequenciador é um aplicativo que roda em um laptop ao qual o sequenciador se conecta, permitindo que o usuário faça loops de bateria em tempo real. É bem divertido, mas requer um laptop porque o seqüenciador não está 'on-board'.
O que eu adoraria é fazer o seqüenciamento a bordo do meu dispositivo.
Agora, vamos supor que eu sei como resolver a conformidade de classe para a conectividade USB MIDI, e também vamos supor que eu possa descobrir como conectar um arduino para enviar notas MIDI a partir de uma porta DIN de 5 pinos. O que mais me preocupa é o desvio do tempo ao longo do tempo devido ao tempo inconsistente em quantidades mínimas em cada execução do loop de eventos.
Algumas coisas que eu sei:
Você não deve confiar
delay()
para controlar o loop de tempo. O atraso interrompe toda a operação do firmware, e isso não pode funcionar, porque eu preciso pesquisar na interface do usuário física se há alterações enquanto a sequência está em execução.Os cálculos baseados em
millis()
são melhores porque o firmware pode continuar a operar e agir quando uma certa contagem tiver decorrido.Embora nenhum dos meus controles físicos esteja acionando rotinas de interrupção, algumas operações podem atrasar a
loop()
execução do principal . Se eu projetar uma função que aguarda a entrada do usuário, isso obviamente pode causar o problema de perder um "prazo" para agir se amillis()
contagem terminar. Eu sei que esse problema é do meu próprio projeto ...
Questões:
A. O arduino baseado no AVR é um microcontrolador apropriado para pesquisar uma interface do usuário e executar um loop de tempo de missão crítica? Eu sei que há um Arduino baseado em ARM agora muito mais rápido. Um Teensy 3.0 seria uma alternativa melhor? Ambas são placas de 3,3V, então esse é outro conjunto de questões para trabalhar ... mas vou ignorar isso por enquanto.
B. Devo dividir a tarefa em dois microprocessadores? Um para lidar com pesquisas e atualização da interface do usuário e outro para o loop de temporização de missão crítica.
c. Algo mais?
Meu principal objetivo é não precisar usar um computador. Também quero calcular o balanço, mas, nesse caso, o balanço não significa nada se eu não tiver um tempo preciso e bloqueado. Obrigada pelo Conselho!
noInterrupts();
interrompe a instabilidade, mas também interrompe todas as interrupções desejadas.Respostas:
As interrupções são suas amigas para tarefas sensíveis ao tempo, mas somente se você colocar os aspectos críticos do tempo na interrupção e não houver outras interrupções acontecendo com prioridade mais alta. Os microcontroladores no Arduino "baseado em AVR" (por exemplo, o ATmega328P) fixaram prioridades de interrupção, conforme detalhado na página 58ff da folha de dados . Portanto, se você usou o TIMER2 COMPA como sua interrupção crítica de tempo e nenhuma outra interrupção, deve estar OK (pois possui a maior prioridade). Se você também deseja usar interrupções de prioridade mais baixa, certifique-se de que todas elas reativem interrupções globais ao entrar na rotina de serviço de interrupção:
(p. 14 da folha de dados )
Isso é um pouco diferente nos Arduinos baseados em ARM, já que o núcleo do Cortex-M3 possui um "Nested Vector Interrupt Controller", onde as prioridades não são fixas (podem ser definidas no software) e o tratamento de interrupções aninhadas é a norma. Portanto, para cronometrar aplicativos críticos, o Arduino baseado em ARM ofereceria mais flexibilidade. No entanto, não acho que isso seja realmente necessário para a sua aplicação.
A grande questão é realmente quão fácil essas coisas podem ser implementadas com as bibliotecas do Arduino. Para obter o melhor desempenho, você provavelmente terá que codificar fora das bibliotecas até certo ponto, pelo menos para os bits críticos de tempo, ou seja, evitar coisas como delay () ou millis () por completo.
A necessidade de dividir ou não depende de quanto processamento você pretende fazer. Novamente, sair das bibliotecas pode potencialmente oferecer um melhor desempenho.
fonte
Isso pode, com a programação apropriada, ser feito definitivamente em um ATmega328P (dependendo da complexidade do loop de bateria. Estou assumindo ~ <50 eventos de bateria no loop. Isso é razoável?).
Note que eu disse ATmega328P , não necessariamente um Arduino .
O ambiente do Arduino tem muitas coisas padrão acontecendo em segundo plano, o que torna a programação extremamente determinística (como você precisará de algo crítico no tempo) desafiadora.
A verdadeira pergunta que você precisa fazer aqui é qual é o seu interesse em programação versus o interesse em desenvolver um instrumento?
Embora eu esteja bastante confiante de que é possível fazer tudo o que você deseja em um único ATmega (loop de bateria, várias entradas analógicas, LCD, botões, interface MIDI), a verdadeira questão é quanto trabalho será necessário para espremer tudo? Mais uma vez, você deseja aprender a otimizar o código MCU incorporado ou criar instrumentos? É muito fácil simplesmente acessar um MCU mais rápido, se necessário, mas você precisa determinar o desempenho do MCU necessário agora ; portanto, seis meses de trabalho, você não percebe que não consegue fazer tudo funcionar tão rápido quanto você. necessidade.
Se eu fosse você, a primeira coisa que faria seria fazê-lo funcionar sem o material do arduino (basicamente, trate-o como um ATmega bruto e use o AVR studio ou similar). Então, você pode analisar com muito mais eficiência que tipo de desempenho precisa e se o ATmega pode gerenciá-lo.
Quando você está livre do material do arduino, fica muito mais livre para usar MCUs diferentes (eles geralmente são mais parecidos do que diferentes. Se você pode descobrir um a partir da documentação, provavelmente pode fazer o mesmo com outros).
Eu tenho trabalhado muito com os dispositivos ATxmega MUITO recentemente, e eles são muito legais. Você tem três prioridades de interrupção, que facilitam o gerenciamento de itens críticos em termos de tempo. Eles também são muito bons de se trabalhar (designs periféricos da Sane! Estruturas de portas convenientes! Etc ...).
Existem também os dispositivos LPC do NXP, que são baseados em ARM, assim como alguns dos dispositivos ARM da Atmel (usados no Arduino Due), ou os MCUs STM32 da ST. Qualquer um desses terá desempenho significativamente mais do que um ATmega, ou mesmo um ATxmega.
A principal desvantagem de um processador maior e mais poderoso é o preço, mas, a menos que você esteja criando milhares dessas unidades, os custos de montagem e fabricação por unidade excederão muito a diferença de custo (que provavelmente será de apenas alguns dólares) ) que é basicamente irrelevante.
fonte
Eu precisava ler os cronômetros antes de começar a pensar na precisão do tempo (também construindo um sequenciador midi step com um arduino, embora seja garantido que pareça menos legal do que aqueles ^^). Esta série de artigos foi a mais informativa:
http://maxembedded.com/category/microcontrollers-2/atmel-avr/avr-timers-atmel-avr/
No momento, acho que minha solução para obter um timing preciso será.
A. Use o AVR arduino
B. Mantenha a tarefa em um microprocessador
C. Use sabiamente prescalers, temporizadores e interrupções para obter a precisão necessária.
ATUALIZAR
Usando o tutorial midi básico para o Arduino e depois de ler este artigo sobre temporizadores e pré-calibradores, o código a seguir foi o que eu vim. O código usa o modo timer1 e CTC para tocar uma nota midi a cada quarto de segundo e uma nota desativada a cada quarto de segundo (que deve ser exatamente 120 bpm). Infelizmente, isso ainda está chegando a menos de 120bpm, embora este seja o mais próximo que eu cheguei ...
ATUALIZAR
Estou lutando com isso há ~ 24 horas e finalmente recebi algumas respostas do fórum. Eu acho que o código que eu usei acima ^^ é muito bom. Usando o ISR, usando o modo CTC e pré-calibradores etc. Depois de entrar em contato com o fórum , acho que a solução tem menos a ver com precisão no midi sequencer, mas com toda a minha configuração de hardware (meus sintetizadores e samplers) conectada à mesma relógio midi, independentemente de o relógio ser ou não proveniente do Arduino.
fonte
Dependendo de quão gradualmente você deseja fazer a transição de um computador conectado a um sistema baseado em µC, considere colocar um Raspberry Pi dentro dessa caixa (US $ 25-35 no varejo ). Dessa forma, você pode ter um computador baseado em Linux completo (embora com pouca energia) com portas USB e pinos GPIO.
fonte