View unanswered posts | View active topics It is currently Thu Apr 24, 2014 3:23 am






Reply to topic  [ 134 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6, 7, 8, 9  Next
1.45..1.40 public: RS485 connection for M/S-muxing? samples? 
Author Message
Rookie

Joined: Sat Apr 19, 2008 11:51 am
Posts: 43
Post Re: 1.40 public: how to use RS485 connection? code samples?
hi,
what I thought was actually:
master always in BT send mode and master always in RS485 receive mode
slave other way round

for motor control 2 codes are sent: speed and encodertarget:
master (BT): slave1.motorA.speed=100 // full speed forward
master (BT): slave1.motorA.encoder=180 // encodertarget, slave1 stops when reached
(no slave reply needed unless you want a "target reached" confirmation)

for sensorvalues a BT request is sent and the slave answeres:
master (BT): getvalue.slave0.sensor2Raw
slave (RS485): slave0.sensor2Raw=234

it's not simple to use both BT and RS485 , I see.
Maybe Ford's idea of using only RS485, copying an existing serial comm protocol, and switching between sending and receiving mode is better (?)


Last edited by spaceballs on Sun Aug 31, 2008 7:55 am, edited 1 time in total.



Sun Aug 31, 2008 7:49 am
Profile
Expert

Joined: Sun Sep 09, 2007 10:12 am
Posts: 116
Post Re: 1.40 public: how to use RS485 connection? code samples?
i understand, the problem here is that if you got 3 or more NXT, it's ended...

But if you wanna try it... go on =)

_________________
http://www.apcsguarda.com
My Project: http://www.robotc.net/forums/viewtopic.php?f=15&t=712


Sun Aug 31, 2008 7:54 am
Profile
Rookie

Joined: Sat Apr 19, 2008 11:51 am
Posts: 43
Post Re: 1.40 public: how to use RS485 connection? code samples?
yes, you are right.
for 3 or more you'll need a network protocol like TCP or token ring.


Sun Aug 31, 2008 7:56 am
Profile
Expert

Joined: Sun Sep 09, 2007 10:12 am
Posts: 116
Post Re: 1.40 public: how to use RS485 connection? code samples?
something like a data link...

But, probably, if , by mistake, both nxt try to be masters and start sending, i am not sure if NXT could not have problems cause of that...

_________________
http://www.apcsguarda.com
My Project: http://www.robotc.net/forums/viewtopic.php?f=15&t=712


Sun Aug 31, 2008 8:04 am
Profile
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post Re: 1.40 public: how to use RS485 connection? code samples?
docilio wrote:
But, probably, if , by mistake, both nxt try to be masters and start sending, i am not sure if NXT could not have problems cause of that...


that's why I suggested
a) to have a buffer array for all messages that have been sent , and to clear in case of it has been read (if you want to write a protocol by your own), or
b) copy an existing protocol (maybe even sort of mailbox program), cause this problem surely already has been solved [ http://en.wikipedia.org/wiki/ALOHAnet ], thx to mightor! 8)
c) as I meanwhile think, TCP won't work as long as you don't have full duplex; but with 3 nxt (or maybe just 2 or even more) you may use 1 brick to be a mail server who gets all messages from anywhere as the first (including the names of original addressee and the sender). He sends a BT signal to all others after a while ("switch to receive mode"), switches to RS485 send mode by himself and distributes all messages to the single addressees. After this, a different BT signal is sent to all others ("switch to send mode") and this starts anew. It surely won't be a good idea to make the brick with the main program (so long called "master") a mail server too because of limited resources, so the "slave1" is supposed to be the best candidate for this. Slave2...slave32653 :wink: may become simple remote slaves.

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;task main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PutPixel(x,y);}}}while(1)}


Sun Aug 31, 2008 8:27 am
Profile
Moderator
Moderator
User avatar

