Notifications
Clear all

REVISIT: Using SD Cards with Arduino - Record Servo Motor Movements

58 Posts
6 Users
7 Likes
3,786 Views
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6662
 

@will Yes that's what they said, but just create a sketch with the movements and done, no need to record and playback. Am I missing something?

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
Will
 Will
(@will)
Member
Joined: 3 years ago
Posts: 2504
 

@zander 

But then they'd need to enter the positions manually and, worse, make them into a program. This way the need only twiddle knobs.

Anything seems possible when you don't know what you're talking about.


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6662
 

@will Ok, I guess I am misunderstanding so I will go away and do something else now.

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
Will
 Will
(@will)
Member
Joined: 3 years ago
Posts: 2504
 

@zander 

I don't think you're misunderstanding the point of the sketches, just the motivation. Your way is certainly a valid and effective way of recording data for animatronics.

But, I'm reading between the lines here, this is not a serious attempt to create a perfectly efficient mechanism for preserving and executing animatronics. It's more like a Dad who wants to get his daughters more involved with some STEM subjects without it being boring or forced.

So, they started this project which carries them along, step by step, improving on what they have and then moving on to the next hurdle, stumbling block, all the while being a learning tool that isn't even noticed as being educational.

So, hinobot is probably more interested in building on the base that the family has already built than starting over on a project they're not going to learn anything from.

Again, I'm just guessing at everybody's real motives 🙂

 

Anything seems possible when you don't know what you're talking about.


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6662
 

@will Ok, I checked the original sketch from Bill. If they want to enlarge that to 3 or 4, isn't that a  good place to use a class? (can't believe I just said that)

They will also need to keep a millis running and insert the time before each write then use that time when reading to delay that many millis in order to get the same timing.

If it was me with my suspenders and belt, I would write some sort of special marker to key on probably before the tie stamp, or around it, just thinking out loud. In the old days a record mark and group mark. I am really showing my age.

I will leave @will to to sort this out, I have some 'must complete' chores due and even hired help so I have to prep for that and him.

Maybe Will will toy with the idea of some animatronic magic by way of some sensors (IR?) that alter the behaviour of the device, after all I think they mentioned halloween.

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6662
 

@will @hinobot Make sure to use only 'High Endurance' cards. This kind of application will be very hard on the card. Here is the Canadian Amazon link to a 32GB card, you probably don't need any bigger https://amz.run/5p03 Just in case that link messes up "https://amz.run/5p03"

Just change the link .ca to whatever your country uses, in the USA it's .com

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
HinoBot
(@hinobot)
Member
Joined: 2 years ago
Posts: 6
Topic starter  

@will Yes, that is correct.  I don't have any attachment to the code posted.  The original code posted by DroneBot Workshop 2019 works perfect for my needs, one to record, the other to play back.  Its just fine, I just need to add the ability to capture 4 pots and 4 servos, and play them back at the same rate recorded.  Any line of code, or modification of the code above, or the original I just attached, would work for us.

ORIGINAL RECORD CODE
/*
  Servo position recorder
  servo-record.ino
  Records servo movements on SD card
  Displays results on Serial Monitor
  DroneBot Workshop 2019
   https://dronebotworkshop.com 
*/

// Include libraries

#include <SPI.h>
#include <SD.h>
#include <Servo.h>

// CS pin for SD Card Module
const int chipSelect = 4;
// Analog pin for potentiometer
int analogPin = 0;
// Integer to hold potentiometer value
int val = 0;

// Create a Servo object
Servo myservo;

void setup() {

  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }


  Serial.print("Initializing SD card...");

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1);
  }
  Serial.println("card initialized.");
  
  // Attach servo on pin 9 to the servo object
  myservo.attach(9);  
}

void loop() {
  // make a string for assembling the data to log:
  String dataString = "";

  // Read pot value and append to the string
  // Map to range of 0-180 for servo
    val = map(analogRead(analogPin), 0, 1023, 0, 180);
    dataString += String(val);
    
  // Write to the servo
  // Delay to allow servo to settle in position
  myservo.write(val);
  delay(15);
  

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("servopos.txt", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port too:
    Serial.println(dataString);
  }
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening servopos.txt");
  }
}

@zander I added the SD card so i can maybe run the servos for an extended period of time, it was my understanding the memory on an Arduino is minimal.  Since we are starting out, we just figured the SD card would eliminate that issue.


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6662
 

