Pages: 1 ... 5 6 [7] 8   Go Down
Author Topic: Declaring digital signal  (Read 6549 times)
0 Members and 1 Guest are viewing this topic.
Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 290
Posts: 25795
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
please tell me where the problem is and where I went wrong
Code:
incoming[i+1] = '\0'
Right there, if "i" is ever 127.
You need to pay attention to array sizes, or all sorts of strange things will start to happen.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Southampton, UK
Offline Offline
Jr. Member
**
Karma: 0
Posts: 66
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
incoming[i+1] = '\0'
Right there, if "i" is ever 127.
You need to pay attention to array sizes, or all sorts of strange things will start to happen.
This is one more issue. As I have mentioned before that the code will be coming in this form from Reprap to Arduino
G28 X0 Y0
G1 X10 Y10
What do you suggest I should put the value as "i" will never be 127  smiley-roll


Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
What do you suggest a proper way of comparing the incoming data would be ?
I'd really suggest that you do this one step at a time. Assure that you are indeed getting what you think you are.

Then, when you have a NULL terminated array of chars containing "G28 Xxx Yyy", you can look at the strtok function to get the first token ("G28" when the delimiter set is " "). Compare that token with the constants, using strcmp().
Logged

Southampton, UK
Offline Offline
Jr. Member
**
Karma: 0
Posts: 66
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

All right, so this is fine now, right !
Code:
void receiveEvent(int howMany)
{
  char incoming[128];
  while(Wire.available() < howMany); // do nothing
    for (int i = 0; i < howMany; i++) {
        if(i < 128){                   
            incoming[i] = Wire.receive(); 
            incoming[i+1] = '\0';
            Serial.print(incoming);
        }
       
        }
    }
Assure that you are indeed getting what you think you are.
According to what I have written in the Reprap code, I am sending
Code:
void loop()
{
  Wire.beginTransmission (5);
  Wire.send ("G1");
  Wire.send ("G28");
  Wire.endTransmission();
}
How do you propose I assure that I am actually getting this? I was putting up LED to see that.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Your posts, Javaid, just don't agree with each other. For example:

Quote
  char incoming[4]; // don't really know what the size of a g-code would be, so work on this number smiley-razz 

Then:

Quote
As I have mentioned before that the code will be coming in this form from Reprap to Arduino
G28 X0 Y0

So straight away you are expecting more than 4 bytes from the reprap?



I pointed out before that this:

Quote
Code:
void loop()
{
  Wire.beginTransmission (5);
  Wire.send ("G1");
  Wire.send ("G28");
  Wire.endTransmission();
}

Will send G1G28 in a single transmission. Thus if the LED flickers, it will do so for a microsecond or so. You changed it a few times and then went back to the very thing I said would not work. Why?



All right, so this is fine now, right !
Code:
void receiveEvent(int howMany)
{
  char incoming[128];
  while(Wire.available() < howMany); // do nothing
    for (int i = 0; i < howMany; i++) {
        if(i < 128){                   
            incoming[i] = Wire.receive(); 
            incoming[i+1] = '\0';
            Serial.print(incoming);
        }
       
        }
    }

The receiveEvent is told how many bytes have been received (the howMany argument). There is absolutely no point in doing this:

Code:
  while(Wire.available() < howMany); // do nothing

Wire.available() will be equal to howMany. That's how it works.

You are asking for help. But you are generally speaking just ignoring what we say:

Quote
To be very honest, I never follow what you say.
Logged

Southampton, UK
Offline Offline
Jr. Member
**
Karma: 0
Posts: 66
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

 smiley-small
Quote
To be very honest, I never follow what you say.
This particular post was for AWOL. I was just telling him that I don't really understand what he says.

And to be honest, it is kind of like this, when someone tells me to do something, I try to do it and then ask whether I have done it right or not. In the meantime, I get some suggestion from someone else and I start working on that. And in the end, I am messing up everything (so stupid of me  smiley-eek)

Let's just do 1 step at a time then, please.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
The receiveEvent is told how many bytes have been received (the howMany argument). There is absolutely no point in doing this:
Does the argument tell how many have been received or how many are to be received? In other words, is the callback called only after all the data has been received, or is it called as soon as data starts arriving?

I put that wait code in there on the assumption that the callback was called as soon as data started to arrive.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Wire.available function does this:

Code:
uint8_t TwoWire::available(void)
{
  return rxBufferLength - rxBufferIndex;
}

And this is the end of the internal ISR:

Code:
  // set rx iterator vars
  rxBufferIndex = 0;
  rxBufferLength = numBytes;
  // alert user program
  user_onReceive(numBytes);

Given that rxBufferIndex is 0 then Wire.available will return numBytes, that being the number of bytes received.

Actually, looking in twi.c I see this case for the stop condition:

Code:
case TW_SR_STOP: // stop or repeated start condition received
      // put a null char after data if there's room
      if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){
        twi_rxBuffer[twi_rxBufferIndex] = '\0';
      }
      // sends ack and stops interface for clock stretching
      twi_stop();
      // callback to user defined callback
      twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex);
      // since we submit rx buffer to "wire" library, we can reset it
      twi_rxBufferIndex = 0;
      // ack future responses and leave slave receiver state
      twi_releaseBus();
      break;

So I think I can say reasonably confidently that the OnReceive callback is not called the moment a byte or two is received, it is called on the stop condition, that is when nothing more is available in this "packet". So there is no real point in looping on Wire.available in any case.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Let's just do 1 step at a time then, please.

OK, I have a couple of test sketches. Connecting two Arduinos together (gnd, +5v, SDA, SCL) and running one on each you should see the inbuilt LED (pin 13) flash once a second.

Master, which sends G1 then G28:

Code:
// Author: Nick Gammon
// Date: 29 August 2011

#include <Wire.h>

#define reprap 6
#define slave 5

void setup ()
 {
 Wire.begin (reprap);
 }
 
void loop()
{
  Wire.beginTransmission (slave);
  Wire.send ("G1");
  Wire.endTransmission();

  delay (1000);
  
  Wire.beginTransmission (slave);
  Wire.send ("G28");
  Wire.endTransmission();

  delay (1000);

}

Note the delay, so you have a chance to see the LED blink. Note the beginTransmission / endTransmission pairs. This was what I have been talking about for quite a few pages.


The slave:

Code:
// Author: Nick Gammon
// Date: 29 August 2011

#include <Wire.h>

#define slave 5
#define LED 13

void receiveEvent (int howMany)
 {
  char buf [10];
  byte i = 0;

  while (Wire.available () > 0)
    {
    char c = Wire.receive ();
    if (i < sizeof (buf) - 1)  // check for overflow
      buf [i++] = c;
    }  // end of while

   buf [i] = 0;  // terminating null
  
  if (memcmp (buf, "G1", 2) == 0)
    digitalWrite (LED, HIGH);
  else if (memcmp (buf, "G28", 3) == 0)
    digitalWrite (LED, LOW);
}  // end of receiveEvent


void setup ()
{
  Wire.begin (slave);
  Wire.onReceive (receiveEvent);
  pinMode (LED, OUTPUT);
}  // end of setup

void loop()
{
// nothing in main loop
}

This looks for a transmission starting with G1 or G28 (actually you should probably make it "G1 " and "G28 " but I'll leave that as an exercise.

It works. It isn't complicated.

Now please, if you change it, make sure you understand why you are changing it.
« Last Edit: August 28, 2011, 06:16:45 pm by Nick Gammon » Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Does the argument tell how many have been received or how many are to be received?

It wouldn't know that anyway. This is a receiveEvent not a requestEvent. It gets what it gets, it can't know in advance how much that will be.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
It wouldn't know that anyway. This is a receiveEvent not a requestEvent. It gets what it gets, it can't know in advance how much that will be.
Not trying to argue. I'm just asking. The Wire.send() function buffer the data. Nothing gets sent until Wire,endTransmission gets called. At that time, the Wire instance knows how much data there is in the buffer, so the receive event could get called as soon as data starts coming in, and the function could be told how much data to expect. Your other post indicates that this is not the case, though.

If not, though, I wonder what the purpose of the Wire.available() function is. If the receive event handler is told how much data to receive, why is there another function to determine how much data there is to read?
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
At that time, the Wire instance knows how much data there is in the buffer, so the receive event could get called as soon as data starts coming in ...

Well they are at different ends. The sending end knows how much is in the buffer, the receiving end doesn't know how much to expect.

And in fact with the Wire.requestFrom the receiving end knows how much it requested, that won't necessarily be how much it gets (however it NAKs once the correct amount is received so it won't get more, but it might get less).

Quote
I wonder what the purpose of the Wire.available() function is.

I suppose it is really a helper function. You pull out a byte at a time with Wire.receive, so it tells you how much is left in the internal buffer.

Perhaps more importantly, the onRequest event doesn't supply howMany (unlike the onReceive event). So without Wire.available you don't know how much data you actually got when you requested it. Maybe you requested 10 bytes but got 5.
Logged

Southampton, UK
Offline Offline
Jr. Member
**
Karma: 0
Posts: 66
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks a bunch for this useful information smiley

I wasn't around as the Z-axis of the Reprap got jammed and had to disassemble almost half the machine (not that anyone asked).

I used the code with Master in Reprap and Slave in Arduino (without any change). Yes, I can see the LED flash every second. But

1- A single command is taking a lot of time to execute. I put in
G28 X0 Y0
G1 X50 Y50
and it took round about 1min 40 sec for the first command and almost the same for the second (give or take 5 sec).
Clearly, it is not good scenario for printing.

2- And the LED is not in sync with the commands. It is just blinking. Whether I give some commands or not, it just keeps on blinking smiley-confuse
According to the coding, it should work properly with any string starting with G1 (or G28) regardless of what follows it.
Logged

Southampton, UK
Offline Offline
Jr. Member
**
Karma: 0
Posts: 66
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I removed the delays in the Reprap (Master) code and now the commands are getting executed at normal speed. I do understand why the delays were there but because of them the commands were taking a lot of time to execute. That is why I removed them.

But now the LED is continuously ON and whenever I send G1 or G28, it turns OFF and then ON back again after the execution. It does flicker very quickly after the execution of each command, understandably as there is no delay.

Is it possible to keep the LED in ON state as long as the G1 command is executed. In short, if I want the LED to remain ON as long as I am sending G1 and only to turn OFF (send 0) when it receives G28, how to do that?

Or let's say
G28 X0 Y0 (remain OFF as long as this is executed)
G1 X10 Y10 (remain ON as long as this is executed)

Wait for a string with G28 to turn OFF otherwise if a string of G1 is being received, stay ON.

You guys have been extremely patient with somebody like me who has the programming skills of a bag of rocks and I really appreciate that. But I am still not there yet, so please keep posting your valuable comments smiley


« Last Edit: September 01, 2011, 06:54:32 pm by Javaid » Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I posted code that did exactly what you wanted (from the test Arduino). When it sent G1 it turned the LED on and when it sent G28 it turned it off.

Now you want help with code that you haven't posted. Sorry that's impossible.
Logged

Pages: 1 ... 5 6 [7] 8   Go Up
Jump to: