Sybian diagram

Full guide - OSV V1

2023.10.20 00:51 stumro Full guide - OSV V1

Full guide - OSV V1
Edit: I'll update this as I find issues. But this reached the character limit of Reddit for a post. Also - turns out you can only have one image in a comment. I'll work out how to do this better in future. I've removed some of my earlier guide posts (as it's incorporated here), though left later ones up that had images.
This is a combination of prior posts I made along the way while building. I'm working on a V2 (without the Arduino Nano), and I've been talking to Jands87 about other improvements to make for future revisions. The V1 is based of the design and info from u/jands87 posted here: https://diy-toys.boards.net/thread/2/3d-printed-saddle and the .STL from here: https://www.thingiverse.com/thing:3554455/files - From Jands87.
Here is the GitHub repository made by Jands too: https://github.com/Jands87/OpenSaddleVibrator
I've complied this as a way so people can find what they need in a fairly systematic way to get the finished product, and avoid the mistakes I made along the way.
Please - read the whole guide (or at least the steps and look at the pictures).
Related videos:
Much of this project does rely on you using your own initiative. I won't go into detail for some bits which I found to be design as you go (such as the saddle shell), but use the tools available to you. I'm not actively using this code, so you may need to rely on the GitHub depository and your ability to use ChatGPT and asking the right questions on the sub here.
I like the look of this for the control box, but I don't have the .STL files. Please comment if you have it / find it.
The image for this sub.
To begin with, it's probably best to order all the component pieces (excluding the shell). You may want to break this down into electrical, then the build bits, like the bearings and such. You'll also need a bunch of tools to get this done too.
General tools required for the build overall:
  • FDM 3D Printer (I have the Ender 3 v2)
  • Cura on your PC (or another slicer)
  • Arduino IDE
  • Soldering iron
  • Heat gun
  • Crimpers - something like this will work https://www.jaycar.co.nz/automotive-crimp-tool-with-connectors/p/TH1848
  • Solder
  • Flux
  • Wire strippers - get some half decent at least - https://www.jaycar.co.nz/wire-strippep/TH1824
  • Digital multimeter
  • Solder mask and wick (optional)
  • Wire shrink wrap
  • Spare wire
  • Flush cutters
  • Drill / drill bits and bolt/screw bits
  • Phillips and flat head screwdrivers
  • Hex / Allen keys
  • A ratcheting socket set is useful
  • Safety gear (ear muffs, safety glasses, gloves) for using a grinder
  • Glue stick (to attach paper to metal as a template)
  • Grinder with cutting and polishing disks
  • See blow for general tools used for the saddle enclosure.