@hinobot Oh you definitely need the SD card, just make sure it's a 'High Endurance' card.

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6662
 

@hinobot @will If you want it to run longer even indefinitely, then maybe just record a meaningful stretch (5, 10, 15, ??? mins) then repeat the whole thing. I don't know how much of a delay a close file/open file will impose, but I doubt it will be noticeable.

In version 2 introduce a random factor using time of day as a seed to a random number generator that adds some amount of variable more pot movement or whatever into the scene.

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 5 years ago
Posts: 2037
 

@hinobot 

You have inspired me to order an SD card adapter for the Arduino to play around with myself. Hopefully I will get it before next weekend. It is easier to write code or even be motivated to work on code problems when you have the hardware to test it all. Are you willing to perhaps attach an image of your printed 3d work?  I don't have a 3d printer myself so that part I can't do.

 


   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 5 years ago
Posts: 2037
 

@hinobot 

If you want to control many servos you might consider buying this 16 CHANNEL 12-BIT PWM SERVO MOTOR DRIVER MODULE PCA9685 FOR ARDUINO PROJECTS. I did buy one some time ago but haven't got around to using it.

TA0298

 


   
ReplyQuote
Inq
 Inq
(@inq)
Member
Joined: 2 years ago
Posts: 1900
 
Posted by: @hinobot

@inq Thank you, this was our first post, I'll get it right the next time.  The reason I am using the two (2) separate codes is because we don't know any better 😆. 

No worries at all!  Everyone does it on new forums.  Using two separate codes makes sense, especially as a teaching tool for your daughters.  And even... later, having one rig for recording and just putting it on various animatronics still makes a lot of sense.  Or later, you may learn to make it into a library that just gets added to every project and is ready for recording at any time even when the primary goal is to scare the local children at Halloween!  🤣

Posted by: @hinobot

We attached a sketch of the setup.

4 servos

 

OUTSTANDING!  Beats the heck out of anything I've seen on the forum!  Especially by me.  😉 Mine look like wiring diagrams that look like my actual boards...

PigSty

Keep up the great work.  Your girls will rocket to the top of any high-tech company.

VBR,

Inq

P.S. - I won't comment on anything technical as I'm sure my brethren have already beat me to it.  I get my Internet via smoke signals on some days while the Indian reservation three miles away gets fiber and Gigabit.  Our tax dollars at work!

 

3 lines of code = InqPortal = Complete IoT, App, Web Server w/ GUI Admin Client, WiFi Manager, Drag & Drop File Manager, OTA, Performance Metrics, Web Socket Comms, Easy App API, All running on ESP8266...
Even usable on ESP-01S - Quickest Start Guide


   
ReplyQuote
Inq
 Inq
(@inq)
Member
Joined: 2 years ago
Posts: 1900
 

@hinobot - Ok, I've read through the rest of the thread.  It sounds like you have some good skills already.  I have not looked at your code YET, but I believe that it is always best to teach concepts, not "place this line of code here."  That if you understand the concepts you can catch fish forever.  🤣 I tend to overdo it with obscure metaphors sometimes.  You just have to ignore them.

Why don't I start out at the top of a process flow that might address your two issues:  Only seeming to get one servo to work and it doesn't play back in human time well.  You have most of the mechanics available already, let's just see if this gets you on a good track. 

Remember there are hundreds of ways to tackle a problem and I'm sure others will suggest different schemes.  For instance in an industrial sense, it's all about being AT a specific position AT a specific time.  I suggest for an Animatronics type scenario it should be handled more like film... recording what the current position is at a PERIODIC time.  If you agree that this sounds like a good strategy for you and have a problem on how to implement a step, just let us know.  I'm sure most people here will get you an answer long before I can even receive your post. 

Recording

  1. You've said you can control all the servos in real time and you want to record and playback in that same real time.  You must be far more dexterous than I.  I would love to see you performing this slight of hand in a video.
  2. Set up a recurring event.  I would suggest starting out using a 1 second interval while developing and you can later go back and change it to something like 1/15th of a second (film) or even 1/60th of a second for video.  Just starting out, you would normally do this in the loop() method by adding a delay(1000); statement.  You will not be able to do here as your code has to run to handle your input from the pots and control the servos.
  3. When this interval fires, gather three pieces of information for EACH servo.  
    1. a servo ID... say... 1, 2, 3, etc.
    2. that servo's position -90 to 90.
    3. the time since starting - You would use the current value returned from millis(); but subtract from it, a stored variable that contains the millis(); you got when you pressed the record button.
  4. Store those three pieces of information for each servo at each interval.  As a side note, it sounds like for your eyes scenario, the recording will not be that long and not use that much data.  I would bet it could easily be stored in the EEPROM area and save you the complexity and cost of having the SD card.   However, it is a good learning case and you could always learn to use it on your Animatronic Cat project. 😉 

