---
title: "Wizfloats"
url: "https://maker.wiznet.io/Tri_kiting/contest/wizfloats/"
markdown_url: "https://maker.wiznet.io/Tri_kiting/contest/wizfloats/md"
type: "Contests"
author: "Tri Susanto"
author_url: "https://maker.wiznet.io/Tri_kiting/"
original_author: "Tri Susanto"
license: "GNU General Public License, version 3 or later (GPL3+)"
published: "2024-07-08"
language: "en"
tags: ["C/C++"]
hardware: ["WIZnet W7500", "SparkFun Stepper motor driver board A4988", "Seeed Studio Grove - Micro Switch"]
likes: 27
views: 5576
comments: 4
source: "WIZnet Makers (https://maker.wiznet.io/)"
---

# Wizfloats

> Wizfloats are a type of floating device for ocean health. The floats will collect temperature, depth, and biogeochemical data information

Original author: Tri Susanto

## Components

- **WIZnet W7500** x 1 ([docs](https://docs.wiznet.io/Product/Chip/MCU/W7500))
- **SparkFun Stepper motor driver board A4988** x 1 ([docs](https://cdn.sparkfun.com/datasheets/Robotics/A4988-Datasheet.pdf))
- **Seeed Studio Grove - Micro Switch** x 1 ([docs](https://www.seeedstudio.com/Grove-Micro-Switch.html))
- Software: **solidworks SolidWork**: CAD Design ([docs](https://www.solidworks.com/support/resource-center))
- Software: **microsoft Visual Studio 2017** ([docs](https://visualstudio.microsoft.com/vs/))

## Documents and links

- [All code Wizfloat project](https://github.com/3susanto/Wizfloat) (code)
- [Schematics all Wizfloats project](https://maker.wiznet.io/_lib/download.asp?path=project/10013&downfile=Wizfloat%2Epng) (schematics)
- [CAD Desain](https://grabcad.com/library/bifloats-1)

## Article

WIZFLOATS
Wizfloats are a type of floating device for ocean health. The floats will collect temperature, depth, and biogeochemical data information.

Before I create this Wizfloats, which has been widely implemented worldwide. And everyone can freely access the data for research, such as Argo.ucsd.edu and Mbari.org. However, these tools or applications have not been widely distributed in Indonesia. Because all activities will be regulated by the government through the BMKG agency. So the system I am creating has never been tested in my own country.

bifloats is a prototype of an autonomous underwater robot, which consists of only one cylinder carrying several sensors. The system works very simply: this floating robot will automatically sink using a ballast tank system similar to submarines, then it will read all conditions within the sea, including depth and temperature. After some time, it will resurface. Ideally, in this experiment, the data collected should be automatically transmitted using wifi or satellite, but for this project, I have difficulty finding devices that can support the components and size of my cylinder. Therefore, for now, it only utilizes cables for data transmission. With the presence of Wizfloats.

**In this production, there are several steps involved:**

- 3D Design using Solidworks 2022 Student Version

- Mechanical Assembly

- Controller Design

- Programming

**Hardware**

1. Surf5

2. WIZPOE-P1

3. Stepper Motor

4. A4988 - Stepper Motor Driver

5. Depth/ Pressure Sensor (ms5837 blue robotics)

6. DS18B20 Waterproof Temperature Sensor

7. limit switch

8. syringe 20ml

9. Lippo Battery 2 cell

10. UBEC

**Software**

1. Visual Studio

2. Solidworks

## Step 1: 3D Design

Every time I work on a project, after coming up with an idea, I always design it using the CAD application that I usually use, which is Solidworks 2022 Student Version. By using this CAD application, I can lay out the mechanical components of the project I'm working on. I can even simulate whether the position and movements are okay.

![](https://maker.wiznet.io/upload/ckeditor5/901487399%5F1719631320%2Epng)

![](https://maker.wiznet.io/upload/ckeditor5/901487399%5F1719644545%2Epng)

![](https://maker.wiznet.io/upload/ckeditor5/901487399%5F1719641892%2Epng)

***Bottom side***

![](https://maker.wiznet.io/upload/ckeditor5/901487399%5F1719644588%2Epng)

***Top side*Video Design**

[Embedded media](https://www.youtube.com/embed/UnLg9psAKVI)

## Step 2 : Mechanical Assembly

The mechanical system in this Wizfloats is based on the ballast tank system used in submarines. The following are the materials that will be used in the construction of bifloats:

![](https://maker.wiznet.io/upload/ckeditor5/41556989%5F1719786422%2Epng)

1. Acrylic tube

2. Acrylic for end cap, syringe stand and stepper mounting

3. Smooth rod stainless steel 304 8mm, pcb spacer , bolt and hexnut

4. Syringe 20ml

5. Stepper motor, leadScrew T8-2-D8, Copper nut LeadScrew, Flexible coupling (all part from cnc machine)

6. Stopper speccer (make from 3d prtinter)

7. Electronic component

![](https://maker.wiznet.io/upload/ckeditor5/41556989%5F1719804462%2Ejpg)

The mechanical system in the bifloats robot mimics the style of submarine systems using a ballast tank system. Three syringes will be used as ballast tanks, which will be operated by a stepper motor. This allows the bifloat to adjust its buoyancy by adding water into the cylinder.

![](https://maker.wiznet.io/upload/ckeditor5/41556989%5F1719804494%2Ejpg)

This ballast tank system thatt will cause the Wizfloat to move up and down in the water.

**Video Assembly**

[Embedded media](https://www.youtube.com/embed/sbeGyqF33cM)

next step make a waterproof using super glue and epocxy glue

![](https://maker.wiznet.io/upload/ckeditor5/255393073%5F1719840795%2Epng)

Before casting, first, to adhere the syringe to acrylic, we will apply super glue on the syringe side. After applying the super glue and waiting for it to dry, the we add epoxy resin as a waterproof coating or sealer. I'm using epoxy from Devcon

![](https://maker.wiznet.io/upload/ckeditor5/255393073%5F1719841104%2Epng)

**Video Waterproof**

[Embedded media](https://www.youtube.com/embed/AZpde9YLuTo)

## STEP 3: Controller Design

![](https://maker.wiznet.io/upload/ckeditor5/896832938%5F1720158133%2Epng)

1. Surf5

2. DS18B20 Waterproof Temperature Sensor

3. Depth/ Pressure Sensor (ms5837 blue robotics)

4. A4988 - Stepper Motor Driver

5. On off switch (blue robotics)

6. limit switch

7. UBEC

This for Electronic schematic

![](https://maker.wiznet.io/upload/ckeditor5/250687780%5F1720397746%2Epng)

![](https://maker.wiznet.io/upload/ckeditor5/896832938%5F1720158364%2Epng)

Limitswitch Position

![](https://maker.wiznet.io/upload/ckeditor5/896832938%5F1720158434%5F1%2Ejpeg)

![](https://maker.wiznet.io/upload/ckeditor5/896832938%5F1720158656%2Epng)

## STEP 4 : PROGRAMMING

**Test stepper motor**

For test motor stepper, use code from example surf5 (projects/W7500x_StdPeriph_Examples/GPIO/GPIO_IOToggle) , stepper need 2 pin digital as dir pin and step pin. so first must be initialization

```plaintext
#define DIR_PIN  GPIO_Pin_14
#define STEP_PIN GPIO_Pin_13
```

add function GPIO_Config

```plaintext
static void GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Direction = GPIO_Direction_OUT;
    GPIO_InitStructure.GPIO_AF = PAD_AF1;
    GPIO_Init(GPIOC, &GPIO_InitStructure);


    // Configure the pins for the stepper motor control
    GPIO_InitStructure.GPIO_Pin = DIR_PIN | STEP_PIN;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
}
```

and then code in looping

```plaintext
while (1) {
        GPIO_SetBits(GPIOC, DIR_PIN);
        // Rotate stepper motor one revolution in one direction
        for(int i = 0; i < 1000; i++) {
            GPIO_SetBits(GPIOC, STEP_PIN);
            Delay(1000);  // Adjust the delay for stepper speed
            GPIO_ResetBits(GPIOC, STEP_PIN);
            Delay(1000);
        }
        Delay(800000);

        // Set direction to counterclockwise
        GPIO_ResetBits(GPIOC, DIR_PIN);

        // Rotate stepper motor one revolution in the other direction
        for(int i = 0; i < 1000; i++) {
            GPIO_SetBits(GPIOC, STEP_PIN);
            Delay(1000);  // Adjust the delay for stepper speed
            GPIO_ResetBits(GPIOC, STEP_PIN);
            Delay(1000);
        }

        Delay(800000);
        }
```

and this result after upload

[Embedded media](https://www.youtube.com/embed/Rp5hKywLv_Y)

Test stepper motor and limitswitch

and then add 2 limit switch to give maximum and minimum stepper movement,

add initialization for 2 limit switch in pin 8 and pin 9

```plaintext
#define LIMIT1_PIN GPIO_Pin_8
#define LIMIT2_PIN GPIO_Pin_9
```

add function gpio_config

```plaintext
GPIO_InitStructure.GPIO_Pin = LIMIT1_PIN | LIMIT2_PIN;
GPIO_InitStructure.GPIO_Direction = GPIO_Direction_IN;
GPIO_Init(GPIOC, &GPIO_InitStructure);
```

upload program for trial test limit switch and stepper

```plaintext
while (1) {
    	if (GPIO_ReadInputDataBit(GPIOC, LIMIT1_PIN) == Bit_RESET) {
            printf("LIMIT1 Pressed\r\n");
            GPIO_SetBits(GPIOC, DIR_PIN);  // Set direction to CW
        } 
else if (GPIO_ReadInputDataBit(GPIOC, LIMIT2_PIN) == Bit_RESET) {
            printf("LIMIT2 Pressed\r\n");
            GPIO_ResetBits(GPIOC, DIR_PIN);  // Set direction to CCW
        }


        // Step the motor
        GPIO_SetBits(GPIOC, STEP_PIN);
        Delay(1000);
        GPIO_ResetBits(GPIOC, STEP_PIN);
        Delay(1000);


    }
   
    return 0;
}
```

[Embedded media](https://www.youtube.com/embed/Fvh6wN5_xXY)

because we need wizfloat can controll with browser so, we can add 3 button in browser to controll it, add new variabel for CW and CCW movement

```plaintext
void Stepper_MoveCW(void);
void Stepper_MoveCCW(void);
```

add function stepper movement

```plaintext
volatile uint8_t stepper_state = 0; // 0: stopped, 1: CW, 2: CCW


/* Moves the stepper motor CW */
void Stepper_MoveCW(void)
{
    GPIO_SetBits(GPIOC, DIR_PIN);  // Set direction to CW


    // Generate a step pulse
    GPIO_SetBits(GPIOC, STEP_PIN);
    delay(1);  // Short delay for pulse width
    GPIO_ResetBits(GPIOC, STEP_PIN);
    delay(1);  // Short delay for pulse spacing
}


/* Moves the stepper motor CCW */
void Stepper_MoveCCW(void)
{
    GPIO_ResetBits(GPIOC, DIR_PIN);  // Set direction to CCW


    // Generate a step pulse
    GPIO_SetBits(GPIOC, STEP_PIN);
    delay(1);  // Short delay for pulse width
    GPIO_ResetBits(GPIOC, STEP_PIN);
    delay(1);  // Short delay for pulse spacing
}
```

and then call in webserver

```plaintext
int32_t WebServer(uint8_t sn, uint8_t* buf, uint16_t port)
{
     uint8_t i;
    uint8_t adcChannelOffset = 2;
    int32_t ret;
    uint16_t size = 0;
    uint8_t destip[4];
    uint16_t destport;
    uint8_t adc_buf[128] = { '\0', };


    switch (getSn_SR(sn))
    {
        case SOCK_ESTABLISHED:


            if (getSn_IR(sn) & Sn_IR_CON) {


                getSn_DIPR(sn, destip);
                destport = getSn_DPORT(sn);
                printf("%d:Connected - %d.%d.%d.%d : %d\r\n", sn, destip[0], destip[1], destip[2], destip[3], destport);


                setSn_IR(sn, Sn_IR_CON);
            }


            if ((size = getSn_RX_RSR(sn)) > 0) {
                if (size > DATA_BUF_SIZE) size = DATA_BUF_SIZE;
                ret = recv(sn, buf, size);
                if (ret <= 0) return ret;
                printf("%s", buf);


                // Check for button press
                if (strstr((char*)buf, "GET /?led=on") != NULL) {
                    // Turn on LED (or GPIO)
                    GPIO_SetBits(GPIOC, GPIO_Pin_15);
                } else if (strstr((char*)buf, "GET /?led=off") != NULL) {
                    // Turn off LED (or GPIO)
                    GPIO_ResetBits(GPIOC, GPIO_Pin_15);
                } else if (strstr((char*)buf, "GET /?stepper=cw") != NULL) {
                    // Start moving stepper motor CW
                    stepper_state = 1;
                } else if (strstr((char*)buf, "GET /?stepper=ccw") != NULL) {
                    // Start moving stepper motor CCW
                    stepper_state = 2;
                } else if (strstr((char*)buf, "GET /?stepper=stop") != NULL) {
                    // Stop moving stepper motor
                    stepper_state = 0;
                }


                // Send HTML response
                ret = send(sn, "HTTP/1.1 200 OK\r\n"
                        "Content-Type: text/html\r\n"
                        "Connection: close\r\n"
                        "\r\n"
                        "<!DOCTYPE HTML>\r\n"
                        "<html>\r\n"
                        "<body>\r\n"
                        "<h1>WIZnet Web Server</h1>\r\n"
                        "<p>Analog input values:</p>\r\n", sizeof("HTTP/1.1 200 OK\r\n"
                        "Content-Type: text/html\r\n"
                        "Connection: close\r\n"
                        "\r\n"
                        "<!DOCTYPE HTML>\r\n"
                        "<html>\r\n"
                        "<body>\r\n"
                        "<h1>WIZnet Web Server</h1>\r\n"
                        "<p>Analog input values:</p>\r\n") - 1);
                if (ret < 0) {
                    close(sn);
                    return ret;
                }


                for (i = 0; i < 4; i++) {
                    ADC_Cmd(ENABLE);
                    if(i >= 2) adcChannelOffset = 4;
                    else if (i < 2) adcChannelOffset = 2;
                    ADC_ChannelConfig(i+adcChannelOffset);
                    ADC_StartOfConversion();
                    sprintf(adc_buf, "analog input %d is %d<br />\r\n", i+adcChannelOffset, ADC_GetConversionValue());
                    ret = send(sn, adc_buf, strlen(adc_buf));
                    if (ret < 0) {
                        close(sn);
                        return ret;
                    }
                    ADC_Cmd(DISABLE);
                    memset(adc_buf, '\0', 128);
                }


                // Add buttons to the HTML
                ret = send(sn, "<br /><button onclick=\"location.href='/?led=on'\">Turn LED On</button>\r\n", strlen("<br /><button onclick=\"location.href='/?led=on'\">Turn LED On</button>\r\n"));
                if (ret < 0) {
                    close(sn);
                    return ret;
                }
                ret = send(sn, "<button onclick=\"location.href='/?led=off'\">Turn LED Off</button>\r\n", strlen("<button onclick=\"location.href='/?led=off'\">Turn LED Off</button>\r\n"));
                if (ret < 0) {
                    close(sn);
                    return ret;
                }
                ret = send(sn, "<br /><button onclick=\"location.href='/?stepper=cw'\">Move Stepper CW</button>\r\n", strlen("<br /><button onclick=\"location.href='/?stepper=cw'\">Move Stepper CW</button>\r\n"));
                if (ret < 0) {
                    close(sn);
                    return ret;
                }
                ret = send(sn, "<button onclick=\"location.href='/?stepper=ccw'\">Move Stepper CCW</button>\r\n", strlen("<button onclick=\"location.href='/?stepper=ccw'\">Move Stepper CCW</button>\r\n"));
                if (ret < 0) {
                    close(sn);
                    return ret;
                }
                ret = send(sn, "<button onclick=\"location.href='/?stepper=stop'\">Stop Stepper</button>\r\n", strlen("<button onclick=\"location.href='/?stepper=stop'\">Stop Stepper</button>\r\n"));
                if (ret < 0) {
                    close(sn);
                    return ret;
                }


                ret = send(sn, "</body></html>\r\n", sizeof("</body></html>\r\n") - 1);
                if (ret < 0) {
                    close(sn);
                    return ret;
                }


                disconnect(sn);
            }


            break;
        case SOCK_CLOSE_WAIT:


            if ((ret = disconnect(sn)) != SOCK_OK) return ret;


            printf("%d:Socket Closed\r\n", sn);


            break;
        case SOCK_INIT:


            printf("%d:Listen, Web server, port [%d]\r\n", sn, port);


            if ((ret = listen(sn)) != SOCK_OK) return ret;


            break;
        case SOCK_CLOSED:


            if ((ret = socket(sn, Sn_MR_TCP, port, 0x00)) != sn) return ret;


            break;
        default:
            break;
    }


    // Check the stepper state and move accordingly
    switch (stepper_state)
    {
        case 1:
            Stepper_MoveCW();
            break;
        case 2:
            Stepper_MoveCCW();
            break;
        default:
            break;
    }


    return 1;
}
```

edit gui for display ground controller

```plaintext
ret = send(sn, "HTTP/1.1 200 OK\r\n"
                                "Content-Type: text/html\r\n"
                                "Connection: close\r\n"
                                "\r\n"
                                "<!DOCTYPE HTML>\r\n"
                                "<html>\r\n"
                                "<head>\r\n"
                                "<style>\r\n"
                                "body { font-family: Arial, sans-serif; background: linear-gradient(to right, #8e2de2, #4a00e0); display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; }\r\n"
                                ".container { background-color: white; border-radius: 15px; padding: 30px; display: flex; box-shadow: 0 0 20px rgba(0, 0, 0, 0.1); }\r\n"
                                ".left-section { margin-right: 20px; }\r\n"
                                ".right-section { display: flex; flex-direction: column; justify-content: center; }\r\n"
                                "h1 { color: #333; margin-bottom: 20px; }\r\n"
                                ".data { background-color: #f2f2f2; padding: 10px; border-radius: 10px; margin: 10px 0; display: inline-block; width: 100%; text-align: center; }\r\n"
                                ".button { background-color: #4CAF50; color: white; padding: 15px; border: none; border-radius: 10px; cursor: pointer; margin: 10px 0; width: 100%; text-align: center; }\r\n"
                                ".button:hover { background-color: #45a049; }\r\n"
                                "</style>\r\n"
                                "</head>\r\n"
                                "<body>\r\n"
                                "<div class='container'>\r\n"
                                
                                "<div class='right-section'>\r\n"
                                "<h1>WIZFLOAT</h1>\r\n"
                                "<div class='data'><strong>Temperature</strong><p>30 C</p></div>\r\n"
                                "<div class='data'><strong>Depth</strong><p>1.2 Meters</p></div>\r\n"
                                "</body>\r\n"
                                "</html>\r\n", sizeof("HTTP/1.1 200 OK\r\n"
                                "Content-Type: text/html\r\n"
                                "Connection: close\r\n"
                                "\r\n"
                                "<!DOCTYPE HTML>\r\n"
                                "<html>\r\n"
                                "<head>\r\n"
                                "<style>\r\n"
                                "body { font-family: Arial, sans-serif; background: linear-gradient(to right, #8e2de2, #4a00e0); display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; }\r\n"
                                ".container { background-color: white; border-radius: 15px; padding: 30px; display: flex; box-shadow: 0 0 20px rgba(0, 0, 0, 0.1); width:50%;}\r\n"
                                ".left-section { margin-right: 20px; }\r\n"
                                ".right-section { display: flex; flex-direction: column; justify-content: center; }\r\n"
                                "h1 { color: #333; margin-bottom: 20px; }\r\n"
                                ".data { background-color: #f2f2f2; padding: 10px; border-radius: 10px; margin: 10px 0; display: inline-block; width: 100%; text-align: center; }\r\n"
                                ".button { background-color: #4CAF50; color: white; padding: 15px; border: none; border-radius: 10px; cursor: pointer; margin: 10px 0; width: 100%; text-align: center; }\r\n"
                                ".button:hover { background-color: #45a049; }\r\n"
                                "</style>\r\n"
                                "</head>\r\n"
                                "<body>\r\n"
                                "<div class='container'>\r\n"
                                
                                "<div class='right-section'>\r\n"
                                "<h1>WIZFLOAT</h1>\r\n"
                                "<div class='data'><strong>Temperature</strong><p>30 C</p></div>\r\n"
                                "<div class='data'><strong>Depth</strong><p>1.2 Meters</p></div>\r\n"
                                "</body>\r\n"
                                "</html>\r\n") - 1);
```

this result for gui grond controller

![](https://maker.wiznet.io/upload/ckeditor5/250688684%5F1720379031%2EJPG)

after program run, then assemble in syrnge and test stepper motor and limitswitch in hardware

[Embedded media](https://www.youtube.com/embed/Clk3FaimTPw)

Final test Bifloats

[Embedded media](https://www.youtube.com/embed/boG8SdnuSNU)

GUI for Bifloats

[Embedded media](https://www.youtube.com/embed/b2FUo1gIsc0)

---

Source: https://maker.wiznet.io/Tri_kiting/contest/wizfloats/