Joined: Wed Jan 31, 2007 3:39 am
Posts: 299
Location: San Diego, California. USA
Post Re: 1.40 public: how to use RS485 connection? code samples?
Great work everyone, I look forward to everyones progress! B-)

Hey Koldo, don't forget to post your project in the project section for others to find. Looks Great :-)

Scott

_________________
Mmmm Legos B-)

My Robot Projects:
http://www.freewebs.com/robotprojects/


Sun Aug 31, 2008 2:16 pm
Profile WWW
Rookie

Joined: Sun Aug 12, 2007 3:18 pm
Posts: 38
Post Re: 1.40 public: how to use RS485 connection? code samples?
I've a new version of the programs, I think is clearer.

Only three bytes to send. Only when the robot need it sends the message.

MASTER
Code:
#pragma config(Motor,  motorA,          tangentialA,   tmotorNormal, openLoop, )
#pragma config(Motor,  motorB,          tangentialB,   tmotorNormal, openLoop, )
#pragma config(Motor,  motorC,          tangentialC,   tmotorNormal, openLoop, )
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

#pragma platform(NXT)

bool bTransmit;
long nXmitSuccesses = 0;
long nRcvChars = 0;
byte RmotorA, RmotorB, RmotorC;             //speed values

//Speed ratio for RmotorA, RmotorB and RmotorC motors
#define RELACION_TRANSM_RADIAL 1

//Speed ratio for TmotorA, TmotorB and TmotorC motors
#define RELACION_TRANSM_TANGENCIAL 1

//matriz de velocidades  ------speed array
int Velocidades[9][6] =
{
   { -54,  47,-100,-85, 27, 58},
   {   0, -87, -87,100,-50,-50},
   {  54, 100, -47,-85, 58, 27},
   { 100, 100, 100,  0,  0,  0},
   {   0,   0,   0,  0,  0,  0},
   {-100,-100,-100,  0,  0,  0},
   {  54, -47, 100, 85,-27,-58},
   {   0,  87,  87,-100, 50, 50},
   { -54,-100,  47, 85,-58,-27},
};

/////////////////////////////////////////////////////////////////////////////////////
//            High Speed link functions
/////////////////////////////////////////////////////////////////////////////////////
void setupHighSpeedLink(const bool bMaster)
{
   //
   // Initialize port S$ to "high speed" mode.
   //
   nxtEnableHSPort();
   //nxtSetHSBaudRate();
   nxtHS_Mode = bMaster ? hsMsgModeMaster : hsMsgModeSlave;
   return;
}

task send()
{
   ubyte nData[] =
     {0x00, 0x00, 0x00};

   while (true)
   {
      while (bTransmit)
      {
        //assign the values to the array
         nData[0] = RmotorA;
        nData[1] = RmotorB;
        nData[2] = RmotorC;

         if (nxtWriteRawHS(nData[0], sizeof(nData), 0) == ioRsltSuccess)
           bTransmit = false;
      }
   }
}
// the main task shows the movements witch the robot can do

task main ()
{
  byte i;

  bTransmit = true;
  setupHighSpeedLink(true);
  nxtHS_Mode = hsRawMode;

  StartTask (send);

  while (true)
  {
     for (i=0; i<9; i++)
    {
      //3 motors conected in the master NXT
       motor[tangentialA] = Velocidades[i][0];
      motor[tangentialB] = Velocidades[i][1];
      motor[tangentialC] = Velocidades[i][2];

      //other 3 in the slave NXT
      RmotorA = Velocidades[i][3];
      RmotorB = Velocidades[i][4];
      RmotorC = Velocidades[i][5];

      bTransmit = true;

      wait10Msec(600);
    }
  }
}


SLAVE
Code:
#pragma config(Motor,  motorA,          RadialmotorA,  tmotorNormal, openLoop, )
#pragma config(Motor,  motorB,          RadialmotorB,  tmotorNormal, openLoop, )
#pragma config(Motor,  motorC,          RadialmotorC,  tmotorNormal, openLoop, )
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