Control Box, connector cable and the UNO
Items required for this step:
With the OSV V1 it uses the I2C protocol to communicate between the Arduino Uno and Nano. Less resistance (shorter cable) is better. I've found the max is ~1.5 m. This is why the OSV V2 is happening.
There's effectively 2 options I'll talk about for the cable between the control box and the saddle. Option A is for an ethernet cable (preferred). Option B is to make a mic cable.
Option A - there's .STL files for the control box to fit a standard connector into, and you can get a round passthrough for going on the saddle. It's the preferred method as you don't have to make the cable (it's off the shelf), relatively cheap / fast to implement, lowers the bar of entry for most people, and most people will have a spare cable about in a drawer.
Option B - There's a .STL file for a mic connector. You'll need to get the right connectors and make a cable. This option exists if you want to make more things. If you want to be able to make OSV V2, you'll want at least 6 cores in your cable.
Steps:
  1. Print this control box to fit the ethernet connector: https://www.thingiverse.com/thing:5595029. If you aren't happy with the print quality or colour - reprint. Filament is cheap. The control box is ~$2 of filament. Printing slow, fine and detailed takes ~15 hours or so. You do you, but it's hard to replace it later. Note: currently I need to update the control box lid to be slightly better for the POTs (it's like 0.5 mm too small).
  2. Insert the ethernet passthrough connector.
  3. Load this code (below) to the Arduino Nano with Arduino IDE.
  4. "Dry run" fit everything together into the control box and plan how you are doing this.
  5. Start to solder things to their appropriate places following the diagram below. Use shrink tubes on wire-wire joins. Personally, I stripped wire and wrapped it through / around the end of components, then soldered. For the Nano board, solder the bottom of the board with the wires through it, then use flush cutters to trim. Personally, I did it in this order:
    1. Cut your shorter ethernet cable. Leave about 10 cm from the connector. Remove the outer plastic casing and any shielding. It's easier to use longer than necessary wires than shorter ones..
    2. Create and cut wiring as per diagram.
    3. Solder these into the Adriano Nano.
    4. Insert buttons into the control box and screw the backs to them. Connect the wires and solder them in. The wires here can be relatively short (as it doesn't matter if you need to open the control box).
    5. Strip and connect wires to the potentiometers as per diagram. These should be slightly longer for if you need to open the control box and update the Nano's code.
  6. Test for continuity / shorts with a Digital Multimeter.
  7. Insert the 4x M3 x 10mm bolts / screws to secure the lid to the box.
  8. Be satisfied with the control box you've made and connect it to the control box cable
  9. Load the code further below to the Arduino UNO R4 using Arduino IDE.
  10. Strip back 5 cm or so of the cut ethernet cable. Now we are going to solder these to the ends of breadboard cables, so we can plug the male ends into the UNO. By using an ethernet cable you'll have 4 extra cables here. OSV V2 will have 2 extra.
  11. Attach in accordance with the wiring diagram above.
Wiring the Uno to the Nano.
Nano code:
// Master code for Arduino Nano for the Saddle Vibrator by Jands87 // https://www.thingiverse.com/thing:3554455 // Modified based off the code from Jands87 // Dated 27/09/2023 #include  const int pot0 = A0; // pin designation for pot 0 const int pot1 = A1; // pin designation for pot 1 const int butt0 = 2; // pin designation for button 0 const int butt1 = 3; // pin designation for button 1 const int LED = 13; // LED showing debugging mode byte motor0; byte motor1; byte button0; byte button1; byte debugflag; void setup() { Wire.begin(8); // join i2c bus with address #8 Wire.onRequest(requestEvent); // register event Serial.begin(9600); // set serial communication baud to 9600 Serial.println("Slave - controller"); // print on screen position of board (i.e is the slave board) if (Serial.available() > 0) { // Nano is receiving data from the Uno (connected) Serial.println("Connected to Uno"); } else { // Nano is not receiving data from the Uno (disconnected) Serial.println("Not connected to Uno"); } pinMode(butt0, INPUT_PULLUP); // set both inputs to internal pull ups pinMode(butt1, INPUT_PULLUP); } void loop() { // Read the state of button 0 and button 1 int button0State = digitalRead(butt0); int button1State = digitalRead(butt1); // Read the values of potentiometer 0 and map it to a motor speed range (0-255) int pot0Value = analogRead(pot0); int motor0Speed = map(pot0Value, 0, 1023, 0, 255); // Read the values of potentiometer 1 and map it to a motor speed range (0-255) int pot1Value = analogRead(pot1); int motor1Speed = map(pot1Value, 0, 1023, 0, 255); // Print the states and values on one line Serial.print("Button 0 State: "); Serial.print(button0State); Serial.print(" Button 1 State: "); Serial.print(button1State); Serial.print(" Potentiometer 0 Value: "); Serial.print(pot0Value); Serial.print(" Motor 0 Speed: "); Serial.print(motor0Speed); Serial.print(" Potentiometer 1 Value: "); Serial.print(pot1Value); Serial.print(" Motor 1 Speed: "); Serial.println(motor1Speed); { if (Serial.available() > 0) { // Data is received from the Uno (connected) Serial.println("Connected to Uno"); } else { // No data received from the Uno (disconnected) Serial.println("Not connected to Uno"); } // Delay to prevent reading too frequently delay(10000); // You can adjust this delay depending on your requirements } motor0 = map(analogRead(pot0), 0, 1023, 0, 255); // map will return byte size data delay(10); motor1 = map(analogRead(pot1), 0, 1023, 0, 255); button0 = !digitalRead(butt0); // read in button status and invert button1 = !digitalRead(butt1); delay(100); // 0.1-sec interval as a test interval if ((digitalRead(butt0) == 0) && (digitalRead(butt1) == 0)) { // enter debug mode if both buttons pressed when powered on if (debugflag == 0) { debugflag = 1; digitalWrite(LED, HIGH); button0 = 0; button1 = 0; delay(1000); } else { debugflag = 0; digitalWrite(LED, LOW); button0 = 0; button1 = 0; delay(1000); } } } void requestEvent() { Wire.write(motor0); // data item-1 as ASCII codes Wire.write(motor1); // data item-2 as ASCII codes Wire.write(button0); // data item-3 as ASCII codes Wire.write(button1); // data item-3 as ASCII codes Wire.write(debugflag); // data item-3 as ASCII codes if (debugflag == 1) { Serial.print(motor0); // data item-1 as ASCII codes Serial.print(","); // local separator Serial.print(motor1); // data item-2 as ASCII codes Serial.print(","); // local separator Serial.print(button0); // data item-3 as ASCII codes Serial.print(","); // local separator Serial.print(button1); // data item-3 as ASCII codes Serial.print(","); // local separator Serial.println(debugflag); // display debug status } } 
UNO code:
// Master code for Arduino Uno for the Saddle Vibrator by Jands87 // https://www.thingiverse.com/thing:3554455 // Modified based off the code from Jands87 // Dated 27/09/2023 #include  byte inData[10]; // incoming data array for data from controller (make larger than you need) const int motor0 = 6; // pin designation for motor 0 const int motor1 = 9; // pin designation for motor 1 const int LED = 13; // LED showing debugging mode const int IN1 = 5; // Motor 0 direction control 1 const int IN2 = 4; // Motor 0 direction control 2 const int IN3 = 8; // Motor 1 direction control 1 const int IN4 = 7; // Motor 1 direction control 2 bool button0 = 0; // internal variables for button 0 on controller bool button1 = 0; bool button1flag = 0; // check flag to see if button is being held down, debounce bool rampmode = 0; // flag for ramping mode on motor 0 bool flag = 0; // dead man switch for connection, stop motors if no data bool debugflag = 0; // set 1 for debugflag mode to print serial updates void setup() { pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT); pinMode(IN3, OUTPUT); pinMode(IN4, OUTPUT); // Set all motor control pins HIGH to enable floating digitalWrite(IN1, HIGH); digitalWrite(IN2, HIGH); digitalWrite(IN3, HIGH); digitalWrite(IN4, HIGH); delay(1000); // allow time fro controller to start first Wire.begin(); // join i2c bus (address optional for master) Serial.begin(9600); // set serial baud to 9600 } void loop() { flag = 0; // set connection flag to off to show data to stop motors if no data arrives Wire.requestFrom(8, 5); // request 5 bytes from slave device #8 while (Wire.available()) { for (int i = 0; i <= 4; i++) { inData[i] = Wire.read() - '0'; // read 1 byte from the wire buffer in to "inData[i]" -'0' is to convert back to int from char } button0 = inData[2]; // check to see if any buttons have been presed button1 = inData[3]; if (inData [4] == 1){ debugflag = 1; // enter debug mode digitalWrite(LED, HIGH); // LED showing debugging mode, HIGH); } else { debugflag = 0; // exit debug mode digitalWrite(LED, LOW); // LED showing debugging mode, HIGH); } flag = 1; // set connection flag to on to show data has arrived. } if (flag == 0) { // dead man (no connection) switch to stop motors for (int i = inData[0]; i == 0; i--) { // decrease motor 0 and 1 speeds until stopped analogWrite(motor0, 0); delay(10); } digitalWrite(IN1, HIGH); digitalWrite(IN2, HIGH); for (int i = inData[1]; i == 0; i--) { analogWrite(motor1, 0); delay(10); } digitalWrite(IN3, HIGH); digitalWrite(IN4, HIGH); } if (flag == 1) { // only continue if controller is connected (dead man switch check) // ***************** BUTTON 0 ROUTINES ***************** if (button0 == 1) { // process button routine if button 0 has been pressed button0press(); } // ***************** BUTTON 1 ROUTINES ***************** if (button1 == 1) { button1flag = 1; // set button flag to make sure it does not continuously run the routine (debounce) } if ((button1 == 0) && (button1flag == 1)) { // if button has been released reset button 0 flag and process routine button1flag = 0; if (rampmode == 0) { button1press(); } else if (rampmode == 1) { rampmode = 0; } } // ****************** MOTOR ROUTINES ****************** if ((button0 == 0) && (button1 == 0)) { // no buttons have been pressed - set motor speed if (rampmode == 1) { inData[0] = 255; } digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW); analogWrite(motor0, inData[0]); // PWM to output motor 0 port delay(10); digitalWrite(IN3, HIGH); digitalWrite(IN4, LOW); analogWrite(motor1, inData[1]); // PWM to output motor 1 port } } if (debugflag == 1) { showSerial(); delay(1000); } else if (debugflag == 0) { delay(100); } } void button0press() { // button 0 has been pressed inData[0] = 255; // set motor 0 speed to 100% analogWrite(motor0, inData[0]); // PWM to output motor 0 port } void button1press() { // button 1 button has been pressed rampmode = 1; for (int i = inData[0]; i <= 255; i++) { // slowly ramp motor speed to 100% Serial.print(i); Serial.println("."); analogWrite(motor0, i); delay(10); } Serial.println(); } void showSerial() { Serial.print("Masterboard Status: "); if (flag == 0) { // dead man (no connection) switch to stop motors Serial.println("Controller disconnected. (Debugging)"); } else if (flag == 1) { Serial.println("Controller connected. (Debugging)"); } Serial.print("Motor 0:"); Serial.print(inData[0]); Serial.print(" / "); Serial.print("Motor 1:"); Serial.print(inData[1]); Serial.print(" / "); Serial.print("Button 0:"); Serial.print(button0); Serial.print(" / "); Serial.print("Button 1:"); Serial.print(button1); Serial.print(" / "); Serial.print("Button 1 Flag:"); Serial.print(button1flag); Serial.print(" / "); Serial.print("Ramp Mode:"); Serial.print(rampmode); Serial.println(); Serial.println(); } 

More electrical
Note: This is one of the steps that I'm hoping to change. There's a bit of safety risk with this design, so an external adaptor (rather than internal) is being looked into soon. This will again lower the bar of entry for people, as it'll be an off the shelf component to use, but also increase the safety factor. Below is what I've done so far on the OSV V1.
You will need:
Steps:
  1. Put the fuse, and spare fuse, into the IEC Fuse Chassis Male Power Plug with Switch.
  2. Follow the instructions here on how to wire the IEC Fuse Chassis Male Power Plug with Switch: https://www.instructables.com/Wire-Up-a-Fused-AC-Male-Power-Socket/
  3. With the other end of the wire, strip an appropriate amount of casing, then strip each individual wire. Crimp the Forked Spade - Red - 4.1 mm to each wire end.
  4. Attach this to the PSU.
  5. Print the appropriate one of these to hold the PWM: https://www.thingiverse.com/thing:6228257 or https://www.thingiverse.com/thing:4877230/files
  6. Prepare 3 sections of maybe 20 cm (less if you want better cable managements and such) of mains 3 core wire to go between each of the components.
  7. On the end of one of these sections, crimp the black / red wires with the forked spade ends. This will later connect to the PSU. Connect the other end to green plug on the PWM controller by screwing it in. You can optionally include a fuse here too.
  8. Connect the two motors to the separate connectors. You'll need to screw these in also. You can optionally include a fuse here for each motor too.
  9. You can optionally include the diode between +/- of the brushed motors. When an electric motor is running by means of external power and that power is removed, it starts acting like a generator. This will prevent these issues.
  10. With these components connected, you should be able to connect the power cable with crimped fork spade ends to the PSU
  11. Use the wiring diagram below to connect the Arduino Uno to the XC-4492 (or the XY-160D if using).
  12. Test the device now if you want to jump the gun or wait to print the casing and holding for everything (bar the actual saddle) so nothing flies away. If you've done everything right, there hopefully isn't any issues. In theory, this is all the electrical work that needs to be done. However, you can install a USB passthrough (I did) so you can change code on the Arduino Uno without dismantling the device.
  13. When you are happy with everything, then put final touches on stuff so it won't break in operation. Hot glue, solder mask, zip ties, insulation tape, etc. Use things to secure connections and ensure they are durable. This step is repeated further on when assembling the device properly.
Using XC-4492 for motor controller
Using XY-160D for motor controller
Internal metal plates
Making the metal plates (vibration and base plate)
You will need to print out the templates in a 1:1 scale.
Vibration plate
Base plate
submitted by stumro to OpenSaddleVibrator [link] [comments]


http://swiebodzin.info