C ++ « n'a pas été déclaré dans ce champ » erreur de compilation et des conseils de modification
-
21-09-2019 - |
Question
Je suis en train de modifier ce code pour tenter de le faire fonctionner sur un Arduino Mega. Je suis à peu près à nouveau C, je peux avoir fait quelques erreurs majeures. Soit dit en passant, ceci est pour une planche à roulettes d'équilibrage automatique. : P
Ce code est tiré d'un ATmega32 (à partir de: [url = http://sites.google.com/site/onewheeledselfbalancing/ Accueil / double roue auto-équilibrage-planche à roulettes léger version / code4] http://sites.google.com/site/onewheeledsel...t-version/code4 [/ url] et je m essayer de le faire fonctionner sur un Arduino Mega.
Ce code a été writen pour une carte de ATmega32 DEVELOPPEMENT http://www.active-robots.com/products/controllr/m32db. shtml
Merci!
Voici la première erreur que je rencontre:
En fonction 'timer_init void ()': Erreur: « TCCR0 » n'a pas été déclarée dans Dans ce cadre fonction "int main ():
Quelqu'un pourrait-il me expliquer ce qui est faux? Je suis à peu près un débutant dans la programmation mais j'ai lu beaucoup de livres / site et j'apprends vite aussi! ^^ et est ici le code complet (son assez long):
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <math.h>
définir CLOCK_SPEED 16000000
définir OCR1_MAX 1023
typedef unsigned char u8; vide set_motor_idle (void); vide InitPorts (void); niveau = 0 flotteur; flotte Throttle_pedal; flotter aa; flotte accelraw; flotter x_acc; flotter accsum; flotter x_accdeg;
gyrosum float;
gangleratedeg flotteur; flotte gangleraterads; flotteur ti = 2.2;
flotter overallgain; flotter gaincontrol; flotter batteryvolts = 24; flotte gyroangledt; angle flotter; flotte anglerads; flotter balance_torque; flotte softstart;
cur_speed flotteur; flotter CYCLE_TIME = 0,0064; flotter Balance_point; flotter a0, a1, a2, a3, a4, a5, a6; // les variables Savitzky-Golay pour accéléromètre
int i; int j; int TipStart; vide InitPorts (void) {PORTC = 0x00; //Port C pullups fixés à faible (pas de sortie tension) pour commencer DDRC = 0xFF; // broches Port C toutes définies comme sortie via la direction du port C // registre PORTC | = (1 <
DDRA = 0x00; // toutes les broches A du port défini comme entrée PORTA = 0x00; // Une entrée du port pullups fixés à de faibles tractions
DDRD = 0xFF; // Configurer toutes les broches Port D en sortie en tant que condition préalable à la OCR1A (PinD5) et OCR1B (Pin D4) travaillant correctement
PORTB = 0x00; // Port B tractions mis à faible (pas de tension de sortie) pour commencer DDRB = 0xFF; // Toutes les broches Port B réglé sur sortie
} / * IO: J'utilise 16MHz Atmega32 avec horloge à quartz externe. Nouveau Dispositif de broche prévu à moteur OSMC PC4 contrôleur embarqué LED PD5 / OC1A ALI -> pin OSMC 6 PD4 / OC1B BLI -> OSMC broche 8 PC1 Disable -> 4 broches OSMC PC2 BHI -> pin OSMC 7 PC3 AHI -> pin OSMC 5 PA6 / ADC6 Vbatt / 10 -> OSMC broche 3 gyro PA1 / de vitesse de tangage de ADC1 accéléromètre PA0 / ADC0 de / vide adc_init (void) {/ désactiver comparateur analogique que nous ne l'utilisons pas / ACSR = (1 << ACD); / sélectionnez PA0 / ADMUX = 0; ADMUX | = (1
/ ADCSRA = 0 | (1 < / attendez que la conversion première bogus fini * / while (ADCSRA & (1 << ADSC)) {}}uint16_t adc_read (canal uint8_t) {
/ * Sélectionnez le canal / = ADMUX canal; ADMUX | = (1/ attendre la conversion terminée / while (ADCSRA & (1 << ADSC)) {} / retourner la résultat * / retour ADCW; }
ADCSRA | = (1 << ADSC); // * 156 cycles par seconde, 6.4ms pcycle er MESURÉ OSCILLOSCOPE * / / * lire tous les entrées ADC et faire une conversion * / 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); // pin gyro PA1 gyrosum = (float) gyrosum + ADC1; // en utilisant une moyenne de 7 échantillons par boucle du gyroscope il obtient un mise à jour avec chaque boucle de la programme }
adc2 = adc_read(2); /* grey wire overallgain (via cutout switch)
Position PA2 * / ADC3 = adc_read (3); / * Levier de position tiré vers l'arrière la position PA3 * / adc4 = adc_read (4); / * Position Throttle_pedal PA4 * / ADC5 = adc_read (5); / * Levier de position enfoncée Position avant PA5 * / // ADC6 = adc_read (6); / * Vbatt entrée de OSMC (Non utilisé à l'heure actuelle) Position PA6 * / // Sav Golay filtre pour accel seulement a0 = a1; a1 = a2; a2 = a3; a3 = a4; a4 = a5; a5 a6 =; a6 = (Float) accelraw; accsum = (float) ((A0 * -2) + (3 * a1) + (6 * a2) + (7 * a3) + (6 * a4) + (3 * a5) + (-2 * a6)) / 21; // Sav calcul Golay
gaincontrol = (float) gaincontrol*0.9 + 0.1*adc2/341;
// des pointes de adoucit la tension et donne gamme 0-3 Throttle_pedal = (float) Throttle_pedal * 0,9 + 0,1 * adc4 / 341; // aplanit les pointes de tension et donne gamme 0-3
// coupe le moteur si les mans morts bouton se laisse aller // (gaincontrol également variable câblé à travers cette bouton pour CAN2 si (CAN2 <100) { Throttle_pedal = 0,001; gaincontrol = 0,001; } overallgain = gaincontrol * softstart; // ce qu'il faut faire si le levier tiré vers l'arrière ou vers l'avant ou non poussé à faire quoi que ce soit: Balance_point = 514; if (ADC3> 100) Balance_point = 534;
if (ADC5> 100) Balance_point = 494;
PORTB |= (1<<PB2);//Port B2 turned on/off once per loop so I can
temps de la boucle de mesure avec un oscilloscope
/ traitement du signal Accéléromètre / / Soustraire décalages / x_acc = (float) accsum - Balance_point; // accsum est la valeur SG pour accéléromètre, pas une véritable « somme » de sorte pas besoin de diviser par 7 if (x_acc <-250) x_acc = -250; // cap valeurs Accel à une gamme de -250 à 250 (80 degré d'inclinaison dans chaque sens) if (x_acc> 250) x_acc = 250; / * Changement d'angle de l'accéléromètre est d'environ 3,45 unités par inclinaison du degré de gamme de 0-30 degrés (sin theta) Autre incliner à degrés d'inclinaison à partir de capteur accéléromètre. angle de Sin = angle plus ou moins pour les petits angles de sorte que pas besoin de faire la trigonométrie. x_acc ci-dessous est maintenant en DEGRÉS * /
x_accdeg = (float) x_acc / -3,45; // Le signe moins corrige un dos pour le montage de l'accéléromètre avant!
/*GYRO signal processing*/ /*Subtract offsets: Sensor reading is 0-1024 so "balance point"
i.e.. mon point zéro nécessaire sera que la lecture moins 512 * /
/ angle Gyro changement de 20mV par degrés par seconde à partir de la fiche technique donne changement 4.096 unités (sur l'échelle de 0 à 1023) par degré par seconde angle modifier ce limite le taux de variation du gyroscope angle juste inférieur au maximum Estimez-est réellement capable de mesure (100deg / sec). Notez tous ces Les fractions sont arrondies à un nombre entier plus tard, juste avant qu'il ne soit envoyé au générateur PWM qui à son tour est connecté au contrôleur de moteur / gangleratedeg = (float) ((gyrosum / 7) - 508) /4.096; // gyrosum est une somme d'un groupe de 7 échantillons afin de diviser par 7 pour La valeur du gyroscope if (gangleratedeg <-92) gangleratedeg = -92; if (gangleratedeg
92) gangleratedeg = 92 / Je passe le port B2 et hors une fois par programme principal le cycle que je puisse joindre un oscilloscope à travailler et le cycle du programme J'utilise le temps le temps de cycle pour travailler changement d'angle gyro par cycle où vous doivent connaître la longueur de ce temps intervalle / PORTB & = (0 <
/ ti représente pour la mise à l'échelle "i" ou facteur intégral (actuellement 2,2 ici) gyroangledt est anglechange depuis le dernier cycle de degrés gyro capteur, où Ti est le facteur d'échelle (Devrait en théorie être d'environ 1 mais 2.2fait sentir conseil serré)
ganglerate est maintenant en degrés par seconde aa fait varier le temps constante, i.e. plus petite valeur aa marques constante de temps de l'accéléromètre plus que il corrige lentement du gyroscope la dérive /aa = 0,005; gyroangledt = (float) ti CYCLE_TIME gangleratedeg;
gangleraterads = (float) * gangleratedeg 0,017453;/ nouvel angle dans DEGRÉS est ancien angle plus le changement d'angle du gyroscope depuis dernier cycle avec peu de nouvelles Accel lecture pris en compte / angle = (Float) ((1-aa) * (angle + gyroangledt)) + (Aa * x_accdeg); // l'angle principal fonction de calcul * / // Convertir angle de degrés en radians
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;
/ * La valeur de niveau est de -1 à +1 et représente le cycle de service doit être envoyé au moteur. Conversion en radians nous aide à rester dans ces limites niveau = (balance_torque + cur_speed) * overallgain;
}
timer_init void () {TCCR0 = 0 | (1 <
// mode PWM est « PWM, phase correcte, 10 bits » TCCR1A = 0 | (1 <
(1 <
set_motor void ()
/ * Les termes de leveli est le terme de niveau rééchelonné -1023 à 1023 en tant que entier prêt à envoyer au moteur PWM orifices de commande qui sont à leur tour connecté au OSMC * / {
// if (niveau <-0,9) Niveau = -0.9; // vérifie que nous sommes dans des limites raisonnables // si le niveau = 0,9 (niveau> 0,9);
int16_t leveli = (Int16_t) (niveau * 1023); // NOTE ici nous prendre la valeur en virgule flottante, nous avons fini avec pour « niveau », nous multiplions par 1023, puis en faire une entier avant d'alimenter la valeur en le générateur PWM comme "leveli"
if (leveli <-1020) leveli = -1020; // revérifie nous sommes dans les limites PWM sensibles que ne pas veulent être soudainement jeté le bord si (leveli> 1020) leveli = 1020;
/ Mettre en place LED ou buzzer sur le port B1 à me prévenir de ralentir si le couple d'être livré est plus de 50% maximum La raison possible est que vous devez toujours un moteur de réserve puissance au cas où vous commencez à basculer avant à la vitesse Si le moteur déjà flat-out en cours d'exécution, vous seriez sur le point tomber à grande vitesse! Certains d'utilisation auto-pointe arrière de routine pour automatiquement limiter la vitesse de pointe. Pour l'instant je vais le faire cette façon plus facile /
if (niveau <-0,7 || niveau> 0,7) {
PORTB | = (1 < PORTB & = (0 <softstart = (float) softstart + 0,001; if (softstart> 1,0) softstart = 1,0;
//PORTC |= (0<<PC1); // AHI=1 PinC3, BHI=1 PinC2 set both to ON for
OSMC à travailler et à la fois sur OFF à fermer moteur vers le bas / * NOTE: Je ne sais pas pourquoi mais arrêter le moteur de coupe sur la direction les changements que j'avais à la fin de fil dur AHI et BHI à + 12V / / Un handicapé OSMC par réglage de la sortie PinC1 à zéro, un 1 pourrait désactiver le OSMC * / PORTC | = 0x0c; // faire C1 tiré vers le bas de façon un-à-dire désactive le OSMC permet. PORTC & = ~ 0x02; // désactiver est désactivé si (Leveli <0) { OCR1A = -leveli; // ALI est PWM va en arrière aussi variable est leveli une valeur négative signée, garder la moins se connecter ici! OCR1B = 0; // BLI = 0} else {OCR1A = 0; // ALI = 0 aller vers l'avant comme leveli variable est une valeur positive signée OCR1B = leveli; // BLI est PWM}}
main (void) {int InitPorts ();
adc_init ();
timer_init ();
/ * Code d'inclinaison initial Activer le début tandis micro bord incliné vers un côté, cavalier sur le point de monter sur lui, si l'inclinaison angle traverse balance ponctuelle (mi) zéro algorithme devient opérationnel sinon pour toujours enfermé dans cette boucle jusqu'à ce qu'il soit basculé sur la position de niveau comme cycliste se trouve sur une planche * / TipStart = 0; accelraw = 0;
while (TipStart <1) {
// vous aurez besoin pour permettre au SG filtrage déposée à la stabilité correcte valeur lors de la première machine à sous tension, avant de regarder la valeur de accsum (Ci-dessous).
for (i = 0; i <20; i ++) {
sample_inputs ();
}if (accsum <504 || accsum> 524) {//
if (x_accdeg> 0) {TipStart = 0; } else {TipStart = 1;
softstart = 0,4; }}angle = 0; cur_speed = 0; / * Fin de basculement code de démarrage. Si aller au-delà de ce point puis la machine est devenue niveau et actif * /
sei ();
while (1) {sample_inputs ();
set_motor ();
}}
La solution
Vous avez probablement le mauvais MCU spécifié pour votre construction. Alors que DDRA existe sur les ATmega1280 sur un Arduino Mega, DDRA n'existe pas sur les ATmega328 d'un Arduino régulier.
Si vous utilisez l'interface Arduino, allez dans Outils | Conseil et choisissez Mega Arduino.
Si vous utilisez votre propre système de construction, vous aurez besoin de mettre à jour la valeur que vous spécifiez pour -mmcu = sur la ligne de commande gcc.
Autres conseils
Je pense que vous avez peut-être laissé de commentaire de clôture ici:
/*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 >>>*/<<<
Lorsque le compilateur vous dit que quelque chose « n'a pas été déclaré dans cette portée », comme vous cette question:
Quel champ n'a est déclarée?
Si vous ne pouvez pas répondre à cette question, alors vous avez découvert le problème. Après tout, si ne savent pas ce que le nom fait référence, comment pouvez-vous attendre que le compilateur? Rappelez-vous que sont l'expert sur un code écriture.
Si vous peut déterminer quelle portée la chose est déclarée, alors la tâche suivante est de déterminer comment cette portée concerne la portée que vous essayez de l'utiliser. Les problèmes typiques comprennent (mais sans s'y limiter) les éléments suivants:
- Il a été déclaré dans un autre espace de noms. Utilisez l'opérateur
::
portée résolution pour donner un nom complet. - Elle a été déclarée en tant que membre d'une classe et que vous essayez de l'utiliser dans une fonction autonome. Soit trouver une instance de la classe et accéder à la variable ou la fonction par cet objet, ou changer la classe d'avoir votre nouvelle fonction comme l'un de ses membres.
Si vous ne peut pas trouver ce champ, il a été déclaré dans, puis il y a quelques choses qui pourraient être mal:
- Vous avez orthographié mal. Vérifiez l'orthographe dans la documentation et corriger votre code.
- Il est déclaré dans certains en-tête que vous avez oublié d'inclure. Savoir où il est déclaré et d'ajouter la directive
#include
appropriée. Ceci est probablement le problème dans votre cas. - Il est pas déclaré nulle part. Figure où il devrait être déclaré et déclarer vous-même là-bas.
Voici un lien vers le code Arduino relativement simple pour le contrôle d'un bricolage Segway.
Ce serait un meilleur point de départ pour votre planche à roulettes, je pense.
http://diysegway.blogspot.com/
Meilleurs voeux
John