• Time
  • Show
Clear All
new posts

  • bwi 971
    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 }


    Leave a comment:

  • bwi 971

    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.


    Leave a comment:

  • bwi 971
    Originally posted by redboat219
    Ever considered adding an "obstacle avoidance sonar"?
    I did....this is the one I considered JSN SR04T

    Leave a comment:

  • Albacore 569
    Thank you , very interesting!

    Leave a comment:

  • redboat219
    Ever considered adding an "obstacle avoidance sonar"?

    Leave a comment:

  • bwi 971
    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.

    Leave a comment:

  • bwi 971
    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;
    rval <<= 1;
    rval |= (digitalRead(din)?1:0);
    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,

    Leave a comment:

  • Alucard
    Here is a Link to one with instructions, I am not suggesting you but this particular one, if you wish to get one but that it is the board with a tutorial 7479593&hvbmt=be&hvdev=c&hvlocphy=92771&hvnetw=o&h vqmt=e&hvtargid=kwd-83632557699499%3Aloc-190&hydadcr=19103_13351684&keywords=arduino+board& qid=1697990337&s=industrial&sr=1-3

    Leave a comment:

  • Albacore 569
    What is a Arduino board?

    Leave a comment:

  • bwi 971
    My preference was to create a PCB where all components would be integrated. While software aids were available, the challenge remained. I aimed for the smallest possible PCB footprint and chose screw terminal blocks for wiring due to their sturdiness, reducing the risk of loose wires caused by vibrations (imo, soldering is n1, screw terminals comes second).

    It's a delicate balance between space efficiency, component alignment, and trace routing. Components can be found in the software library, on the web, or you can use substitutes. The critical factor is the accuracy of the schematics. I had to start over multiple times because some component holes didn't appear when uploaded to the PCB manufacturer's website, which was quite frustrating.

    Although most of these programs offer an auto-routing option, it often doesn't work as expected. I used FRITZING for PCB design, which is user-friendly, and GERBV to verify that everything is correctly displayed and dimensioned.

    Anyway, here's what I came up with."

    Have a nice day,

    Click image for larger version

