Значения частных переменных класса недоступны в публичной функции

Я экспериментирую с классами в коде Arduino. У меня есть следующий небольшой фрагмент кода:

#include "Motor.h"
#include "Arduino.h"

Motor::Motor()
{

}

void Motor::Configure(uint16_t inA_pin, uint16_t inB_pin, uint16_t speed_pin, Stream* SerPort)
{
    uint16_t _inA_pin = inA_pin;
    uint16_t _inB_pin = inB_pin;
    uint16_t _speed_pin = speed_pin;
  gl_pSerPort = SerPort;

    gl_pSerPort->printf("...._inA_pin set to %d\n", _inA_pin);
    gl_pSerPort->printf("...._inB_pin set to %d\n", _inB_pin);
    gl_pSerPort->printf("...._speed_pin set to %d\n", _speed_pin);


    pinMode(_inA_pin, OUTPUT);
    pinMode(_inB_pin, OUTPUT);
    pinMode(_speed_pin, OUTPUT);


}

void Motor::RunMsec(bool bisFwd, uint16_t onMsec, uint16_t speed)
{
  gl_pSerPort->printf("RunMsec(%d, %d, %d\n", bisFwd, onMsec, speed);
  gl_pSerPort->printf("RunMsec: _inB_pin = %d\n", _inB_pin);
  gl_pSerPort->printf("RunMsec: _speed_pin = %d\n", _speed_pin);
  gl_pSerPort->printf("%lu: Calling Run(%d, %d)\n",millis(), bisFwd,speed);
    Run(bisFwd, speed);

    //Шаг 2: Задержка timesec секунд
    delay(onMsec);

    //Шаг 3: Добавлены остановки двигателей 04/12/21
  gl_pSerPort->printf("%lu: Calling Stop()\n",millis());
    Stop();
}

Файл Motor.h:

#pragma once
#include "Arduino.h"

const uint16_t MOTOR_SPEED_FULL = 200; //диапазон 0-255
const uint16_t MOTOR_SPEED_MAX = 255; //диапазон 0-255
const uint16_t MOTOR_SPEED_HALF = 127; //диапазон 0-255
const uint16_t MOTOR_SPEED_QTR = 75; //добавлено 25.09.20
const uint16_t MOTOR_SPEED_LOW = 50; //добавлено 22.01.15
const uint16_t MOTOR_SPEED_MIN = 15; //добавлено 12/24/23 для обнаружения «зеркального sfc»
const uint16_t MOTOR_SPEED_OFF = 0; //диапазон 0-255
const uint16_t MOTOR_SPEED_CAPTURE_OFFSET = 75; //добавлено 06/21/20 для захвата смещения
const uint16_t TURN_START_SPEED = MOTOR_SPEED_QTR; //добавлено 14.11.21

class Motor
{
public:
    Motor();
    void Configure(uint16_t inA_pin, uint16_t inB_pin, uint16_t speed_pin, Stream* gl_pSerPort);
    void RunMsec(bool bIsFwd = true, uint16_t onMsec = 1000, uint16_t speed = MOTOR_SPEED_HALF);
    void Run(bool bIsFwd = true, uint16_t speed = MOTOR_SPEED_HALF);
    void Stop();

private:
    uint16_t _inA_pin;
    uint16_t _inB_pin;
    uint16_t _speed_pin;
    Stream* gl_pSerPort;

    void SetDirAndSpeed(bool bIsFwd, uint16_t speed);
};

Код в соответствующем .ino-файле:

#include "Motor.h"
#include <Wire.h>
#include "FlashTxx.h"       // Флэш-примитивы TLC/T3x/T4x

#pragma region MOTOR PINS
//11/04/21 Теперь используем драйверы Pololu VNH5019 для всех 4 двигателей
const uint16_t InA_Left = 22;
const uint16_t InB_Left = 21;
const uint16_t Spd_Left = 23;

const uint16_t InA_Right = 34;
const uint16_t InB_Right = 33;
const uint16_t Spd_Right = 35;
#pragma endregion MOTOR PINS

Motor LeftMotor;
Motor RightMotor;

  Stream* gl_pSerPort = 0; //09/26/22 сделан глобальным, поэтому может использоваться везде.