#pragma platform(NXT)


long nXmitSuccesses = 0;
long nRcvChars = 0;
bool bReceive;

int vmotorA, vmotorB,vmotorC; // velocidades de los motores -- motor's speeds

void setupHighSpeedLink(const bool bMaster)
{
   //
   // Initialize port S$ to "high speed" mode.
   //
   nxtEnableHSPort();
   //nxtSetHSBaudRate();
   nxtHS_Mode = bMaster ? hsMsgModeMaster : hsMsgModeSlave;
   return;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//                                        Receive Bytes
//
////////////////////////////////////////////////////////////////////////////////////////////////////////


task recibe()
{
   const int kHexDigitsPerLine = 3;

   int nNumbBytesAvail;
   int nNumbBytesToRead;
   int nNumbBytesActuallyRead;
   byte BytesRead[kHexDigitsPerLine];
   while (true)
   {
     while (bReceive)
     {
        //
        // Loop continuously, reading one byte at a time. The interface will support larger reads.
        //
         nNumbBytesAvail = nxtGetAvailHSBytes();
         
         if (nNumbBytesAvail <= 0)
         {
            nNumbBytesActuallyRead = 0;
            wait1Msec(5);
            continue;
         }

         if (nNumbBytesAvail < sizeof(BytesRead))
           nNumbBytesToRead = nNumbBytesAvail;
         else
           nNumbBytesToRead = sizeof(BytesRead);

         nNumbBytesActuallyRead = nxtReadRawHS(BytesRead[0], nNumbBytesToRead);
         nRcvChars += nNumbBytesActuallyRead;
         wait1Msec(5);

         //
         // Display progress results on the NXT LCD screen.
         //
         nxtDisplayBigStringAt(0, 31, "Rcv");
        nxtDisplayBigStringAt(0, 15, "%d", nRcvChars);

        //assign the message values to motor power for the three motors
        vmotorA = BytesRead[0];
        vmotorB = BytesRead[1];
        vmotorC = BytesRead[2];

        //
        // Display the  bytes read on the NXT LCD in hex format.
        //
         nxtDisplayTextLine(1, "%d", vmotorA);
         nxtDisplayTextLine(2, "%d", vmotorB);
         nxtDisplayTextLine(3, "%d", vmotorC);
     }
 }
}
task main()
{
  bReceive = true;
  setupHighSpeedLink(true);
  StartTask(recibe);
   //
   // Configure the link for raw read and write. User program will have complete control over the link.
   // User program will be responsible for managing the half-duplex operation and must prevent collisions!
   //
   nxtHS_Mode = hsRawMode;

   while (true)
   {
      motor[RadialmotorA] = vmotorA;
      motor[RadialmotorB] = vmotorB;
      motor[RadialmotorC] = vmotorC;
   }
}

Hey Scott, when I finish the project I'll publish it, but RS485 opens new ways to me and I'm improving it.

Koldo

_________________
Image http://lrobotikas.net English version


Last edited by Koldo on Mon Sep 01, 2008 12:50 pm, edited 1 time in total.



Mon Sep 01, 2008 12:17 pm
Profile WWW
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post Re: 1.40 public: how to use RS485 connection? code samples?
hi,
looks even better ! 8)

In your code is a line that might be improved:
Code:
task send()
{
   ubyte nData[] =
     {0x00, 0x00, 0x00/*, 0x00, 0x00, 0x00, 0x00*/};


maybe you may use those bytes to transmitt both motor speed and encoder targetvalues?
byte 1: slave number
byte 2: motor number
byte 3: speed (read as byte, not ubyte: +/- 127, only +/-100 are used)
byte 4,5,6: encodertarget byte 4+ (byte5<<2) + (byte6<<4) should be big enough :wink:

the receiver shuts down the motor automatically when the target has been reached;
thus every motor can be controlled seperately...

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;task main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PutPixel(x,y);}}}while(1)}


Last edited by Ford Prefect on Mon Sep 01, 2008 1:53 pm, edited 1 time in total.



Mon Sep 01, 2008 12:37 pm
Profile
Rookie

Joined: Sun Aug 12, 2007 3:18 pm
Posts: 38
Post Re: 1.40 public: how to use RS485 connection? code samples?
Yes, it is a good option, however I don't need encoder control in my project , I use PF motors, without feedback.

The right code was
Code:
   ubyte nData[] =
     {0x00, 0x00, 0x00};

_________________
Image http://lrobotikas.net English version


Mon Sep 01, 2008 12:57 pm
Profile WWW
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post Re: 1.40 public: how to use RS485 connection? code samples?
yes, I know!
The idea was not to control all of the 3 slave motors all at once but seperate for a universal motor interface (not just for your personal project).
If you don't need the target, set them "FF FF FF" that means "infinite".

1.)
Usually you use
Code:
motor[0]=100; // motor[0]=motor[motorA];
nMotorEncoderTarget[0]=360; // 360 degrees

you may write a new function
Code:
void setMotor(ubyte n, byte v, int t)
{
  motor[n]=v;
  nMotorEncoderTarget[n]=t;
}

which does exactly this if passed as
Code:
setMotor(0,100,360);


2.)
now if you want to control a remote motor on a slave nxt, this can be the same function:
Code:
void setRemoteMotor(ubyte n, byte v, int t)
{
  //...
}

But now you parse the bytes and integers to single bytes an transmit them as an array - as you are just doing.
Only the interpretation of the byte array is different.

3.)
If you'll add even an extra byte as a slave ID, you may use the same function
Code:
void setRemoteMotor(ubyte s, ubyte n, byte v, int t) // s= slave number
{
  //...
}

this byte array might be sent to more than 1 nxt, maybe 2 or 3 slaves, but only THAT slave is executing this received array if the first byte is equal to his personal slave ID - the other one(s) ignore(s) this.
Thus you have got a motor remote control for many slaves with 3 motors each.

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;task main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PutPixel(x,y);}}}while(1)}


Last edited by Ford Prefect on Mon Sep 01, 2008 1:59 pm, edited 2 times in total.



Mon Sep 01, 2008 1:52 pm
Profile
Expert

Joined: Sun Sep 09, 2007 10:12 am
Posts: 116
Post Re: 1.40 public: how to use RS485 connection? code samples?
hi Ford, i am also working on that...

And algo got new ideas for a include file...

_________________
http://www.apcsguarda.com
My Project: http://www.robotc.net/forums/viewtopic.php?f=15&t=712


Mon Sep 01, 2008 1:58 pm
Profile
Rookie

Joined: Sat Apr 12, 2008 11:09 am
Posts: 49
Location: holland
Post Re: 1.40 public: how to use RS485 connection? code samples?
Hello,

I copyed Koldo´s code and changed it a little. still master/slave, but the master his only task is to keep the messaging running.

The idea is simple. Each brick has a number.

first byte send is the number for the brick to recieve it.
second byte is the brick whitch is sending.
byte 3 to as much as you like is the message.
each brick sends a message to all bricks with the latest data drawn from an array. The program can put the data into that array.

if the brick finished sending, it sends the folowing message
byte 1 bricknumber who has to start sending
byte 2 value 99.

i am still working on the code but if anyone can improve it or has ideas your wlecome
i could not test it with more than 2 bricks yet.
Code:
#pragma platform(NXT)

int transmitsucces=0;
bool bReceive=true;
bool bTransmit=false;
long nXmitSuccesses = 0;
long nRcvChars = 0;
long lastRcvChars=0;
int bricktorecieve=1;
const int numberofbricks=2; //number of bricks
const int bricknr=1;       //1 = master

int sendbuffer[numberofbricks+1][6];// values to be send to each brick
int recievebuffer[numberofbricks+1][6];//values recieved from each brick