Name:	Image (27).jpg
Views:	161
Size:	52.0 KB
ID:	175149

    Leave a comment:

  • Alucard
    Well said Quartermaster and i remember that episode, turn it off, lol, receptionist was great and I myself want to learn more about it when I have time.

    Leave a comment:

  • QuarterMaster
    Originally posted by bwi 971

    No offense taken.
    It's a good solution for you guys, but here in Belgium, 900MHz is not allowed.

    It's indeed part of the fun to push boundaries. In addition, an airplane takes off against the wind, not with it.

    Regarding the installation, I understand, although my professional education consisted of grease, oil, heavy fuel, and marine gasoline. Spanners were my tools; screwdrivers were only used as crowbars. Just four weeks ago, I had no clue how to write a single line of code.

    I want the sub to follow my instructions directly, not manipulate it until it does what I want. Commands like diving, surfacing, reaching specific depths, performing a 'crazy Ivan,' initiating an emergency surface, and more. For me, that's where the fun lies in operating a sub.

    My aim isn't to persuade the establishment to adopt Arduino technology, but perhaps the next generation can use it as a start.
    The written word can always be interpreted incorrectly, two folks conversing allows true intent thru facial expression and vocal tone.

    My only intent was for you to not get upset if no one follows the path, and that the regular modeler doesn't freak out and run thinking he needs to learn Arduino. I did use one to get my US Sub ID Beacon to flash the proper light sequence. Advanced programming such as yours is something I plan to tackle when I have the time. Working for the man sucks, but I like to pay bills lol.

    So much can be done here, and the future is exciting for those of us passionate enough to not see these as mere "toy's".

    Mean while Rob's got me thinking "Fembot", providing I don't end up in the ER in a compromising pose like Howard Wolowitz from the "Big Bang Theory"

    Leave a comment:

  • bwi 971
    While adding components to the Arduino Nano, I carefully monitored the available pins. It's important to note that not all pins are equally suitable for specific signals. For instance, pins marked with a '~' symbol (~x) are designed for sending PWM (Pulse Width Modulation) signals, which are commonly used for controlling servos and Electronic Speed Controllers (ESCs). Additionally, 'D' denotes digital pins, and 'A' indicates analog pins.

    • Channel 1: Rudder
    • Channel 3: Depth
    • Channel 4: Throttle

    Two-way Toggle Switch:
    • Channel 2: Logic 1 Dive
    • Channel 5: Logic 2 Surface
    • Channel 6: Logic 3 Optional
    • Channel 7: Logic 4 Optional
    • Channel 8: Logic 5 Optional

    • Pin TX
    • Pin RX
    • Pin RESET
    • Pin GND
    • Pin D2 (channel 1 Receiver pin) - Rudder
    • Pin ~D3 (channel 1 Rudder Servo pin) - Rudder
    • Pin D4 (channel 3 Receiver pin) - Depth
    • Pin ~D5 (channel 3 FwdPlane Servo pin) - Depth
    • Pin ~D6 (channel 4 ESC pin) - Throttle
    • Pin D7 (channel 4 Receiver pin) - Throttle
    • Pin D8 (DRV8871 IN1 pin) - Ballast pump
    • Pin ~D9 (DRV8871 PWM pin) - Ballast pump
    • Pin ~D10 (AftPlane servo pin) - Auto-Pitch
    • Pin D11 (HX710B SCLK) - Depth
    • Pin D12 (HX710B DOUT) - Depth
    • Pin VIN
    • Pin GND
    • Pin RESET
    • Pin +5V
    • Pin A7 (Water detection)
    • Pin A6 (channel 8 Receiver pin) - Logic 5 Optional
    • Pin A5 (MPU6050 SCL pin) - Auto-Pitch
    • Pin A4 (MPU6050 SDA pin) - Auto-Pitch
    • Pin A3 (channel 7 Receiver pin) - Logic 4 Optional
    • Pin A2 (channel 6 Receiver pin) - Logic 3 Optional
    • Pin A1 (channel 5 Receiver pin) - Logic 2 Surface
    • Pin A0 (channel 2 Receiver pin) - Logic 1 Dive
    • Pin AREF
    • Pin +3V3 (MPU6050 VCC pin) - Auto-Pitch
    • Pin D13 (DRV8871 IN2 pin) - Ballast pump

    • Lost signal (LOGIC 2 Surface)
    • Low voltage (LOGIC 2 Surface)
    • Water detection (LOGIC 2 Surface)

    Leave a comment:

  • bwi 971
    I adjusted my BOD cfr feetback of Readboat and David meaning I changed the pitch controll to the aft planes and depth control to the fwd planes, also added the componends I (will) use

    Receiver: (CORONA RD8220II, tested and working)
    This component receives signals from the RC transmitter, providing input to the control system.

    Arduino Nano: (ARDUINO NANO EVERY, so far so good)
    Each channel from the receiver is connected to an Arduino Nano, which processes the input signals and generates output commands for the various control surfaces and components.

    Channel 1 - Rudder Control: (HEXTRONIK HXT900 tested and working, Capacitors on order)
    This channel controls the rudder. To have a "setpoint rudder" indicating the desired rudder angle and an "output servo" that adjusts the rudder's position accordingly.

    Channel 4 - Thrust Control: (ESC ROXXY 930, BL-motor ROXXY 3529 tested and working)
    This channel controls the thrust of the submarine. To have a "setpoint thrust" representing the desired thrust level, and an "output ESC" that regulates the power to the propulsion system to achieve the set thrust level.

    Channel 3 - Depth Control: (HX710 to do, on order)
    This channel adjusts the depth of the submarine. Using a pressure sensor and a PID controller to control the FwdPlanes servo, which manages the depth of the submarine.

    Pitch Control: (MPU6050, tested and working)
    The pitch control system uses an accelerometer and Gyroscope sensor and a PID controller to adjust the position of the AftPlanes servo. This helps control the pitch (tilting) of the submarine.

    Ballast Pump Control: ( DRV8871, to do, on order)
    The ballast control system manages the ballast system, which controls the submarine's buoyancy. The functions include "filling," "off," and "empty," allowing to control the water ballast tank.

    Logic 1 Diving: (to do)
    Ballast Pump Filling: When the "Diving" command is received on Channel 5 ((indicating the desire to dive), enable the ballast pump to fill the tank with water.
    Timer: Set a timer for XX seconds to control how long the pump should operate.
    Pitch and Depth Control: After XX seconds, activate the pitch and depth control systems. This will involve using the PID controllers for the Aft Planes servo and depth control using the pressure sensor.

    Logic 2 surfacing: (to do)
    Ballast Pump Discharge: When the "Surfacing" command is received on Channel 5 (indicating the desire to surface), enable the ballast pump to discharge water from the tank.
    Overrule PID Controllers: During this time, set both the forward and aft dive planes to XX, effectively overruling the normal PID control.
    Timer: Set a timer for XX seconds to control how long the pump should operate and the planes should be at XX.
    Stop Pump and Reset Planes: After XX seconds, stop the ballast pump and reset the forward and aft dive planes to their neutral positions.
    Disable Plane Control: Disable the forward and aft dive plane control systems, so they no longer respond to pitch and depth commands.​

    On the arduino nano I have room to trigger 3 aditional logic's, not yet determined.
    Logic 3 Optional
    Logic 4 Optional
    Logic 5 Optional


    Leave a comment:

  • Nathan
    For completeness, there is an existing submarine control system out there: I don't know that much about it, but it might be really useful as is, or it might have good learnings that can be used elsewhere.

    Leave a comment: