C ++ “no estaba declarado en este ámbito” error de compilación y consejos de modificación
-
21-09-2019 - |
Pregunta
Estoy intentando modificar este código en un intento de hacer que funcione en un Arduino Mega. Estoy bastante nuevo en C así, puedo haber cometido algunos errores importantes. Por cierto, esto es para un monopatín autobalanceo. : P
Este código se toma de una ATmega32 (a partir de: [url = http://sites.google.com/site/onewheeledselfbalancing/ Inicio / doble ruedas auto-equilibrio-skate-ligero versión / code4] http://sites.google.com/site/onewheeledsel...t-version/code4 [/ url] y yo' m tratando de hacer que funcione en un Arduino Mega.
Este código fue escrito por una junta Developpement ATmega32 http://www.active-robots.com/products/controllr/m32db. shtml
Gracias!
Este es el primer encuentro de error I:
En función de 'timer_init vacío ()': error: 'TCCR0' no fue declarado en este alcance En función 'int main ()':
Podría alguien explicar lo que está mal? Estoy más o menos un principiante en la programación pero he leído muchos libros / sitio web y estoy aprendiendo rápido también! ^^ y aquí está el código completo (es bastante larga):
#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; vacío set_motor_idle (void); vacío InitPorts (void); nivel de flotación = 0; flotador Throttle_pedal; flotar aa; flotador accelraw; flotar x_acc; flotar accsum; flotador x_accdeg;
flotador gyrosum;
gangleratedeg flotador; flotador gangleraterads; flotan Ti = 2,2;
flotar overallgain; flotar gaincontrol; batteryvolts flotador = 24; flotador gyroangledt; flotar ángulo; flotador anglerads; flotar balance_torque; flotador de arranque suave;
flotador cur_speed; flotar cycle_time = 0,0064; flotar Balance_point; flotador a0, a1, a2, a3, a4, a5, a6; // Savitzky-Golay variables para acelerómetro
int i; j int; TipStart int; vacío InitPorts (void) {PORTC = 0x00; //Puerto conjunto C dominadas a bajo (salida NO voltaje), para empezar DDRC = 0xFF; // El puerto C pernos Todos conjunto como salida a través el puerto C dirección registro // PORTC | = (1 <
DDRA = 0x00; // Todos los pines del puerto como un conjunto entrada PORTA = 0x00; // Un puerto de entrada dominadas SET para dominadas bajas
DDRD = 0xFF; // configurar todos los pines del puerto D como salida como requisito previo para OCR1A (PinD5) y OCR1B (Pin D4) que trabajan adecuadamente
PORTB = 0x00; // Puerto B dominadas conjunto de baja (sin tensión de salida), para empezar DDRB = 0xFF; // Todos los pines del puerto B determinan a salida
} / * IO: Estoy utilizando ATmega32 16MHz con el reloj de cristal externo. Nuevo disposición de las patillas planificada al motor OSMC controlador PC4 Onboard LED PD5 / OC1A ALI -> pin OSMC 6 PD4 / OC1B BLI -> OSMC pin 8 PC1 Desactivar -> pin 4 OSMC PC2 BHI -> pin OSMC 7 PC3 IAH -> pin OSMC 5 PA6 / ADC6 Vbat / 10 -> pin OSMC 3 PA1 / ADC1 giroscopio de tasa de cabeceo PA0 / ADC0 acelerómetro / void adc_init (void) {/ Apagar comparador analógico, ya que no usamos / ACSR = (1 << ACD); / seleccione PA0 / ADMUX = 0; ADMUX | = (1
/ = 0 ADCSRA | (1 < / esperar hasta primera conversión falsa acabada * / while (ADCSRA y (1 << ADSC)) {}}uint16_t adc_read (canal uint8_t) {
/ * Seleccione el canal / = ADMUX canal; ADMUX | = (1/ esperar hasta la conversión haya terminado / tiempo (ADCSRA Y (1 << ADSC)) {} / Vuelta al como resultado * / ADCW retorno; }
ADCSRA | = (1 << ADSC); // * 156 ciclos por segundo, 6.4ms per ciclo Medido en OSCILOSCOPIO * / / * leer todo las entradas ADC y hacer algo de conversión * / Sample_inputs (void) {
uint16_t adc0, adc1, adc2, adc3, adc4, adc5; gyrosum=0; adc0 = adc_read(0); /* accelerometer pin PA0 */ accelraw
= (float) adc0; para (j = 0; j <7; j ++) { ADC1 = adc_read (1); // gyro pin PA1 gyrosum = (float) gyrosum + ADC1; // usando una media de 7 muestras por lazo para el giro por lo que recibe una actualización completa con cada bucle de la programa }
adc2 = adc_read(2); /* grey wire overallgain (via cutout switch)
Posición PA2 * / adc3 = adc_read (3); / * Posición palanca tirada posición de la espalda PA3 * / adc4 = adc_read (4); / * posición PA4 Throttle_pedal * / adc5 = adc_read (5); / * Posición palanca empujada hacia delante posición PA5 * / // ADC6 = adc_read (6); / * Entrada Vbatt de OSMC (No se utiliza en la actualidad) posición PA6 * / filtro // Sav Golay para Accel solamente 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 cualquier picos de voltaje y da rango 0-3 = Throttle_pedal (float) Throttle_pedal * 0,9 + 0,1 * adc4 / 341; // alisa cualquier picos de voltaje y da gama 0-3
// Corta el motor si los muertos sirven botón se soltó // (gaincontrol variable también conectado a través de este botón para ADC2 si (ADC2 <100) { Throttle_pedal = 0,001; gaincontrol = 0,001; } overallgain = gaincontrol * de arranque suave; // qué hacer si la palanca hacia atrás o se empuja hacia delante o no hacer cualquier cosa: Balance_point = 514; si (adc3> 100) Balance_point = 534;
si (adc5> 100) Balance_point = 494;
PORTB |= (1<<PB2);//Port B2 turned on/off once per loop so I can
tiempo medida bucle con un osciloscopio
/ procesamiento de señal del acelerómetro / / Reste compensaciones / x_acc = (float) accsum - Balance_point; // accsum es el valor SG por el acelerómetro, no es un verdadero "suma", por lo no hay necesidad de dividir por 7 si (x_acc <-250) x_acc = -250; // valores tapa de aceleración a un rango de -250 a 250 (80 grados de inclinación en cada sentido) si (x_acc> 250) x_acc = 250; / * Cambio de ángulo acelerómetro es aproximadamente 3,45 unidades por inclinación grado en Rango de 0-30 grados (theta pecado) Convert incline a grados de inclinación de sensor acelerómetro. Sin ángulo aproximadamente = ángulo para ángulos pequeños de modo No es necesario hacer la trigonometría. x_acc a continuación se encuentra ahora en GRADOS * /
x_accdeg = (float) x_acc / -3,45; // Los corrige signo menos para una parte posterior al frente acelerómetro de montaje!
/*GYRO signal processing*/ /*Subtract offsets: Sensor reading is 0-1024 so "balance point"
es decir. mi punto cero requerido será que la lectura de menos de 512 * /
/ Gyro cambio de ángulo de 20 mV por deg por seg de hoja de datos da cambio de 4.096 unidades (en la escala de 0 - 1023) por grado por cambio de ángulo sec Este limita la velocidad de cambio de gyro ángulo de poco menos que el máximo califica en realidad es capaz de medir (100deg / seg). Tenga en cuenta todos estos las fracciones se redondean a un número entero más tarde, justo antes de que se envíe a la generador de PWM que a su vez es conectado al motor controlador / gangleratedeg = (float) ((gyrosum / 7) - 508) /4.096; // gyrosum es una suma de un grupo de 7 muestras por lo que se divide por 7 para valor giroscopio si (gangleratedeg <-92) gangleratedeg = -92; si (gangleratedeg
92) gangleratedeg = 92 / Me gire puerto B2 dentro y fuera de una vez por programa principal ciclo para que pueda conectar un osciloscopio a ella y trabajar a cabo el ciclo del programa vez que utilizo el tiempo de ciclo para trabajar cambio de ángulo giroscopio por ciclo en el que tiene que saber la longitud de este tiempo intervalo de / = PORTB y (0 <
/ ti representa la ampliación de la "i" o factor integral (actualmente 2,2 aquí) gyroangledt es anglechange desde el último ciclo en grados a partir del giróscopo Sensor, donde ti es factor de escala (En teoría debería ser de aproximadamente 1, pero 2,2hace bordo se sienta más firme)
ganglerate está ahora en unidades de grados por segundo aa varía el tiempo constantes, es decir las marcas de valor más pequeño aa acelerómetro constante de tiempo más largo como se corrige lentamente durante el giroscopio la deriva /aa = 0,005; gyroangledt = (float) ti cycle_time gangleratedeg;
gangleraterads = (float) gangleratedeg * 0,017453;/ nuevo ángulo en grados es el ángulo de edad además de cambio en el ángulo de gyro desde último ciclo con poco de nuevo leer factorizada en / = aceleración angular (Float) ((1-aa) * (ángulo de + gyroangledt)) + (Aa x_accdeg *); // calcular el ángulo principal función * / // Convertir ángulo de grados a radianes
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;
/ * El valor del nivel es -1-1 y representa el ciclo de trabajo para ser enviado al motor. La conversión a radianes nos ayuda a estar dentro de estos límites nivel = (balance_torque + cur_speed) * overallgain;
}
timer_init void () {TCCR0 = 0 | (1 <
modo// PWM es "PWM, la fase correcta, 10-bit" TCCR1A = 0 | (1 <
(1 <
vacío set_motor ()
/ * Los términos leveli es el término nivel reescalado -1,023-1023 como una número entero listo para enviar al motor PWM puertos de control que son a su vez conectado a la OSMC * / {
// si el (nivel <-0.9) = nivel -0.9; // cheques estamos dentro de límites razonables // si (nivel de> 0,9) Nivel = 0,9;
int16_t leveli = (Int16_t) (nivel * 1023); // NOTA aquí tomar el valor de coma flotante que tenemos terminó por "nivel", multiplicamos por 1023 y luego convertirlo en una número entero antes de alimentar el valor en el generador de PWM como "leveli"
si (leveli <-1020) leveli = -1020; // dobles comprobaciones somos dentro de límites razonables PWM como no hacer querer ser arrojado de repente fuera de la tablero si (leveli> 1020) leveli = 1,020;
/ Configuración de LED o zumbador en el puerto B1 a avisarme para reducir la velocidad si el par sea entregado es más de 50% del valor máximo La posible razón de esto es que siempre hay algún motor de reservas energía en caso de vuelco de empezar remitir a la velocidad del motor Si ya casa por la ventana en ejecución, estaría a punto de caer en la velocidad! Algunos utilizan una rutina de vuelta automática a la punta de forma automática limitar la velocidad máxima. Por ahora lo haré De esta manera tan fácil /
Si (nivel <-0.7 || nivel de> 0,7) {
PORTB | = (1 < PORTB & = (0 <arranque suave = (float) de arranque suave + 0,001; si (arranque suave> 1,0) de arranque suave = 1,0;
//PORTC |= (0<<PC1); // AHI=1 PinC3, BHI=1 PinC2 set both to ON for
OSMC de trabajo y tanto en OFF para cierre abajo del motor / * NOTA: No sé por qué, pero a parada de corte hacia fuera en la dirección del motor cambios que tenía en el extremo de alambre duro IAH y BHI a + 12V / / Un-discapacitados OSMC mediante el establecimiento de salida PinC1 a cero, un 1 hará imposible la OSMC * / PORTC | = 0x0C; // crea C1 tira hacia abajo de modo un-desactiva la OSMC es decir, permite a ella. PORTC & = ~ 0x02; // desactivar si está apagado (Leveli <0) { OCR1A = -leveli; // ALI es PWM hacia atrás va tan variables leveli es un valor negativo firmado, mantenga el menos firme aquí! OCR1B = 0; // BLI = 0} else {OCR1A = 0; // ALI = 0 ir hacia delante como leveli variable es un valor positivo firmado OCR1B = leveli; // BLI es PWM}}
int main (void) { InitPorts ();
adc_init ();
timer_init ();
/ * código inicial inclinación inicio Encienda micro mientras tablero apunta hacia un lado, piloto a punto de paso en ella, si la inclinación ángulo cruza (MID) saldo de puntos cero algoritmo en funcionamiento bloqueado de otro modo en este bucle infinito hasta que se inclina a la posición de nivel como piloto se sube a bordo * / TipStart = 0; accelraw = 0;
mientras (TipStart <1) {
// Esto es necesario para permitir que la SG filtrar, para cerrar a la estabilidad adecuada valor cuando se encienda por primera vez en la máquina, antes de mirar el valor de accsum (Abajo).
for (i = 0; i <20; i ++) {
sample_inputs ();
}Si (accsum <504 || accsum> 524) {//
si (x_accdeg> 0) {TipStart = 0; } else {TipStart = 1;
arranque suave = 0,4; }}ángulo = 0; cur_speed = 0; / * Final de la inclinación código de inicio. Si ir más allá de este punto máquina tiene entonces nivel convertido y es activo * /
sei ();
while (1) {sample_inputs ();
set_motor ();
}}
Solución
Lo más probable es que tenga el mal MCU especificado para su construcción. Mientras DDRA existe en los ATmega1280 en un Arduino Mega, DDRA no existe en el ATmega328 de un Arduino regular.
Si está utilizando el Arduino interfaz de usuario, vaya a Herramientas | Junta y elegir Arduino Mega.
Si está utilizando su propio sistema de construcción, tendrá que actualizar el valor que especifique para -mmcu = en la línea de comando gcc.
Otros consejos
Creo que puede haber dejado un comentario de cierre aquí:
/*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 >>>*/<<<
Cuando el compilador le dice que algo "no fue declarada en este ámbito," como a ti mismo esta pregunta:
¿Qué alcance era se declara en?
Si no puede responder a esta pregunta, entonces has descubierto el problema. Después de todo, si no saben lo que se refiere al nombre, cómo se puede esperar que el compilador? Recuerde que es el experto en cualquier código de escritura.
Si puede a determinar lo que alcance la cosa se declara en, a continuación, la siguiente tarea es determinar la forma en que se refiere al alcance del ámbito que estamos tratando de usarlo en. Los problemas típicos incluyen (pero no se limitan a) lo siguiente:
- Se declaró en otro espacio de nombres. Utilice el operador
::
alcance resolución para dar un nombre completo. - Se declara como un miembro de una clase y que está tratando de utilizarlo en una función independiente. O bien encontrar una instancia de la clase y acceso a la variable o función a través de ese objeto, o cambiar la clase a tener su nueva función como uno de sus miembros.
Si no pueden encontrar lo alcance se declaró en, entonces hay algunas cosas que podrían ser mal:
- Usted ha deletreado mal. Comprobar la ortografía en la documentación y fijar su código.
- Se declaró en alguna cabecera que se le ha olvidado incluir. Averiguar dónde se declara y se añada la directiva
#include
apropiado. Este es probablemente el problema en su caso. - No es declarada en cualquier lugar. Averiguar donde debe se declarará y declarar que allí mismo.
Aquí hay un enlace al código de Arduino razonablemente sencillo para el control de un DIY Segway.
Esto sería un punto de partida mejor para su monopatín creo.
http://diysegway.blogspot.com/
Los mejores deseos
John