/////////////////////////////////////////////////////////////////////////////////////
//            High Speed link functions
/////////////////////////////////////////////////////////////////////////////////////
void setupHighSpeedLink(const bool bMaster)
{
   nxtEnableHSPort();
   nxtHS_Mode = bMaster ? hsMsgModeMaster : hsMsgModeSlave;
   return;
}
/////////////////////////////////////////////////////////////////////////////////////
//            send bytes
/////////////////////////////////////////////////////////////////////////////////////
task HS()
{
   while (1==1)
   {
      const int kHexDigitsPerLine = 8;
      int nNumbBytesAvail;
      int nNumbBytesToRead;
      int nNumbBytesActuallyRead;
      byte BytesRead[kHexDigitsPerLine];

      ubyte datasend[8]; //senddata
//      {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
      while (bTransmit)
      {
         for (bricktorecieve=1; bricktorecieve<=numberofbricks; bricktorecieve++) //send data to all bricks
         {
            if (bricktorecieve!=bricknr)//dont send data to itself
            {
               transmitsucces=0;
               while (transmitsucces<2)//keep sending till succes
               {
                  //assign the values to the array
                  datasend[0] = bricktorecieve;      //brick to respont on message
                  datasend[1] = bricknr;             //brick sending the message
                  datasend[2] = sendbuffer[bricktorecieve][0];
                  datasend[3] = sendbuffer[bricktorecieve][1];
                  datasend[4] = sendbuffer[bricktorecieve][2];
                  datasend[5] = sendbuffer[bricktorecieve][3];
                  datasend[6] = sendbuffer[bricktorecieve][4];
                  datasend[7] = sendbuffer[bricktorecieve][5];
                  if (nxtWriteRawHS(datasend[0], sizeof (datasend), 0) == ioRsltSuccess)
                  {   transmitsucces++;}
               }
            }
         }
         if (bricknr==numberofbricks)   // tell next brick to start sending
           {bricktorecieve=1;}
         else
           {bricktorecieve=bricknr+1;}
         datasend[0] = bricktorecieve;      //brick to respont on message
         datasend[1] = 99;             //brick sending the message
         datasend[2] = 0;
         datasend[3] = 0;
         datasend[4] = 0;
         datasend[5] = 0;
         datasend[6] = 0;
         datasend[7] = 0;
         transmitsucces=0;

         while(transmitsucces<1) //keep sending till succes
         {
            if (nxtWriteRawHS(datasend[0], 8, 0) == ioRsltSuccess)
            {transmitsucces ++;}
         }
         bTransmit=false;
         bReceive=true;
      }

      while (bReceive) //recieve data
      {
         //
         // Loop continuously, reading one byte at a time. The interface will support larger reads.
         //
         nNumbBytesAvail = nxtGetAvailHSBytes();
         if (nNumbBytesAvail <= 0)
         {
            nNumbBytesActuallyRead = 0;
            wait1Msec(5);
            continue;
         }
      //   if (nNumbBytesAvail < sizeof(BytesRead))
    //       nNumbBytesToRead = nNumbBytesAvail;
   //      else
        nNumbBytesToRead = 8;//sizeof(BytesRead);always read 8 bytes
         nNumbBytesActuallyRead = nxtReadRawHS(BytesRead[0], nNumbBytesToRead);
         nRcvChars += nNumbBytesActuallyRead;
         wait1Msec(5);
         //
         // Display progress results on the NXT LCD screen.
         //
         nxtDisplayBigStringAt(0, 31, "Rcv");
         nxtDisplayBigStringAt(0, 15, "%d", nRcvChars);

         if(bricknr == BytesRead[0]) //see if data is for this brick
         {
            if (BytesRead[1]==99) // see if this brick has to start sending
            {
               bReceive=false;
               bTransmit=true;
            }
            else //store recieved data into a buffer
            {
               recievebuffer[BytesRead[1]][0]=BytesRead[2];
               recievebuffer[BytesRead[1]][1]=BytesRead[3];
               recievebuffer[BytesRead[1]][2]=BytesRead[4];
               recievebuffer[BytesRead[1]][3]=BytesRead[5];
               recievebuffer[BytesRead[1]][4]=BytesRead[6];
               recievebuffer[BytesRead[1]][5]=BytesRead[7];
          }
         }
      }
   }
}

task opdrachtbrick1()//some sample code for testing. push a button on brick 1
                     //and motorspeed on brick2 will change
{
   while (1==1)
   {
      if (nNxtButtonPressed>0)
        sendbuffer[2][nNxtButtonPressed]=50;
      else
      {
        sendbuffer[2][1]=20;
        sendbuffer[2][2]=20;
        sendbuffer[2][3]=20;
      }
      motor[motorA]= recievebuffer[2][1];
     motor[motorB]= recievebuffer[2][2];
     motor[motorC]= recievebuffer[2][3];
   }
}
task opdrachtbrick2()
{
   while (1==1)
   {
      if (nNxtButtonPressed>0)
        sendbuffer[1][nNxtButtonPressed]=50;
      else
      {
        sendbuffer[1][1]=20;
        sendbuffer[1][2]=20;
        sendbuffer[1][3]=20;
      }
      motor[motorA]= recievebuffer[2][1];
     motor[motorB]= recievebuffer[2][2];
     motor[motorC]= recievebuffer[2][3];
   }
}

task main ()
{

/*   if (bricknr==1)
  {
     bTransmit = true;
    bReceive = false;
  }
  else
  {
    bTransmit=false;
    bReceive=true;
  }*/
 
  setupHighSpeedLink(true);
  nxtHS_Mode = hsRawMode;
  StartTask(HS);
  if(bricknr==1)
  StartTask(opdrachtbrick1);
  if(bricknr==2)
  StartTask(opdrachtbrick2);
  while (1==1)
  {
    if (bricknr==1)// keep messaging running. if messaging stucks all bricks are in recieve mode
    {               // brick 1 will start sending.
       lastRcvChars=nRcvChars;
       wait10Msec(10);
      if (nRcvChars==lastRcvChars)
      {
         if (bReceive)
         {
           bReceive=false;
          bTransmit=true;
        }
        else
        {
          bReceive=true;
          bTransmit=false;
        }
      }
    }
    else
    {
       wait10Msec(999999);  //task has nothing to do anymore so just let is wait.
    }
  }
}



Thu Sep 04, 2008 3:33 pm
Profile
Rookie

Joined: Sun Aug 12, 2007 3:18 pm
Posts: 38
Post Re: 1.40 public: how to use RS485 connection? code samples?
One question, Is it possible to connect more than one brick together with RS485? How?

Koldo

_________________
Image http://lrobotikas.net English version


Thu Sep 04, 2008 3:46 pm
Profile WWW
Expert

Joined: Sun Sep 09, 2007 10:12 am
Posts: 116
Post Re: 1.40 public: how to use RS485 connection? code samples?
yes, if you connect many nxt like:

S4 S4 S4 S4
||_______|| _______|| _______||
--------------------------------
---------------------------------

like this... many connections share between all of nxt

_________________
http://www.apcsguarda.com
My Project: http://www.robotc.net/forums/viewtopic.php?f=15&t=712


Thu Sep 04, 2008 3:52 pm
Profile
Rookie

Joined: Sat Apr 12, 2008 11:09 am
Posts: 49
Location: holland
Post Re: 1.40 public: how to use RS485 connection? code samples?
yes it is

you need to modyfy your cables.

see the folowing movie
http://nl.youtube.com/watch?v=Kg56R6XzVdA


Thu Sep 04, 2008 3:53 pm
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 134 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6, 7, 8, 9  Next

Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  



Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.