Pages: [1]   Go Down
Author Topic: Motorshield and electromagnet ?  (Read 1256 times)
0 Members and 1 Guest are viewing this topic.
Germany
Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi ,
i have a rc-car with a magnetic steering (+volts right, -volts left) which i'm controling it with a L298P Motorshield.
The only Problem is that the steering kinda vibrates an won't really move.
So my question is, how can i make the motor shield working with this electromagnet ?
Or could PLL-mode on this shield (for three-phase-motors) control it ?
Before i do anything maybe dangerous for the circuits, i want to ask someone with more experience smiley
« Last Edit: February 14, 2011, 11:31:50 am by kuno86 » Logged

New Hampshire
Offline Offline
God Member
*****
Karma: 17
Posts: 781
There are 10 kinds of people, those who know binary, and those who don't.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

What is the code you're using to control the motorshield?  You don't want to PWM the motor driver for an electromagnet steering mechanism.  Either drive it full on one direction, full on the other direction, or full off.  If you PWM the signal, that will cause the electromagnet to vibrate.
Logged


Germany
Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thats the code:
Code:
#include <SPI.h>
#include <Ethernet.h>
#include <Udp.h>


byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 10, 56, 35, 178 };
byte gateway[] = { 10, 56, 35, 1 };
byte subnet[] = { 255, 255, 255, 0 };

#define MAX_SIZE 32 // maximum packet size
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet
byte remoteIp[4]; // holds recvieved packet's originating IP
unsigned int remotePort; // holds received packet's originating port

const int ledPin = 13;

int E1 = 5;
int M1 = 4;
int E2 = 6;
int M2 = 7;


void setup() {
  Ethernet.begin(mac, ip , gateway, subnet);
  Udp.begin(9100);
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(M1,OUTPUT);
  pinMode(M2,OUTPUT);
}

void loop() {
  int packetSize=Udp.available();  // holds received packet size
  int DriveSpeed = 0;
  boolean SteuerFehler;
  if(packetSize)
    {
    digitalWrite(ledPin,HIGH);
    int packetSize = packetSize-8;   // minus 8-Bit Header
    Udp.readPacket(packetBuffer,UDP_TX_PACKET_MAX_SIZE, remoteIp, remotePort);
    Serial.println(packetBuffer);
    }
  if(packetSize==0)
    {
    digitalWrite(ledPin,LOW);
    analogWrite(E1,0);
    analogWrite(E2,0);
    }

    
for (int i=1;i!=8;i++)    //Searches for illegal characters inside the control-string
  {
  SteuerFehler=false;
  if(packetBuffer[i]!='-' |packetBuffer[i]!='x' |packetBuffer[i]!='0' |packetBuffer[i]!='1' |packetBuffer[i]!='2' |packetBuffer[i]!='3' |packetBuffer[i]!='4' |packetBuffer[i]!='5' |packetBuffer[i]!='6' |packetBuffer[i]!='7' |packetBuffer[i]!='8' |packetBuffer[i]!='9')
    {SteuerFehler=true;}
  }
  
/*  
  
if (SteuerFehler)
  {
  Serial.println("--------Fehler--------");
  packetBuffer[0]='-';    //Reset the control-string to all off
  packetBuffer[1]='-';
  packetBuffer[2]='-';
  packetBuffer[3]='-';
  packetBuffer[4]='-';
  packetBuffer[5]='-';
  packetBuffer[6]='-';
  packetBuffer[7]='-';
    
  SteuerFehler=false;
  }
*/


//DriveSpeed
if(packetBuffer[4]!='-')
  {
    switch(packetBuffer[4]){
    case '0': DriveSpeed=30;break;
    case '1': DriveSpeed=55;break;
    case '2': DriveSpeed=80;break;
    case '3': DriveSpeed=105;break;
    case '4': DriveSpeed=130;break;
    case '5': DriveSpeed=155;break;
    case '6': DriveSpeed=180;break;
    case '7': DriveSpeed=205;break;
    case '8': DriveSpeed=230;break;
    case '9': DriveSpeed=255;break;
    }
  }

  
if(packetBuffer[0]=='-' & packetBuffer[1]=='-') //Stop
    {analogWrite(E1,0);}
if(packetBuffer[0]=='x')  
    {digitalWrite(M1,HIGH);analogWrite(E1,DriveSpeed);} //Reverse
if(packetBuffer[1]=='x')                       //
    {digitalWrite(M1,LOW);analogWrite(E1,DriveSpeed);}  //Forward    

//Steering
if(packetBuffer[2]=='-' & packetBuffer[3]=='-') //Straight ahead
    {analogWrite(E2,0);}
if(packetBuffer[2]=='x')                        //Left
    {digitalWrite(M2,LOW);analogWrite(E2,255);}  
if(packetBuffer[3]=='x')                        //Right                
    {digitalWrite(M2,HIGH);analogWrite(E2,255);}      
    

}      
    
