Arduino

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • bwi 971
    Captain
    • Jan 2015
    • 896

    #46
    The depth control.
    That was the biggest challenge so far. It did not want to cooperate; it ignored me for hours and hours. There are times when I appreciate silence, but this wasn't one of those moments.
    Eventually, I managed to make it communicate with me in voltages. That was strange; normally these things communicate in Amperes, but hey, never look a gift horse in the mouth.
    After I found a library that worked the below code will let it communicate:
    uint32_t sread(int p)
    {
    uint32_t rval=0;
    int x=0;
    for(x=0;x<p;x++){
    digitalWrite(sck,HIGH);
    delayMicroseconds(10);
    if(x<24){
    rval <<= 1;
    rval |= (digitalRead(din)?1:0);
    }
    digitalWrite(sck,LOW);
    delayMicroseconds(10);
    }
    return rval;
    }​

    Imagine the pressure sensor as a "communication puzzle." It sends information bit by bit, like solving a jigsaw puzzle one piece at a time. Each piece (bit) is a tiny part of the whole picture (data).
    The expresion "uint32_t sread(int p)" in code, is like a special tool for solving this puzzle. It does the following:
    1. It starts by getting ready to receive a puzzle piece by making a signal (like a "let's start" sign).
    2. It waits a short moment to make sure everything is ready.
    3. It looks at the puzzle piece (the bit) and decides where it fits in the puzzle (called a rval variable).
    4. It then asks for the next puzzle piece (bit) and fits it in.
    5. This process continues for all the pieces (bits) of the puzzle.
    6. Finally, it assembles all the pieces (bits) into a complete picture (called the rval value).
    So, in simple terms, this code is like a "puzzle solver" that takes the sensor's data, which comes one piece at a time, and puts it together to get the whole picture. It helps to understand what's going on with the pressure sensor and get useful information from it, like in this case voltage that can be converted to depth.
    The sensor is able to sence the depth in mm so its pretty darn accurate, maybe too accurate, but if so I can make it work with averages over a certain time.

    I'm not out of the ballpark yet, I have to use this data to compare signals sent by the receiver whith the actual valuses measured by the sensor and then sent a signal to theFwdPlane servo and toss a PID on top of it.

    Have a nice one,
    Bart
    Practical wisdom is only to be learned in the school of experience.
    "Samuel Smiles"

    Comment

    • bwi 971
      Captain
      • Jan 2015
      • 896

      #47
      The progress today, the PID in place and it controls the servo as the depth changes; the tube in the glass.
      Requested depth was manualy set in the code.
      Next step request the depth trough the TX-RX.​

      Last edited by bwi 971; 10-24-2023, 04:02 PM.
      Practical wisdom is only to be learned in the school of experience.
      "Samuel Smiles"

      Comment

      • redboat219
        Admiral
        • Dec 2008
        • 2723

        #48
        Ever considered adding an "obstacle avoidance sonar"?
        Make it simple, make strong, make it work!

        Comment

        • Albacore 569
          Commander
          • Sep 2020
          • 301

          #49
          Thank you , very interesting!

          Comment

          • bwi 971
            Captain
            • Jan 2015
            • 896

            #50
            Originally posted by redboat219
            Ever considered adding an "obstacle avoidance sonar"?
            https://www.aliexpress.com/item/1005005245293992.html
            I did....this is the one I considered JSN SR04T


            Practical wisdom is only to be learned in the school of experience.
            "Samuel Smiles"

            Comment

            • bwi 971
              Captain
              • Jan 2015
              • 896

              #51


              I was talking to a friend and former colleague of mine, and we discussed the open-source aspect of my project. One of the points we raised was the variability in how each sub behaves and how to address these differences without accessing the underlying code. We were looking for a one-size-fits-all solution. Our conclusion was that I needed to make the proportional setting for the PID controllers remotely adjustable. QuarterMaster also mentioned that it's available for the 900MHz systems.

              The proportional gain (Kp) is a crucial factor that determines the controller's responsiveness to the current error between the desired setpoint and the actual process variable. In simple terms, it governs how much the control output should change in response to the current error. A higher proportional gain results in a more aggressive response, where the controller reacts more strongly to minimize the error.

              To achieve this, I need to connect two additional channels to the Arduino Nano. However, the available pins are already occupied, so I'll have to make a choice between removing the rudder or throttle control from the Arduino. Alternatively, I might consider using a PCA9685 PWM Servo Driver PCB, which can control multiple servos.

              I've decided to remove the rudder control, freeing up two pins for adjusting the gain. The rudder is not utilized anywhere in the logic, whereas the throttle might be used in an "emergency blow" scenario."/LOGIC.

              With adding two more channels I loose 2 of 3 optional LOGIC's.

              Grtz,
              Bart​​
              Practical wisdom is only to be learned in the school of experience.
              "Samuel Smiles"

              Comment

              • bwi 971
                Captain
                • Jan 2015
                • 896

                #52
                To set the depth seems not so simple as the signal from the transmitter varies and is not stable. For the moment, I have run into a personal limitations wall. I will persevere to deal with it, but for now, I must settle for depth thresholds. This method works fine, although this was not what I pursued. I'm not sure how many depth thresholds I will include. Six, perhaps: depths of 0, 400, 800, 1200, 1600, and 2000 mm.

                Just to give an idea of the code that is require for controlling the depth:

                #include <HX710B_SIMPLE.h> #include <Servo.h> #define SCK 11 #define SDI 12 HX710B_SIMPLE airPressureSensor(SCK, SDI); Servo depthServo; float depth; float setpoint; // Declare setpoint in the global scope float pidOutput; float Kp = 0.5; float Ki = 0.00; float Kd = 0.1; float integral = 0; float lastError = 0; unsigned long calibrationStartTime = 0; unsigned long calibrationDuration = 30000; #define RX_PIN 4 // Define the pulse duration to setpoint mapping const unsigned long pulseRanges[] = {1250, 1400, 1550, 1700, 1850, 2000, 2150, 2300}; const float setpoints[] = {0, 300, 600, 900, 1200, 1500, 1800, 2100}; const int numRanges = 8; void setup() { airPressureSensor.init(); delay(100); Serial.begin(9600); depthServo.attach(5); depthServo.write(90); Serial.println("Depth (mm)"); calibrationStartTime = millis(); } void loop() { unsigned long currentTime = millis(); float voltage = airPressureSensor.readVoltage(); float error; unsigned long pulseDuration = pulseIn(RX_PIN, HIGH, 40000); // Read pulse duration from RX // Map pulse duration to setpoint setpoint = mapToSetpoint(pulseDuration); if (currentTime - calibrationStartTime < calibrationDuration) { depth = 0.00; Serial.println("Calibration Mode"); } else { depth = map(voltage * 1000, 0, 2.5 * 1000, 0, 4000); // 4m = 4000mm if (voltage > 2.5) { depth = 0.00; // Set depth to 0mm for voltage above 2.5V } error = setpoint - depth; integral += error; float derivative = error - lastError; pidOutput = Kp * error + Ki * integral + Kd * derivative; int servoPosition = constrain(90 + int(pidOutput), 20, 170); depthServo.write(servoPosition); Serial.print("Voltage: "); Serial.print(voltage, 2); Serial.print("V, Depth: "); Serial.print(depth, 2); Serial.print(" mm, Servo Position: "); Serial.print(servoPosition); Serial.print(" RX Pulse Duration: "); Serial.print(pulseDuration); Serial.print(" Set Depth: "); Serial.print(setpoint); Serial.println(" mm"); Serial.println("Running Mode"); } lastError = error; delay(1000); } float mapToSetpoint(unsigned long pulseDuration) { for (int i = 0; i < numRanges; i++) { if (pulseDuration <= pulseRanges[i]) { return setpoints[i]; } } return 2100; // Default to 2100 if pulse duration is out of range }

                Bart
                Practical wisdom is only to be learned in the school of experience.
                "Samuel Smiles"

                Comment

                Working...