Hello Forum,
I'm close to crying. I'm eager to get my two NXTs communicating with each other through the RS-485 port. I'm trying to establish the communication with NXC. Yet unsuccessful. I'm using the latest version of the nbc compiler available for mac.
On my mac (running: 10.6.6) I get a few errors when compiling John Hansen's example: ex_RS485Receive.nxc (http://bricxcc.sourceforge.net/nbc/nxcd ... le.html#a0)
Here are the first three (it kinda goes on like this…):
#Error: Undefined Identifier RS485Enable File[…] ; line 8
# RS485Enable(
#----------------------
#Error: ";" expected File […] ; line 8
# RS485Enable()
#----------------------
#Error: Unmatched close parenthesis File […] ; line 8
# RS485Enable();
On my mom's mac (running: 10.5.8) I get this error:
#Error: Preprocessor macro function does not match instance (#asm{__UseRS485() })
Now why would the errors change when using the same compiler? And why won't the example code compile successfully? Please help me, I need to get this running real real real soon for my Science Fair Project! I will be your biggest fan if you can help me out. Do I need to include a file perhaps?
Thanks in advanced
NXC: RS-458
Re: NXC: RS-458
Has anybody else been able to compile this example?
-
- Posts: 1818
- Joined: 02 Oct 2010, 02:19
- Location: Michigan USA
- Contact:
Re: NXC: RS-458
That example compiled perfectly fine for me. I am running Win 7 64-bit, with BCC 3.3.8.10, and NBC 1.2.1.r4.
I don't think I have tried running the examples, but I have successfully used my own RS-485 programs.
Edit: I am running 1.31 EFW.
I don't think I have tried running the examples, but I have successfully used my own RS-485 programs.
Edit: I am running 1.31 EFW.
Matt
http://mattallen37.wordpress.com/
I'm all for gun control... that's why I use both hands when shooting
http://mattallen37.wordpress.com/
I'm all for gun control... that's why I use both hands when shooting
Re: NXC: RS-458
Could you share your code? Could you try compile the example? That would help me a lot.
Thanks though.
Thanks though.
-
- Posts: 1818
- Joined: 02 Oct 2010, 02:19
- Location: Michigan USA
- Contact:
Re: NXC: RS-458
Well, it is certainly not in a "share" type setup. I used these for debugging the lib I was writing. Here is the lib:
Master program:
Slave program:
I just ran a test, exactly as they are, and it worked fine. The master sends 10 numbers (random) to the slave, and the slave responds with 10 numbers (random). I really don't think I can explain it very well, as it was quite a while ago that I wrote them. I do know however, that the lib does not do any error checking (no CRC or checksum).
Hopefully you will be able to get something out of it.
Code: Select all
/*
My RS485 protocol data specs:
Sending byte array looks like this:
Senders address, Target address, Commands(flags), Data1, Data2, ..., Data n
Sending Ping looks like this:
Senders address, Target address, Ping Flag Value
Acknowledgement looks like this:
Senders address, Target address, Acknowledgement Flag Value
Returned values
-2 timeout
-1 something went wrong, probably not right address
0 not acknowledged
Command = success
*/
#define Master485Address 0x00 //The address of this NXT
#define Slave1485Address 0x01 //Slave number 1's address
//Master to slave flags
#define PingValue 0x08 //Return an Acknowledgement
#define WriteValue 0x10 //Write registers
#define ReadBackValue 0x20 //Return Values
//Slave to master flags
#define Acknowledge 0x01 //Result returned from a ping or write-only command
void SendRS485ByteArray (byte SenderAddress, byte TargetAddress, byte Command, byte SendData[]){
byte SendCompleteData[];
byte SendCompleteDataLength=ArrayLen(SendData)+3;
ArrayInit(SendCompleteData, 0, SendCompleteDataLength);
SendCompleteData[0]=SenderAddress;
SendCompleteData[1]=TargetAddress;
SendCompleteData[2]=Command;
byte i=0;
repeat(ArrayLen(SendData)){
SendCompleteData[i+3]=SendData[i];
i++;
}
string StringSendData = FlattenVar(SendCompleteData); //Flatten it into a string
SendRS485String(StringSendData); //Send the string
until(HSOutputBufferOutPtr() == StrLen(StringSendData)+1); //Wait until the string has been sent
}
int MasterReadRS485ByteArray (byte My485Address, byte BytesToReceive, int TimeOut, byte & InArray[]){
bool TimedOut=false;
byte TimePassed=0; //Reset the timeout counter
byte cnt;
string InString;
byte RawInArray[];
byte RawInArraySize=BytesToReceive+3;
ArrayInit(RawInArray, 0, RawInArraySize);
until (HSInputBufferInPtr() >= (BytesToReceive+4) || TimedOut){ //Until whole string is received
Wait(1); //Wait 1 ms
if (TimeOut==0){ //If TimeOut equals 0, then don't time out.
TimedOut=false;
}
else{
TimePassed++; //increase the timer
if (TimePassed>=TimeOut){
TimedOut=true;
}
}
}
if (TimedOut){ //If the timeout took place
return -2;
}
else{ //If the timeout did not take place
cnt=HSInputBufferInPtr();
GetHSInputBuffer(0, cnt, InString); //Read the buffer
SetHSInputBufferInPtr(0);
UnflattenVar(InString, RawInArray); //Unflatten the string into an array
byte SendersAddress=RawInArray[0];
byte TargetsAddress=RawInArray[1];
byte Command =RawInArray[2];
if (TargetsAddress==My485Address) //If the RdataC[0] contains this NXT's address, read the rest
{
ArraySubset(InArray, RawInArray, 3, NA);
return Command;
}
}
return -1;
}
void MasterSendPing(byte My485Address, byte TargetAddress){
byte PingData[3];
ArrayBuild(PingData, My485Address, TargetAddress, PingValue); //Build the array to send
string StringPingData = FlattenVar(PingData); //Flatten it into a string
SendRS485String(StringPingData); //Send the string
until(HSOutputBufferOutPtr() == StrLen(StringPingData)+1); //Wait until the string has been sent
}
int MasterCheckAcknowledgement(byte My485Address, int TimeOut){
bool TimedOut=false;
byte TimePassed=0; //Reset the timeout counter
string InString;
byte RawInArray[];
ArrayInit(RawInArray, 0, 3);
until (HSInputBufferInPtr() == 4 || TimedOut){ //Until whole string is received
Wait(1); //Wait 1 ms
if (TimeOut==0){ //If TimeOut equals 0, then don't time out.
TimedOut=false;
}
else{
TimePassed++; //increase the timer
if (TimePassed>=TimeOut){
TimedOut=true;
}
}
}
if (TimedOut){ //If the timeout took place
return -2;
}
else{ //If the timeout did not take place
GetHSInputBuffer(0, 4, InString); //Read the buffer
SetHSInputBufferInPtr(0);
UnflattenVar(InString, RawInArray); //Unflatten the string into an array
byte SendersAddress=RawInArray[0];
byte TargetsAddress=RawInArray[1];
byte Command =RawInArray[2];
if (TargetsAddress==My485Address) //If the TargetsAddress contains this NXT's address, read the rest
{
return Command;
}
}
return -1;
}
int MasterPing(byte My485Address, byte TargetAddress, int TimeOut){
MasterSendPing(My485Address, TargetAddress);
return MasterCheckAcknowledgement(My485Address, TimeOut);
}
void SlaveAcknowledge(byte My485Address, byte TargetAddress){
byte AcknowledgeData[3];
ArrayBuild(AcknowledgeData, My485Address, TargetAddress, Acknowledge); //Build the array to send
string StringAcknowledgeData = FlattenVar(AcknowledgeData); //Flatten it into a string
SendRS485String(StringAcknowledgeData); //Send the string
until(HSOutputBufferOutPtr() == StrLen(StringAcknowledgeData)+1); //Wait until the string has been sent
}
int SlaveReadAndRespondRS485ByteArray (byte My485Address, byte BytesToReceive, int TimeOut, byte SendValues[], byte & InArray[]){
byte GoOn=0;
int TimePassed=0; //Reset the timeout counter
byte cnt;
string InString;
byte RawInArray[];
until (HSInputBufferInPtr() >= (BytesToReceive+4) || GoOn!=0){ //Until whole string is received
Wait(1);
if(HSInputBufferInPtr()==4){ //If only a ping
Wait(3);
if(HSInputBufferInPtr()==4){ //Confirm only a ping
GoOn=1;
}
}
if (TimeOut!=0){ //If TimeOut equals 0, then don't time out.
TimePassed++; //increase the timer
if (TimePassed>=TimeOut){
GoOn=2;
}
}
}
if (GoOn==2){ //If TimedOut
return -2; // Return -2
}
else{ //If it didn't time out
if (GoOn==0){
byte RawInArraySize=BytesToReceive+3;
ArrayInit(RawInArray, 0, RawInArraySize);
cnt=HSInputBufferInPtr();
GetHSInputBuffer(0, cnt, InString); //Read the buffer
SetHSInputBufferInPtr(0);
UnflattenVar(InString, RawInArray); //Unflatten the string into an array
byte SendersAddress=RawInArray[0];
byte TargetsAddress=RawInArray[1];
byte Command =RawInArray[2];
if (TargetsAddress==My485Address)
{
if (ReadBackValue==(Command&ReadBackValue)){
SendRS485ByteArray (My485Address, SendersAddress, Command, SendValues);
}
if (WriteValue==(Command&WriteValue)){
ArraySubset(InArray, RawInArray, 3, NA);
}
return Command;
}
}
if (GoOn==1){
ArrayInit(RawInArray, 0, 3);
cnt=HSInputBufferInPtr();
GetHSInputBuffer(0, cnt, InString); //Read the buffer
SetHSInputBufferInPtr(0);
UnflattenVar(InString, RawInArray); //Unflatten the string into an array
byte SendersAddress=RawInArray[0];
byte TargetsAddress=RawInArray[1];
byte Command =RawInArray[2];
if (TargetsAddress==My485Address)
{
if (PingValue==(Command&PingValue)){
SlaveAcknowledge(My485Address, SendersAddress);
return Command;
}
}
}
}
return -1;
}
Code: Select all
/*
Returned values
-2 timeout
-1 something went wrong, probably not right address
0 not acknowledged
Command = success
*/
#include "MyRS485 lib.nxc" //Note, the main library
#define My485Address 0x00 //The address of this NXT
#define Master485Address 0x00 //The address of the master
#define Slave1485Address 0x01 //Slave number 1's address
//Master to slave flags
#define PingValue 0x08 //Return an Acknowledgement
#define WriteValue 0x10 //Write registers
#define ReadBackValue 0x20 //Return Values
//Slave to master flags
#define Acknowledge 0x01 //Result returned from a ping or write-only command
#define BytesToReceive 10
#define TimeOut 15
byte Sdata[]; //Array to send data
byte Rdata[BytesToReceive];
byte Svar0,Svar1,Svar2,Svar3,Svar4,Svar5,Svar6,Svar7,Svar8,Svar9;
int result;
task display() //Display the results
{
while(true)
{
ClearScreen();
NumOut(0, LCD_LINE1,Rdata[0]);
NumOut(0, LCD_LINE2,Rdata[1]);
NumOut(0, LCD_LINE3,Rdata[2]);
NumOut(0, LCD_LINE4,Rdata[3]);
NumOut(0, LCD_LINE5,Rdata[4]);
NumOut(50, LCD_LINE1,Rdata[5]);
NumOut(50, LCD_LINE2,Rdata[6]);
NumOut(50, LCD_LINE3,Rdata[7]);
NumOut(50, LCD_LINE4,Rdata[8]);
NumOut(50, LCD_LINE5,Rdata[9]);
NumOut(0, LCD_LINE8,result);
Wait(50);
}
}
task RS()
{
while (true)
{
Svar0=Random();
Svar1=Random();
Svar2=Random();
Svar3=Random();
Svar4=Random();
Svar5=Random();
Svar6=Random();
Svar7=Random();
Svar8=Random();
Svar9=Random();
ArrayBuild(Sdata, Svar0,Svar1,Svar2,Svar3,Svar4,Svar5,Svar6,Svar7,Svar8,Svar9);
SendRS485ByteArray (My485Address, Slave1485Address, (WriteValue|ReadBackValue), Sdata);
result=MasterReadRS485ByteArray (My485Address, BytesToReceive, TimeOut, Rdata);
//result=MasterPing(My485Address, Slave1485Address, TimeOut);
if (result==-1){
PlayToneEx(500,100,3,0);
}
if (result==-2){
PlayToneEx(1000,10,1,0);
}
Wait(500);
}
}
task main()
{
SetSensorType(IN_4, SENSOR_TYPE_HIGHSPEED); //Set up for RS485
SetHSState(HS_INITIALISE); // ''
SetHSFlags(HS_UPDATE); // ''
SetHSSpeed(HS_BAUD_921600);
SetHSInputBufferInPtr(0);
SetHSInputBufferOutPtr(0);
start display;
start RS;
}
Code: Select all
/*
My RS485 protocol data specs:
Sending byte array looks like this:
Senders address, Target address, Commands/flags, Data1, Data2, ..., Data n
Sending Ping looks like this:
Senders address, Target address, Ping Flag Value
Acknowledgement looks like this:
Senders address, Target address, Acknowledgement Flag Value
Returned values
-2 timeout
-1 something went wrong
0 not acknowledged
Command = success
*/
#include "MyRS485 lib.nxc" //Note, the main library
#define My485Address 0x01 //The address of this NXT
#define Master485Address 0x00 //The address of the master
#define Slave1485Address 0x01 //Slave number 1's address
//Master to slave flags
#define PingValue 0x08 //Return an Acknowledgement
#define WriteValue 0x10 //Write registers
#define ReadBackValue 0x20 //Return Values
//Slave to master flags
#define Acknowledge 0x01 //Result returned from a ping or write-only command
#define BytesToReceive 10
#define TimeOut 500
byte Sdata[];
byte Rdata[BytesToReceive];
byte Svar0,Svar1,Svar2,Svar3,Svar4,Svar5,Svar6,Svar7,Svar8,Svar9;
int result;
task display()
{
while(true)
{
ClearScreen();
NumOut(0, LCD_LINE1,Rdata[0]);
NumOut(0, LCD_LINE2,Rdata[1]);
NumOut(0, LCD_LINE3,Rdata[2]);
NumOut(0, LCD_LINE4,Rdata[3]);
NumOut(0, LCD_LINE5,Rdata[4]);
NumOut(50, LCD_LINE1,Rdata[5]);
NumOut(50, LCD_LINE2,Rdata[6]);
NumOut(50, LCD_LINE3,Rdata[7]);
NumOut(50, LCD_LINE4,Rdata[8]);
NumOut(50, LCD_LINE5,Rdata[9]);
NumOut(0, LCD_LINE8,result);
Wait(75);
}
}
task RS()
{
while (true)
{
Svar0=Random();
Svar1=Random();
Svar2=Random();
Svar3=Random();
Svar4=Random();
Svar5=Random();
Svar6=Random();
Svar7=Random();
Svar8=Random();
Svar9=Random();
ArrayBuild(Sdata, Svar0,Svar1,Svar2,Svar3,Svar4,Svar5,Svar6,Svar7,Svar8,Svar9);
result=SlaveReadAndRespondRS485ByteArray (My485Address, BytesToReceive, TimeOut, Sdata, Rdata);
if (result==-1){
PlayToneEx(500,100,3,0);
}
if (result==-2){
PlayToneEx(1000,10,1,0);
}
}
}
task main()
{
SetSensorType(IN_4, SENSOR_TYPE_HIGHSPEED);
SetHSState(HS_INITIALISE);
SetHSFlags(HS_UPDATE);
SetHSSpeed(HS_BAUD_921600);
SetHSInputBufferInPtr(0);
SetHSInputBufferOutPtr(0);
start display;
start RS;
}
Hopefully you will be able to get something out of it.
Matt
http://mattallen37.wordpress.com/
I'm all for gun control... that's why I use both hands when shooting
http://mattallen37.wordpress.com/
I'm all for gun control... that's why I use both hands when shooting
Re: NXC: RS-458
These kind of errors suggest that you are not telling the compiler to target the enhanced NBC/NXC firmware, which these API functions require. Make sure that you pass -EF on the command line. Also make sure that you have the latest enhanced NBC/NXC firmware on your brick. I am fairly sure that adding -EF to your command line will fix the problem. Are you using nxtcc or the nbc command line compiler? If you are using nxtcc then I think you can set the compiler command line options via a preferences dialog - but I can't recall for sure what I have implemented in that tool at this point.webstorms wrote:Hello Forum,
Here are the first three (it kinda goes on like this…):
#Error: Undefined Identifier RS485Enable File[…] ; line 8
# RS485Enable(
#----------------------
#Error: ";" expected File […] ; line 8
# RS485Enable()
#----------------------
#Error: Unmatched close parenthesis File […] ; line 8
# RS485Enable();
John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
http://bricxcc.sourceforge.net/
Re: NXC: RS-458
Thank you so much John! It compiles. and thanks for the source code matt.
Who is online
Users browsing this forum: Semrush [Bot] and 1 guest