void setup()
{
#pragma region SERIAL_PORTS
  Serial.begin(115200);
  delay(2000); //10/06/21 - просто используйте фиксированную задержку

  Serial1.begin(115200);
  delay(2000); //11/20/21 использовать фиксированную задержку вместо ожидания

  if (Serial)
  {
    Serial.printf("Serial port active\n");
    gl_pSerPort = (Stream*)&Serial;
  }
  else if (Serial1)
  {
    Serial.printf("Serial1 port active\n");
    gl_pSerPort = (Stream*)&Serial1;
  }

  gl_pSerPort->printf("gl_pSerPort now points to active Serial (USB or Wixel)\n");

  //25.02.23 добавлено для использования Garmin LIDAR-Lite V4/LED
  Serial2.begin(115200);
  delay(2000); //11/20/21 использовать фиксированную задержку вместо ожидания

  LeftMotor.Configure(InA_Left, InB_Left, Spd_Left, gl_pSerPort);
  RightMotor.Configure(InA_Right, InB_Right, Spd_Right, gl_pSerPort);

#pragma endregion SERIAL_PORTS
}

void loop()
{
  //redLED.Мигание(2000);
  //задержка(200);

  //yelLED.Мигание(2000);
  //задержка(1000);

  gl_pSerPort->printf("%lu: LeftMotor.RunMsec()\n", millis());
  LeftMotor.RunMsec(5000); //вперед на 1 сек
  delay(500);

  gl_pSerPort->printf("%lu: RightMotor.RunMsec()\n", millis());
  RightMotor.RunMsec(5000); //вперед на 1 сек
  delay(500);
}

При запуске я получаю следующий вывод из встроенных операторов печати:

Opening port
Port open
Serial port active
gl_pSerPort now points to active Serial (USB or Wixel)
...._inA_pin set to 22
...._inB_pin set to 21
...._speed_pin set to 23
...._inA_pin set to 34
...._inB_pin set to 33
...._speed_pin set to 35
6300: LeftMotor.RunMsec()
RunMsec(1, 1000, 127
RunMsec: _inB_pin = 0
RunMsec: _speed_pin = 0
6300: Calling Run(1, 127)
In SetDirAndSpeed(true, 127)
In TRUE block of SetRighttMotorDirAndSpeed(true, 127)
....Pin 0 set to 1
....Pin 0 set to 1
7300: Calling Stop()
In SetDirAndSpeed(true, 0)
In TRUE block of SetRighttMotorDirAndSpeed(true, 0)
....Pin 0 set to 0
....Pin 0 set to 0
7800: RightMotor.RunMsec()

Из распечаток я вижу, что Motor::Configure() правильно инициализирует закрытые переменные-члены, но Motor::RunMsec() сообщает, что _inB_pin = 0 и _speed_pin = 0, так что что-то мешает RunMsec увидеть значения, установленные Configure().

Кто-нибудь видит, что я здесь делаю не так?

ТИА,

Фрэнк

, 👍-1


1 ответ


Лучший ответ:

3

В вашей функции конфигурации:

void Motor::Configure(uint16_t inA_pin, uint16_t inB_pin, uint16_t speed_pin, Stream* SerPort)
{
    uint16_t _inA_pin = inA_pin;
    uint16_t _inB_pin = inB_pin;
    uint16_t _speed_pin = speed_pin;
  gl_pSerPort = SerPort;

Вы создаете новые локальные переменные с именами _inA_pin, _inB_pin и _speed_pin. Эти новые локальные переменные затеняют переменные-члены. У вас есть несколько переменных с одинаковым именем, и будет использоваться более локальная область видимости.

Я не думаю, что вы хотите иметь там uint16_t. Я думаю, вы хотите поместить эти значения в переменные-члены в классе.

void Motor::Configure(uint16_t inA_pin, uint16_t inB_pin, uint16_t speed_pin, Stream* SerPort)
{
    _inA_pin = inA_pin;
    _inB_pin = inB_pin;
    _speed_pin = speed_pin;
  gl_pSerPort = SerPort;
,