C++ "não foi declarado neste âmbito" erro de compilação e modificação dicas
-
21-09-2019 - |
Pergunta
Eu estou tentando modificar esse código em uma tentativa de fazê-lo funcionar em um Arduino Mega.Sou muito nova para C assim, eu posso ter feito alguns erros graves.A propósito, esta é para uma auto balanceamento de skate.:P
Este código é obtido a partir de um ATmega32 (a partir de :[url=http://sites.google.com/site/onewheeledselfbalancing/Home/twin-wheel-self-balancing-skateboard-lightweight-version/code4]http://sites.google.com/site/onewheeledsel...t-version/code4[/url] e eu estou tentando fazê-lo funcionar em um Arduino Mega.
Este código foi escrito para um ATmega32 developpement conselho http://www.active-robots.com/products/controllr/m32db.shtml
Obrigado!
Aqui está o primeiro erro que encontrar :
Em função de 'void timer_init()':erro:'TCCR0' não foi declarado na este escopo Em que a função 'int main()':
Alguém poderia me explicar o que está errado?Eu sou praticamente um iniciante em programação, mas eu li um monte de livros/site e estou aprendendo rápido demais!^^ e aqui está o código completo (sua muito longa):
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <math.h>
definir CLOCK_SPEED 16000000
definir OCR1_MAX 1023
typedef unsigned char u8;vazio set_motor_idle(void);vazio InitPorts(void);de nível de flutuador=0;float Throttle_pedal;float aa;float accelraw;float x_acc;float accsum;float x_accdeg;
float gyrosum;
float gangleratedeg;float gangleraterads;float ti = 2.2;
float overallgain;float gaincontrol;float batteryvolts = 24;float gyroangledt;float ângulo;float anglerads;float balance_torque;float softstart;
float cur_speed;float cycle_time = 0.0064;float Balance_point;float a0, a1, a2, a3, a4, a5, a6;//Savitzky-Golay variáveis para acelerômetro
int i;int j;int tipstart;vazio InitPorts(void) { PORTC=0x00;//Porta C pullups definido para baixa (sem saída de tensão) para começar DDRC=0xFF;//Porta C pinos de todo definida como a saída por meio de a porta C direção registrar //PORTC |= (1<
DDRA=0x00;//todas as portas de Um conjunto de pinos como entrada de PORTA=0x00;//Porta de entrada pullups baixa pullups
DDRD=0xFF;//Configurar a porta de todos os pinos D como saída, como pré-requisito para OCR1A (PinD5) e OCR1B Pin (D4) de trabalho corretamente
PORTB=0x00;//Porta B pullups definido para baixa (sem tensão de saída) para começar DDRB=0xFF;//Todos os pinos da porta B para definir saída
} /* E / s:Eu estou usando ATMega32 16MHz externo com relógio de cristal.Novo planejado pinos para OSMC motor controlador PC4 a Bordo LED PD5/OC1A ALI -> OSMC pino 6 PD4/OC1B BLI -> OSMC pino 8 PC1 Disable -> OSMC pino 4 PC2 BHI -> OSMC pino 7 PC3 AHI -> OSMC pino 5 PA6/ADC6 Vbatt/10 -> OSMC pino 3 PA1/ADC1 campo giroscópio PA0/ADC0 acelerômetro / void adc_init(void) { / desligue analógico comparador de como nós não usá-lo / ACSR = (1 << ACD);/ selecione PA0 / ADMUX = 0;ADMUX |=(1< Conjunto de ADC prescaler 128, habilitar a ADC, e iniciar a conversão / ADCSRA = 0 | (1< / aguarde até que o falso primeira conversão terminar */ while (ADCSRA & (1 << ADSC)) { } }
uint16_t adc_read(uint8_t canal) {
/* selecione o canal / ADMUX = canal;ADMUX |=(1< iniciar a conversão /
ADCSRA |= (1 << ADSC);/ aguarde até que a conversão terminar / enquanto (ADCSRA & (1 << ADSC)) { } / o retorno resultado */ return ADCW;}/* 156 ciclos por segundo, 6.4 ms por ciclo MEDIDO NO OSCILOSCÓPIO*/ /* ler todos o ADC entradas e fazer a conversão de algumas */ void sample_inputs(void) {
uint16_t adc0, adc1, adc2, adc3, adc4, adc5; gyrosum=0; adc0 = adc_read(0); /* accelerometer pin PA0 */ accelraw
= (float) adc0;for (j=0;j<7;j++) { adc1 = adc_read(1);//gyro pin PA1 gyrosum = (float) gyrosum + adc1;//com uma média de 7 amostras por loop para o gyro por isso fica um atualização completa com cada ciclo do programa }
adc2 = adc_read(2); /* grey wire overallgain (via cutout switch)
posição PA2*/ adc3 = adc_read(3);/* Posição da alavanca puxada para trás posição PA3*/ adc4 = adc_read(4);/* Throttle_pedal posição AP4*/ adc5 = adc_read(5);/* Posição da alavanca empurrado encaminha posição AP5*/ //adc6 = adc_read(6);/* Vbatt entrada da OSMC (não utilizado atualmente) posição PA6*/ //Sav Golay filtro para accel apenas a0 = a1;a1 = a2;a2 = a3;a3 = a4;a4 = a5;a5 = a6;a6 = (float) accelraw;accsum = (float) ((-2*a0) + (3*a1) + (6*a2) + (7*a3) + (6*a4) + (3*a5) + (-2*a6))/21;//Sav Golay cálculo
gaincontrol = (float) gaincontrol*0.9 + 0.1*adc2/341;
//suaviza qualquer picos de tensão e dá faixa de 0-3 Throttle_pedal=(float) Throttle_pedal*0.9 + 0.1*adc4/341;//suaviza qualquer picos de tensão e dá faixa de 0-3
//Corta o motor se o dead mans o botão é deixar de ir //(gaincontrol variável também com fio por meio do botão para adc2 se (adc2<100) { Throttle_pedal=0.001;gaincontrol=0.001;} overallgain = gaincontrol*softstart;//o que fazer se a alavanca puxada de volta ou avança ou não fazer qualquer coisa:Balance_point = 514;se (adc3>100) Balance_point=534;
se (adc5>100) Balance_point=494;
PORTB |= (1<<PB2);//Port B2 turned on/off once per loop so I can
medir o tempo de loop com um osciloscópio
/ACELERÔMETRO de processamento de sinal/ /Subtrair deslocamentos/ x_acc=(float) accsum - Balance_point;//accsum é SG valor para acelerômetro, não é um verdadeiro "soma" de modo não há necessidade de dividir por 7 se (x_acc<-250) x_acc=-250;//tampa de aceleração valores para um intervalo de -250 a +250 (80 graus de inclinação em cada sentido) se (x_acc>250) x_acc=250;/* Acelerômetro para mudar o ângulo é de cerca de 3.45 unidades por grau de inclinação em intervalo de 0 a 30 graus(pecado theta) Converter de inclinação em graus de inclinação de sensor do acelerómetro.O pecado ângulo cerca de = ângulo para ângulos pequenos, de modo não há necessidade de fazer trigonometria.x_acc abaixo está agora em GRAUS*/
x_accdeg= (float) x_acc/-3.45;//O sinal de menos corrige para uma volta a frente de montagem do acelerômetro!
/*GYRO signal processing*/ /*Subtract offsets: Sensor reading is 0-1024 so "balance point"
i.e.meu ponto zero será que a leitura menos 512*/
/Giroscópio de mudar o ângulo de 20mV por graus por seg a partir de folha de dados dá-alteração de 4.096 (unidades na escala de 0 a 1023) por grau por segundo, ângulo de alterar Este limita a taxa de variação do giroscópio ângulo um pouco menos que o máximo a taxa é realmente capaz de de medição (100deg/seg).Nota: todos estes as frações são arredondadas para um inteiro mais tarde, pouco antes de ela ser enviada para o Gerador de PWM, que por sua vez é ligado ao controlador do motor/ gangleratedeg=(float)((gyrosum/7) - 508)/4.096;//gyrosum é uma soma de um grupo de 7 amostras, assim, dividir por 7 para giroscópio de valor se (gangleratedeg <-92) gangleratedeg=-92;se (gangleratedeg
92) gangleratedeg=92 /Eu viro a porta B2 e fora de uma vez por programa principal ciclo para que eu possa anexar um osciloscópio para ele, trabalhar o ciclo de programa tempo eu uso o ciclo de tempo para trabalhar fora giroscópio de mudar o ângulo por ciclo, onde você precisa saber o tamanho de este tempo intervalo de/ PORTB &= (0<
/ti representa o dimensionamento para o "eu" ou integral fator (atualmente 2.2 aqui) gyroangledt é anglechange desde o último CICLO, em graus, a partir giroscópio sensor, onde ti é fator de escala (deve, em teoria, ser de cerca de 1, mas 2.2 torna conselho sentir mais apertado)
ganglerate está agora em unidades de graus por segundo aa varia o tempo constante, eu.e de menor valor, faz com que aa acelerômetro constante de tempo mais longo como lentamente ele corrige para o giroscópio drift/aa=0.005;gyroangledt = (float)ticycle_timegangleratedeg;
gangleraterads=(float)gangleratedeg*0.017453;/novo ângulo, em GRAUS, é velho ângulo além de alteração no ângulo de giro desde último ciclo com pouco de novo aceleração de leitura levadas em conta/ angle = (float)((1-aa) * (ângulo de+gyroangledt)) + (aa * x_accdeg);//o principal ângulo de cálculo da função*/ //Converter ângulo de graus para radianos
anglerads=(float)angle*0.017453; balance_torque=(float)(4.5*anglerads)
+ (0.5*gangleraterads);
cur_speed = (float)(cur_speed + (Throttle_pedal * balance_torque * cycle_time)) * 0.999;
/*O valor é de -1 a +1 e representa o ciclo de trabalho a ser enviado para o motor.Converter para radianos ajuda-nos a permanecer dentro destes limites nível = (balance_torque + cur_speed) * overallgain;
}
void timer_init() { TCCR0 = 0 | (1<
// Modo PWM é "PWM, a Fase Correta, 10-bit" TCCR1A = 0 | (1<
(1<
void set_motor()
/* O leveli termos é o nível prazo redimensionado a partir de 1023 para +1023 como um inteiro pronto para enviar para o PWM motor portas de controle que por sua vez são ligado a OSMC*/ {
//se (nível<-0.9)=nível -0.9;//verifica se estamos dentro dos limites sensíveis //if (nível>0.9) nível=0.9;
int16_t leveli = (int16_t)(nível*1023);//NOTA aqui nós tomar o valor de ponto flutuante temos acabou com o "nível de", devemos multiplicar por 1023 e, em seguida, torná-lo em uma inteiro antes de alimentar o valor em o gerador de PWM como "leveli"
se (leveli<-1020) leveli=-1020;//verifica somos dentro sensível PWM de limites, como não quero, de repente, ser jogado para fora do conselho se (leveli>1020) leveli=1020;
/Conjunto de LED ou campainha na Porta B1 a avisar-me para abrandar se o torque a ser entregue mais do que 50% de max. possível razão para isso é que você sempre precisa de alguma reserva motora de energia no caso de você começar a gorjeta para a frente em velocidade Se o motor já a execução de televisão-você estaria prestes a cair em alta velocidade!Alguns usam um auto-sugestão de volta a rotina automaticamente limite de velocidade máxima.Por agora vou fazê-lo desta forma, como mais fácil/
se (nível<-0.7 | nível | >0.7) {
PORTB |= (1< PORTB &= (0<softstart = (float) softstart+0.001;se (softstart>1.0) softstart=1.0;
//PORTC |= (0<<PC1); // AHI=1 PinC3, BHI=1 PinC2 set both to ON for
OSMC para o trabalho e tanto OFF (desligado) para desligar motor para baixo /*NOTA:Não sei por que, mas parada do motor de corte para fora em direção as alterações que eu tinha no final de fio duro AHI e BHI para +12V / / Onu-desactivado OSMC por definição PinC1 saída para zero, 1 desative a OSMC*/ PORTC |= 0x0c;//faça C1 puxado para baixo para onu-desativa a OSMC i.e.permite-lo.PORTC &= ~0x02;//desactivar está fora de se (leveli<0) { OCR1A = -leveli;// ALI está PWM indo para trás, como leveli variável é negativo assinado valor, a manter o sinal de subtração aqui!OCR1B = 0;// BLI = 0 } else { OCR1A = 0;// ALI = 0 vai para a frente como leveli a variável é um sinal positivo de valor OCR1B = leveli;// BLI é PWM } }
int main(void) { InitPorts();
adc_init();
timer_init();
/* Inicial tilt-código de início de Ligar micro enquanto conselho pender para um lado, piloto sobre a etapa em que, se a inclinação ângulo de cruzamentos de zero (meio) ponto de equilíbrio algoritmo torna-se operacional caso contrário, preso neste ciclo para sempre até que ele é cotado para a posição de nível como o piloto fica no tabuleiro*/ tipstart=0;accelraw = 0;
enquanto (tipstart<1){
// você precisa esta opção para permitir que o SG filtro de vento até a adequada estável valor quando pela primeira vez máquina, antes de olhar para o valor da accsum (abaixo).
for (i=0;eu<20;i++) {
sample_inputs();
}se (accsum<504 || accsum>524) { //
se (x_accdeg>0) { tipstart=0;} else { tipstart=1;
softstart=0.4;} }ângulo=0;cur_speed=0;/* fim do tilt código de início.Se ir além deste ponto em seguida, a máquina tornou-se nível e é ativo*/
sei();
while (1) { sample_inputs();
set_motor();
} }
Solução
Provavelmente você tem errado MCU especificado para a sua construção.Enquanto DDRA existe no ATmega1280 em um Arduino Mega, DDRA não existe no ATmega328 regular Arduino.
Se você estiver usando o Arduino INTERFACE de usuário, vá para Ferramentas | Conselho de administração e escolha o Arduino Mega.
Se você estiver usando o seu próprio sistema de compilação, você precisará atualizar o valor que você especificar para -mmcu= no gcc linha de comando.
Outras dicas
Eu acho que você pode ter deixado um fechamento comentário aqui:
/*The level value is from -1 to +1 and represents the duty cycle to be sent to the motor. Converting to radians helps us stay within these limits >>>*/<<<
Quando o compilador diz que algo "não foi declarado neste âmbito," como a si mesmo esta pergunta:
O âmbito foi é declarada?
Se você não pode responder a essa pergunta, então você já descobriu o problema.Afinal, se você não sabe o que esse nome se refere, como você pode esperar que o compilador?Lembre-se de que você é o especialista em qualquer código você escrever.
Se você pode determinar o escopo da coisa que for declarado e, em seguida, a próxima tarefa é determinar como esse escopo se refere ao âmbito de aplicação que você está tentando usá-lo.Problemas típicos incluem (mas não estão limitados a) o seguinte:
- Ele foi declarado em algum outro espaço de nomes.Use o
::
escopo do operador de resolução de dar um nome totalmente qualificado. - Ele foi declarado como um membro de uma classe e que você está tentando usá-lo em uma função autônomo.Quer encontrar uma instância da classe e acessar a variável ou função de objeto, ou alterar a classe para ter sua nova função como um de seus membros.
Se você não pode encontrar escopo que foi declarado, em seguida, há algumas coisas que podem estar erradas:
- Você escreveu errado.Verificar a ortografia na documentação e corrigir o seu código.
- Ele é declarado no cabeçalho que você esqueceu de incluir.Descobrir onde é declarado e adicione o adequado
#include
directiva. Este é, provavelmente, o problema no seu caso. - Não declaradas em qualquer lugar.Descobrir onde é que deve ser declarado e declará-lo lá mesmo.
Aqui está um link para razoavelmente simples código do Arduino para controle de um DIY Segway.
Este seria um ponto de partida melhor para o seu skate, eu acho.
http://diysegway.blogspot.com/
Melhores cumprimentos,
João