Playback

  1. Read in the first three values (servo ID, servo position, timestamp).  This will be called your current move.
  2. When the replay button is pressed a start time is taken (millis();)
  3. In the loop read the current millis() and subtract the start time
  4. If the difference is less than the timestamp of the current move, don't make a move yet.
  5. If it is greater,
    1. make that current servo move to the current position in the current move.
    2. read in the next current move.
  6. This should play back the steps at the same relative time.
  7. If you want to run it continuously (eye project) simple rewind the file and set a new start time.

I hope this makes sense, and if it doesn't let me know where you get bogged down.  That is... if you even want to do it this way.

VBR,

Inq

3 lines of code = InqPortal = Complete IoT, App, Web Server w/ GUI Admin Client, WiFi Manager, Drag & Drop File Manager, OTA, Performance Metrics, Web Socket Comms, Easy App API, All running on ESP8266...
Even usable on ESP-01S - Quickest Start Guide


   
ReplyQuote
Will
 Will
(@will)
Member
Joined: 3 years ago
Posts: 2504
 

@inq @hinobot

I agree with breaking time into standard slices, but I would suggest that it would be better to do it for the array of pots instead of individually. That is, send a time duration and a list of servo positions instead of a time duration, a servo ID and a single servo value.

The reason is that you'll want to make the target object operate as if some of its parts are connected and that illusion will be difficult to create unless the servos are tied together in time as well.

So, instead of sending individual data points, you're sending (effectively) a snapshot of the locations of all the servos at the same time.

Note that the "tick" rate at which the lines are decoded and displayed will depend only on the playback cycle. It may take some experimentation to decide how far any servo can change per "tick" and how long it takes to execute the longest instruction line.

Note also that this will require you to dedicate another key (or button) to indicate that the current set of pot positions is deemed correct and that their positions should be collected, interpreted and stored. The servos on the input side should immediately be set to the new position indicated by the pot (i.e. the servo immediately moves to the current pot setting).

After the pots (and servos) are correctly placed, press the button (or key) to take a snapshot of all values and store them.

Anything seems possible when you don't know what you're talking about.


   
ReplyQuote
Inq
 Inq
(@inq)
Member
Joined: 2 years ago
Posts: 1900
 

@Will - That way would work just as well.  Although all the steps do not happen at the same time, I'd imagine the differences would be negligible.  The differences are in how you like to program.  The way you suggest is a more C/Procedural way.  The file storage would be smaller using that technique.  Only one timestamp for many servos.  The way I propose is a more C++/Object Oriented way of doing it.  I suggest the C++ way because:

  1. I'm assuming the data is read off a file.  The format of the file will ALWAYS be the same:
    1. 4 bytes integer (u32) for timestamp
    2. 1 byte signed integer (s8) for the servo pin
    3. 1 byte signed integer (s8) for the angle
  2. Say... in the future they want to do a full Animatronic beast.  A second eye, move head, stick out tongue.  They could go from four servos to dozens by simply sorting the timestamps.  Using an array of servos, they'd have to script everything over OR they have to write some other program to tear apart the file and integrate into some integrated conglomerate file.  What if some phases of the script only mess with 4 servos, while another works 200.  Doing an array approach makes that difficult.  Doing it as a read current position, do current position when the time arrives, read the next position... is very simple to say and very simple to implement.
  3. I'd just wrap it up in a simple C++ class for one servo.  From then on you simply add servos to your heart's delight and no changes to file format or to the main sketch's logic.

But as I mentioned... there are as many opinions here as there are people.  It is totally what makes the most sense to @hinobot and his daughters.  Some people think procedurally.  Fewer people (I have to admit) thing Object Oriented.

3 lines of code = InqPortal = Complete IoT, App, Web Server w/ GUI Admin Client, WiFi Manager, Drag & Drop File Manager, OTA, Performance Metrics, Web Socket Comms, Easy App API, All running on ESP8266...
Even usable on ESP-01S - Quickest Start Guide


   
ReplyQuote
Page 2 / 4