Steering-part is at the last lines.

I send a control-string of 8 characters, [2] is left and [3] is right, i'm always using the max. 255 for steering in one direction and LOW/HIGH. If [2] or [3] is not 'x', i set it to 0 volt.

It currently uses PWM and i'm not sure what the PLL-mode is...
When i listen to the sound that it makes, i get the feeling that the controller is giving out a stuttering (_-_-) voltage, like on->off->on... in very fast.
Maybe the magnet could work better without that fast on-off...

Edit:
I have set the Motor2 to PLL, but i don't rellay know a thing about it.
Heres what i have figured out so far:
M2 LOW -> Does nothing on any E2-Value ?
M2 HIGH -> enables Speed Control (in only one direction ?)

With M2=HIGH and E2=0, i can turn left just fine. But what about Right ?
« Last Edit: February 15, 2011, 06:21:28 am by kuno86 » Logged

Australia
Offline Offline
Full Member
***
Karma: 8
Posts: 161
You dont have to touch powerlines for them to kill you, even looking at them for too long will make them angry.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

E1 and M1 are the FWD/Backward setting pins, Reverse is HIGH, forward is LOW. 
E2 and M2 are the PWM pins, you should be able to use these as digitalWrite pins and not use pwm at all. This will send Full Left with lets say E2 at HIGH and E1 at LOW. Center is E2 = LOW. Full right would be E1 at HIGH E2 at HIGH
Logged

"Human beings, who are almost unique in having the ability to learn from the experience of others, are also remarkable for their apparent di

Germany
Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Back to the PWM-mode, it dosent work perfect, but at least i have left and right...

But there was something else i've noticed, the controller seems to get the signal, but then its sending out a low power (~40%) which then switches to the set power value after ~0,5 seconds delay.
shouldn't it give out the full power instantly ?
Logged

Australia
Offline Offline
Full Member
***
Karma: 8
Posts: 161
You dont have to touch powerlines for them to kill you, even looking at them for too long will make them angry.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Is it possible for you to try using digitalWrite(<pin>,HIGH) instead of outputting PWM? I would like to see of this changes anything as far as output power goes.
Logged

"Human beings, who are almost unique in having the ability to learn from the experience of others, are also remarkable for their apparent di

Germany
Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

HIGH is the same as 255.
Logged

New Hampshire
Offline Offline
God Member
*****
Karma: 17
Posts: 781
There are 10 kinds of people, those who know binary, and those who don't.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Your control for receiving input and controlling the car is a bit... wonky (no offense intended) and overcomplicated.  I can't see anything that will obviously cause the problems you are seeing, but a more simplified control scheme will not only make it easier to debug, but make it less likely that there will be a problem to debug from the start.

To that end, don't even bother checking for invalid characters.  Since you only perform actions based on valid characters, there's little benefit being gained by doing so.

Only set IO points when you receive a command packet.  There's no benefit to repeatedly setting IO points to the same values over and over and over.  Again, there shouldn't technically be anything wrong with doing so, but it can make diagnosing and debugging problems more of a headache than it already is.

So, as sort of some pseudo-code to go by:
Code:
if(packetavailable){
  receive packet
  perform drive control
  perform steering control
}

You can also easily reduce your drive control down to a single byte and your steering control down to a single byte.

Steering control byte would just be a three state control.
val1 = straight ahead
val2 = left
val3 = right

Drive control would only be slightly more complicated.  Using a signed char variable, you have a range of -127 to 127. if the val is less than 0, set you direction to reverse, otherwise set it to forward.  Take the absolute value of the variable, multiply it by 2 (then add 1 if you absolutely want the max speed possible, but the reality is the difference between 254 and 255 is likely negligible), and that's your speed.
Logged


Germany
Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks a lot jraskell, i deleted the in fact useless check-part and moved the controls into the the "if(packetsize)".

The stuttering is also solved now, it was propably caused by:
Code:
  if(packetSize==0)
    {
    digitalWrite(ledPin,LOW);
    analogWrite(E1,0);             
    analogWrite(E2,0);           
    }

this always activates when there are no packets, which is always the case right after a packet.
So i removed the two "analogWrite()" and it was gone smiley-grin



About making the controls bitwise, i had that in mind before, but i couldn't get the RAW-Data from UDP...
Logged

New Hampshire
Offline Offline
God Member
*****
Karma: 17
Posts: 781
There are 10 kinds of people, those who know binary, and those who don't.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Good to hear.  I never even noticed those lines from your original code, but that is clearly what was causing your problems.

As another side note, you may want to look at the difference between & and && as well as | and ||.  For what you're doing in your comparisons, the bitwise & and | operators are still accomplishing your goal, but you really should be using the boolean && and || operators in comparisons.
Logged


Pages: [1]   Go Up
Jump to: