Hi guys!
Sorry for my English.
Hope you can help me out a bit. I took over this project from a former employee and sadly my projects including an Arduino are far between – so my programming skills are pretty rusty.
In the code below I’ve tried to write some code for the project, which should do the following:
Imagine you’re on a ship and your task is to control a winch, which has a lot of cable on it and you need to lower an instrument into the ocean. But as a winch controller you must also make sure you know how much cable you’ve rolled into the ocean so the instruments don’t hit the bottom, and at which speed you roll out the cable. When rolling the cable backwards onto the winch, the speed must also be known and it’s also nice to know how much cable is left.
Now – we got the hardware for this and it’s all setup and working. It consists of two Hall Effect Sensors, which sends a “LOW” when it senses a piece of magnetic material passing by. The Arduino reads this value and sends text to a 4x20 Blue LCD Display.
What we need your help with is this:
Since the Hall Effect sensors are mounted on the winch with a few centimeters between, they both go “LOW” with a small delay between them, no matter if the winch is rolling forward or backwards, which is logical to understand, they’re not doing anything wrong.
But – I can’t get the code right to figure out HOW the Arduino should know and tell the display if the winch is rolling forwards or backward (Cable in or out). I think it should be possible somehow, but it’s pretty difficult to differentiate the signals, since those two sensors acts in the same way and both activates with a small delay, no matter what direction the winch is rolling.
So what do you think could be done? Hope the code below is somewhat understandable.
What really happens with the current code below, is that the counter first counts up, shortly after it counts down, then up, then down.. so the counting isn't really going anywhere.
The speed at which you run the winch is working fine, it don't care if the cable is being run in or out.
P.S - Sorry for all the O's - just like them for separation ![]()



//OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
#include <Wire.h> // Comes with Arduino IDE
#include <LiquidCrystal_I2C.h>
//OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
int sensor1 = 2; // Magnetsensor 1 input from Hall-Effect Sensor 1.
int sensor2 = 3; // Magnetsensor 2 input from Hall-Effect Sensor 2.
int winch_switch = 7; // Switch to choose between CTD or WP2 winch.
int sensor_count = 0; //Set the sensor count to zero.
int sensor_last_value = LOW;
volatile float counting_range; // Defines how much the counter should count up or down when the Magnetsensor is activated.
volatile float Total_cable; // Defines in total how much the cable has been rolled in or out.
unsigned long Start_timer; //starts the timer when a Magnetsensor is activated.
unsigned long Saved_timer; //Saves how far the timer counted.
volatile float Timedifference; //Timedifference in milliseconds.
volatile float Timer_MPM; // Timer for meters per minute.
volatile float Timer_seconds; //Timer time in seconds.
volatile float Timer_minutes; //Timer time in minutes.
volatile int Cable_MPM; //Saves the cable length rolled in or out in meters per minute.
//OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
//Setup blue LCD Display.
// set the LCD address to 0x3F for a 20 chars 4 line display
// some displays may respond on 0x27 instead!
// Set the pins on the I2C chip used for LCD connections: addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
//OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
void setup()
{
lcd.begin(20,4); // initialize the lcd for 20 chars 4 lines, turn on backlight
// ------- Quick 2 blinks of backlight -------------
for(int i = 0; i< 3; i++)
{
delay(250);
lcd.noBacklight();
delay(250);
}
lcd.backlight(); // finish with backlight on
pinMode(2, INPUT_PULLUP); // Enable internal pull-up resistor on pin 2
pinMode(3, INPUT_PULLUP); // Enable internal pull-up resistor on pin 3
pinMode(winch_switch, INPUT);
digitalWrite(winch_switch, HIGH);
attachInterrupt(0, sensor_counter, CHANGE);
attachInterrupt(1, sensor_counter, CHANGE);
lcd.setCursor(0,0);
lcd.print("NULSTIL I OVERFLADEN"); // Means "reset at the surface"
lcd.setCursor(0,1);
lcd.print("--------------------");
lcd.setCursor(0,2);
lcd.print("SPEED ");
lcd.write(0x7E);
lcd.setCursor(0,3);
lcd.print("METER ");
lcd.write(0x7E);
}
//OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
void sensor_counter ()
{
if ((sensor_last_value == HIGH) && (digitalRead(sensor1) == LOW && (digitalRead(winch_switch) == LOW))) // In this mode Winch_switch is chosen for CTD winch.
{
Start_timer = millis();
Timedifference = Start_timer-Saved_timer;
Timer_seconds = Timedifference/1000; //Some time converting from mS to seconds.
Timer_minutes = Timer_seconds/60; //Some time converting from seconds to minutes.
Cable_MPM = 0.10/Timer_minutes; //Used for calculating the speed of rolling cable out (meters per minute).
Saved_timer = Start_timer;
if (digitalRead(sensor2) == LOW)
{
sensor_count = sensor_count + 1; // Count up if sensor2 goes low first.
}
else
{
sensor_count = sensor_count - 1; // Count down if sensor1 goes low first.
}
counting_range = sensor_count * 0.10; //Count up 10 centimeters every time the magnetic sensor is activated.
Total_cable = counting_range;
}
if ((sensor_last_value == HIGH) && (digitalRead(sensor1) == LOW && (digitalRead(winch_switch) == HIGH))) // In this mode Winch_switch is chosen for WP2 winch.
{
Start_timer = millis();
Timedifference = Start_timer - Saved_timer;
Timer_seconds = Timedifference/1000; //Some time converting from mS to seconds.
Timer_minutes = Timer_seconds/60; //Some time converting from seconds to minutes.
Cable_MPM = 0.10/Timer_minutes; //Used for calculating the speed of rolling cable out (meters per minute).
Saved_timer = Start_timer;
if (digitalRead(sensor2) == LOW)
{
sensor_count = sensor_count - 1; // Count up if sensor2 goes low first.
}
else
{
sensor_count = sensor_count + 1; // Count down if sensor1 goes low first.
}
counting_range = sensor_count * 0.10; //Count up 10 centimeters every time the magnetic sensor is activated.
Total_cable = counting_range;
}
sensor_last_value = digitalRead(sensor1);
}
//OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
void loop()
{
if(millis() - Start_timer > 4000)
{
//delay(500);
Cable_MPM = 0;
lcd.setCursor(11,2);
lcd.print(" "); //Inserting some blank space for this type of display.
}
if (digitalRead(winch_switch) == HIGH)
{
lcd.setCursor(10,2);
lcd.print(Cable_MPM,1); //Write the rotation speed on display when winch_switch is HIGH.
}
if (digitalRead(winch_switch) == LOW)
{
lcd.setCursor(10,2);
lcd.print(Cable_MPM,1); //Write the rotation speed on display when winch_switch is LOW.
}
if(digitalRead(winch_switch) == HIGH)
{
lcd.setCursor(10,3);
lcd.print(Total_cable,2); //Write the total cable length rolled out, on display, when winch_switch is HIGH.
lcd.print(" ");
}
if(digitalRead(winch_switch) == LOW)
{
lcd.setCursor(10,3);
lcd.print(Total_cable,2); //Write the total cable length rolled out, on display, when winch_switch is LOW.
lcd.print(" ");
}
}
//OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO



