C++ "لم يتم الإعلان عنه في هذا النطاق" خطأ في التجميع ونصائح التعديل

StackOverflow https://stackoverflow.com/questions/1972475

سؤال

أحاول تعديل هذا الرمز في محاولة لجعله يعمل على Arduino Mega.أنا جديد إلى حد كبير على لغة C، لذا ربما ارتكبت بعض الأخطاء الجسيمة.بالمناسبة، هذا من أجل لوح التزلج ذاتي التوازن.:ص

هذا الرمز مأخوذ من ATmega32 (من:[رابط =http://sites.google.com/site/onewheeledselfbalancing/Home/twin-wheel-self-balancing-skateboard-lightweight-version/code4]http://sites.google.com/site/onewheeledsel...t- الإصدار/الكود4[/url] وأحاول أن أجعله يعمل على Arduino Mega.

تمت كتابة هذا الرمز للوحة تطوير ATmega32http://www.active-robots.com/products/controllr/m32db.shtml

شكرًا لك!

هنا هو الخطأ الأول الذي أواجهه:

في الوظيفة 'void timer_init()':خطأ:لم يتم الإعلان عن "TCCR0" في هذا النطاق في الوظيفة "int main ()":

هل يمكن لأحد أن يشرح لي ما هو الخطأ؟أنا مبتدئ في البرمجة إلى حد كبير ولكنني قرأت الكثير من الكتب/مواقع الويب وأتعلم بسرعة أيضًا!^^ وهنا هو الرمز الكامل (طويل جدًا):

#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <math.h>

تعريف CLOCK_SPEED 16000000

تعريف OCR1_MAX 1023

typedef غير موقعة char u8؛void set_motor_idle (void) ؛باطلة مبدئي (void) ؛مستوى التعويم = 0؛تطفو Throttle_pedal ؛تعويم أأ؛تعويم accelraw.تعويم x_acc؛تطفو على السطح؛تعويم x_accdeg;

الجيروسيوم العائم

تعويم عصابة على سبيل المثال؛تعويم Gangleraterads.تعويم تي = 2.2؛

تعويم المكاسب الشاملة.السيطرة على مكاسب تعويم.تعويم فولت البطارية = 24؛تعويم الدورانغليت.زاوية تعويمتعويم الصياد.تعويم Balance_torque؛تعويم SoftStart.

تعويم cur_speed؛Float Cycle_time = 0.0064 ؛تعويم Balance_point؛Float A0 ، A1 ، A2 ، A3 ، A4 ، A5 ، A6 ؛ // Savitzky-Golay متغيرات لمقياس التسارع

كثافة العمليات أنا؛كثافة العمليات ي؛كثافة العمليات تلميح؛void initports (void) {portc = 0x00 ؛// Port C Pullups تم ضبطها على منخفضة (لا يوجد جهد إخراج) لتبدأ مع DDRC = 0xFF ؛// Port C دبابيس جميعها تم تعيينها كإخراج عبر سجل الاتجاه المنفذ C // portc | = (1

DDRA=0x00;.// PORT A PROWUPS مدخلات تم تعيينها على عمليات سحب منخفضة

DDRD=0xFF;// تكوين جميع دبابيس المنفذ D كإخراج كشرط أساسي لـ OCR1A (PIND5) و OCR1B (PIN D4) يعملون بشكل صحيح

بورتب=0x00;// Port B Pullups تم ضبطها على منخفضة (لا يوجد جهد إخراج) لتبدأ بـ DDRB = 0xFF ؛// جميع دبابيس المنفذ B تم تعيينها على الإخراج

} /* الإدخال:أنا أستخدم Atmega32 16MHz مع ساعة بلورية خارجية.ترتيب دبوس جديد مخطط له لوحدة التحكم في محرك OSMC PC4 Onboard LED PD5/OC1A ALI -> OSMC PIN 6 PD4/OC1B BLI -> OSMC PIN 8 PC1 DISABLE -> OSMC PIN 4 PC2 BHI -> OSMC PIN 7 PC3 AHI -> OSMC PIN 5 PA6/ADC6 VBATT/10 -> OSMC PIN 3 PA1/ADC1 معدل الملعب GYRO PA0/ADC0 / void adc_init (void) { / قم بإيقاف المقارنة التناظرية لأننا لا نستخدمه / ACSR = (1 << ACD);/ حدد PA0 / أدموكس = 0؛addux | = (1 <set ADC prescaler إلى 128 ، تمكين ADC ، وبدء التحويل / adcsra = 0 | (1 < / انتظر حتى انتهاء التحويل الأول لبراعة */ بينما (adcsra & (1 << adsc)) {}}

uint16_t adc_read(قناة uint8_t) {
/* اختر القناة / addux = قناة ؛ADMUX |=(1< بدء التحويل /
ADCSRA |= (1 << ADSC);/
انتظر حتى الانتهاء من التحويل / بينما (adcsra & (1 << adsc)) {} / إرجاع النتيجة */ return ADCW ؛}

/* 156 دورة لكل ثانية ، 6.4 مللي ثانية لكل دورة تقاس على الذبذبات*//* اقرأ جميع مدخلات ADC وقم ببعض التحويل*/ void sample_inputs (void) {

uint16_t adc0, adc1, adc2, adc3, adc4, adc5;
 gyrosum=0;   adc0 = adc_read(0); /* accelerometer pin PA0 */   accelraw

= (تعويم) adc0؛ل (ي = 0؛ي<7;j ++) {adc1 = adc_read (1) ؛// gyro pin pa1 gyrosum = (float) الجيروس + ADC1 ؛// باستخدام متوسط ​​7 عينات لكل حلقة للديرو بحيث تحصل على تحديث كامل مع كل حلقة من البرنامج}

adc2 = adc_read(2); /* grey wire overallgain (via cutout switch)

الموضع PA2*/ adc3 = adc_read(3);/* ذراع الموضع سحبت الموضع مرة أخرى PA3*/ ADC4 = ADC_READ (4) ؛/* therottle_pedal posital pa4*/ adc5 = adc_read (5) ؛/* تم دفع ذراع الموضع إلى الأمام PA5*/// ADC6 = ADC_READ (6) ؛/* VBATT INPUT من OSMC (غير مستخدم في الوقت الحاضر) الموضع PA6*/// SAV Golay Filter لـ Accel فقط A0 = A1 ؛a1 = a2;a2 = a3;a3 = a4;a4 = a5؛a5 = a6;A6 = (تعويم) accelraw ؛accsum = (float) ((-2*A0) + (3*A1) + (6*A2) + (7*A3) + (6*A4) + (3*A5) + (-2*A6)) /21 ؛// حساب جولاي

    gaincontrol = (float) gaincontrol*0.9 + 0.1*adc2/341;

// ينعم أي طفرات جهد ويعطي النطاق 0-3 Throttle_pedal = (float) Throttle_pedal*0.9 + 0.1*ADC4/341 ؛// ينعم أي طفرات جهد ويعطي النطاق 0-3

// يقطع المحرك إذا كان زر Mans الميت هو ترك // (GainControl متغير أيضًا من خلال هذا الزر إلى ADC2 إذا (ADC2 <100) {Throttle_pedal = 0.001 ؛التحكم = 0.001 ؛} بشكل عام = gainControl*softStart ؛// ماذا تفعل إذا انسحبت رافعة أو دفعت للأمام أو عدم القيام بأي شيء:Balance_point = 514؛إذا (adc3>100) Balance_point=534;

إذا (adc5>100) Balance_point=494;

 PORTB |= (1<<PB2);//Port B2 turned on/off once per loop so I can

قياس وقت الحلقة باستخدام راسم الذبذبات

/معالجة إشارة مقياس التسارع/ /طرح الإزاحات/ x_acc = (float) accsum - balance_point ؛// accsum هي قيمة SG لـ Accelerometer ، وليس "SUM" حقيقيًا ، لذا لا داعي للقسمة على 7 if (x_acc <-250) x_acc = -250 ؛// cap accel القيم إلى نطاق -250 إلى +250 (80 درجة ميل في كل اتجاه) إذا (x_acc> 250) x_acc = 250 ؛/* تغيير زاوية التسارع حوالي 3.45 وحدة لكل درجة في المدى 0-30 درجة (SIN THETA) تحويل الميل إلى درجة من الإمالة من مستشعر التسارع.زاوية الخطيئة تقريبًا = زاوية للزوايا الصغيرة ، لذا لا داعي لقيام علم المثلثات.x_acc أدناه هو الآن بالدرجات*/

x_accdeg= (float) x_acc/-3.45;.

  /*GYRO signal processing*/
 /*Subtract offsets: Sensor reading is 0-1024 so "balance point"

أي.ستكون نقطة الصفر المطلوبة هي القراءة ناقص 512*/

/تغيير زاوية الدوران البالغ 20 مليون فولت لكل درجة لكل ثانية من ورقة البيانات يعطي تغييرًا قدره 4.096 وحدة (على مقياس 0 - 1023) لكل درجة لكل زاوية ثانية. قادرة على القياس (100deg/sec).لاحظ أن كل هذه الكسور يتم تقريبها إلى عدد صحيح في وقت لاحق قبل إرسالها إلى مولد PWM والذي بدوره متصل بوحدة تحكم المحرك/gangleratedeg = (تعويم) ((الجيروس/7) - 508) /4.096 ؛// الجيروسوم هو مجموع مجموعة من 7 عينات حتى تقسمها 7 لقيمة الدوران إذا (gangleratedeg <-92) gangleratedeg = -92 ؛إذا (عصابة على سبيل المثال

92) العقدة=92 /أقوم بتشغيل المنفذ B2 وإيقاف تشغيله مرة واحدة لكل دورة برنامج رئيسية حتى أتمكن من إرفاق الذبذبات به وأعمل على تحديد وقت دورة البرنامج ، أستخدم وقت الدورة لإجراء تغيير زاوية الدوران لكل دورة حيث يتعين عليك معرفة طول هذا الوقت فاصلة/ بورتب &= (0<

/يمثل TI التحجيم لـ "I" أو عامل متكامل (حاليًا 2.2 هنا) Gyronglett هو AngleChange منذ الدورة الأخيرة بدرجات من مستشعر الدوران ، حيث يكون TI عامل التحجيم (يجب أن يكون من الناحية النظرية حوالي 1 ولكن 2.2 يجعل اللوحة أكثر إحكاما)
Ganglerate الآن في وحدات من الدرجات في الثانية AA يختلف الوقت الثابت ، أي أن قيمة AA الأصغر تجعل وقت التسارع ثابتًا لفترة أطول لأنه يصحح ببطء لانجراف الدوران
/

أأ=0.005;gyroangledt = (تعويم)tiدورة الزمنGangleratedeg;
gangleraterads=(float)gangleratedeg*0.017453;

/الزاوية الجديدة في الدرجات هي زاوية قديمة بالإضافة إلى تغيير في الزاوية من الدوران منذ الدورة الأخيرة مع القليل من القراءة الجديدة التي تم تأسيسها في/ angle = (float) ((1-AA) * (angle + gyroanglett)) + (aa * x_accdeg) ؛// وظيفة حساب الزاوية الرئيسية*///تحويل الزاوية من الدرجات إلى الراديان

 anglerads=(float)angle*0.017453;
      balance_torque=(float)(4.5*anglerads)

+ (0.5*جانجليراتراد)؛

cur_speed = (float) (cur_speed + (throttle_pedal * balance_torque * cycle_time)) * 0.999 ؛

/*قيمة المستوى من -1 إلى +1 وتمثل دورة العمل المراد إرسالها إلى المحرك.يساعدنا التحويل إلى Radians على البقاء ضمن مستوى هذه الحدود = (Balance_torque + cur_speed) * بشكل عام ؛

}

void timer_init () {tccr0 = 0 | (1

// وضع PWM هو "PWM ، المرحلة الصحيحة ، 10 بت" TCCR1A = 0 | (1

(1<

مجموعة باطلة ()

/* مصطلحات المستوى هي مصطلح المستوى الذي تم إعادة قياسه من -1023 إلى +1023 باعتباره عددًا صحيحًا جاهزًا للإرسال إلى منافذ التحكم في محرك PWM والتي بدورها متصلة بـ OSMC*/ {

// إذا (المستوى <-0.9) المستوى = -0.9 ؛ // الشيكات ، نحن ضمن حدود معقولة // إذا (المستوى> 0.9) المستوى = 0.9 ؛

int16_t leveli = (int16_t) (المستوى*1023) ؛)

إذا كان (المستوى <-1020) المستوى = -1020 ؛ // ، فإننا نكون ضمن حدود PWM معقولة كما لا نريد أن نلقي فجأة من اللوحة إذا (Leveli> 1020) المستوى = 1020 ؛

/إعداد LED أو الجرس على المنفذ B1 لتحذيري من التباطؤ إذا كان عزم الدوران الذي سيتم تسليمه هو أكثر من 50 ٪ من الحد الأقصى للسبب في ذلك هو أنك تحتاج دائمًا المحرك الذي يعمل بالفعل مسطحًا ، ستكون على وشك أن تسقط بسرعة عالية!يستخدم البعض روتين الظهر التلقائي للحد تلقائيًا من السرعة القصوى.الآن سأفعل ذلك بهذه الطريقة أسهل/

إذا (المستوى<-0.7 || المستوى>0.7) {
portb | = (1 <portb & = (0

softstart = (float) softstart+0.001;إذا (softstart>1.0) softstart=1.0;

//PORTC |= (0<<PC1);   // AHI=1  PinC3, BHI=1 PinC2 set both to ON for

OSMC للعمل وكلاهما لإغلاق المحرك لأسفل /*ملاحظة:لست متأكدًا من السبب ، ولكن إيقاف التغير في الاتجاه تغييرات في النهاية إلى الأسلاك الصلبة AHI و BHI إلى +12V / / OSMC غير معمول به عن طريق تعيين إخراج PINC1 على الصفر ، من شأنه تعطيل OSMC*/ PORTC | = 0x0C ؛// اجعل C1 يتم سحبها لأسفل حتى un-disables OSMC أيتمكنه.PORTC &= ~0x02;// disable يتم إيقاف تشغيل IF (Leveli <0) {OCR1A = -LEVELI ؛.OCR1B = 0؛// bli = 0} آخر {ocr1a = 0 ؛.// BLI هو PWM } }

int main (void) {initports () ؛

adc_init();

timer_init();

/* رمز الإمالة الأولي قم بتشغيل micro بينما يميل اللوحة إلى جانب واحد ، على وشك التنقل إليه ، إذا كانت زاوية الإمالة تعبر خوارزمية توازن النقطة الصفر (منتصف) ، فإنها تعمل على خلاف ذلك مقفلة في هذه الحلقة إلى الأبد حتى يتم توجيهها إلى وضع المستوى عندما يحصل Rider على اللوحة*/ tipStart = 0 ؛تسريع = 0;

بينما (تلميح<1){

// تحتاج إلى هذا للسماح لمرشح SG بالانتهاء من القيمة المستقرة المناسبة عند تشغيل الجهاز أولاً ، قبل النظر إلى قيمة ACCSUM (أدناه).

ل (ط = 0؛أنا <20؛ط ++) {
Sample_inputs();
}

إذا (أكسوم<504 || أكسوم>524) {//
إذا (x_accdeg>0) { Tipstart=0;} آخر {tipStart = 1 ؛
softstart=0.4;} }

زاوية = 0؛cur_speed=0;/* نهاية رمز بدء الميل.إذا تجاوزت هذه النقطة ، فسيصبح الجهاز مستويًا ونشط*/

sei();

بينما (1) {sample_inputs();

set_motor();

} }

هل كانت مفيدة؟

المحلول

من المحتمل أن يكون لديك وحدة MCU خاطئة محددة للبناء الخاص بك.في حين أن DDRA موجود على ATmega1280 على Arduino Mega، فإن DDRA غير موجود على ATmega328 على Arduino العادي.

إذا كنت تستخدم واجهة المستخدم Arduino ، فانتقل إلى الأدوات | اللوحة واختيار Arduino Mega.

إذا كنت تستخدم نظام البناء الخاص بك، فستحتاج إلى تحديث القيمة التي تحددها لـ -mmcu= في سطر أوامر gcc.

نصائح أخرى

أعتقد أنك ربما تركت التعليق الختامي هنا:

/*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 >>>*/<<<

عندما يخبرك المترجم أن شيئًا ما "لم يتم الإعلان عنه في هذا النطاق"، مثل هذا السؤال بنفسك:

ما النطاق كان أعلن في؟

إذا لم تتمكن من الإجابة على هذا السؤال، فقد اكتشفت المشكلة.بعد كل شيء، إذا أنت لا أعرف إلى ماذا يشير هذا الاسم، كيف تتوقع أن يفعل المترجم ذلك؟تذكر ذلك أنت هم الخبراء في أي رمز أنت يكتب.

اذا أنت يستطيع تحديد النطاق الذي تم الإعلان عن الشيء فيه، ثم تتمثل المهمة التالية في تحديد كيفية ارتباط هذا النطاق بالنطاق الذي تحاول استخدامه فيه.تشمل المشاكل النموذجية (على سبيل المثال لا الحصر) ما يلي:

  • تم الإعلان عنه في مساحة اسم أخرى.استخدم ال :: عامل دقة النطاق لإعطاء اسم مؤهل بالكامل.
  • لقد تم الإعلان عنه كعضو في الفصل الدراسي وأنت تحاول استخدامه في وظيفة مستقلة.يمكنك إما العثور على مثيل للفئة والوصول إلى المتغير أو الوظيفة من خلال هذا الكائن، أو تغيير الفئة لتكون وظيفتك الجديدة أحد أعضائها.

اذا أنت لا أستطيع ابحث عن النطاق الذي تم الإعلان عنه، ثم هناك بعض الأشياء التي قد تكون خاطئة:

  • لقد كتبتها بشكل خاطئ.تحقق من التهجئة في الوثائق وأصلح الكود الخاص بك.
  • لقد تم الإعلان عنه في بعض الرؤوس التي نسيت تضمينها.اكتشف مكان الإعلان وأضف المناسب #include التوجيه. ربما هذه هي المشكلة في حالتك.
  • لم يتم الإعلان عنها في أي مكان.معرفة أين هو يجب أعلن وأعلن ذلك هناك بنفسك.

فيما يلي رابط لكود Arduino البسيط والمباشر للتحكم في DIY Segway.

أعتقد أن هذه ستكون نقطة انطلاق أفضل للوح التزلج الخاص بك.

http://diysegway.blogspot.com/

أطيب التمنيات

جون

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top