Notifications
Clear all

Dancing Tinkerbell for a pirate magician

82 Posts
6 Users
9 Likes
2,713 Views
frogandtoad
(@frogandtoad)
Member
Joined: 5 years ago
Posts: 1458
 

@eliza

Posted by: @eliza

@robotbuilder  After posting I see that this reply is really related to what Ron Bently posted but I replied to robotbuilder.

  I am using the modules from the tutorial you linked because they are small and the coding is absolutely trivial.

I have used nRf24L01 with the reliable data gram package as Bill shows with the robot car. I think that method would work as the software uses a "send until you get confirmation" technique. I didn't use this hardware/software combo because it took up a lot of space and seemed like tremendous overkill. All I want is to capture a single digit, that comes only every minute or so. The apparatus needs to be hidden in a Captain Hook costume hook.

The only reason I'm using a 14 char buffer is I preceeded the data with "Tinkerbell" so as to check that I wasn't getting any spurious data from radio noise. My intention was to check that the package contained "My header" and then capture the digit off the end of the string. For the initial test I sent "Tinkerbell: 1" When I use a simple test over and over loop it works perfectly. As soon as I use "do something, then check for radio data" it fails. My original "do something" loop took about 10 seconds so I chopped that into a series of small steps that take less than a second but found that I needed to pare it down to a tiny step that doesn't accomplish anything near what I want to do.

I can light up a single pixel and then check for the single, but I want to draw a 5 pixel diamond, then some random pixie dust pixels, and then scatter the previously dropped pixie dust ... Just drawing the 5 pixel diamond apparently takes too much time.

My next plan is to imbed the radio driver into the tinkerbell object and check for data after every single light a pixel event. This is a real pain. I think:

void LightLed( int pixelToLight) {

  lightItUp( pixgelToLight);


  radio.recv( params here)


  if (dataIn)


    set "data ready" class variable


    capture radio buffer to class variable


    return "discontinue function" variable


else


   return "keep going"

 

Might work

All the comments are appreciated. Keep 'em coming. Thanks

As already noted, it's hard to know without seeing all the code, but since you mention you are using an object of your own, are you perhaps exceeding the max transmission of bytes causing it to fail?

RH_ASK.h

image

Please also check: RadioHead reference, specifically under "Implementation Details".

This may or may not be your problem, just another guess.

Cheers


   
ReplyQuote
(@eliza)
Member
Joined: 2 years ago
Posts: 81
Topic starter  

@robotbuilder I shortened the MakeTinkDance function to just light up one pixel and then return, with this I can get radio data.  I need to do more than just light up one pixel however.

The problem is not failure to get new data when a function is running. If I acquire data I run a long routine, and I don't get new data during that processing, and I don't want too.

I want Tinkerbell dancing "all the time"  When the transmitter sends data I want to detect it, then enter a new state and run a new function.

I'm assuming that the ASK library gets data from a timer interrupt, but perhaps that assumption is false. Maybe it only gets data when I explicitly call the recv function, but if so, I don't get how any program would work as you'd have to call recv at just the right moment.  I also presume that the transmitter somehow sends the data enough times that the receiver has a chance to see it, as even a println statement in the receiver takes some time, indeed just going around the loop function has entry and exit conditions that must take up a few clock ticks.

PS, I saw your comments about using millis etc. and I understand those comments and thank you for them.  I am checking into writing my own timer interrupt function to check for radio data behind the scenes.   My concern is that the ASK library is already running a timer interrupt and then I'll be running a second timer interrupt on top of that, calling a function that is itself timer interrupt controlled. That seems prone to failure.


   
ReplyQuote
(@eliza)
Member
Joined: 2 years ago
Posts: 81
Topic starter  

@frogandtoad I'm not exceeding maximum transmission of bytes. I'm transmitting 14 bytes every minute or so. If I "do nothing" between calls to recv it works perfectly. If I "do something" between calls to recv I get no data at all. I shortened my "do something" function to "do almost nothing" and it works perfectly. I need to do more than "almost nothing" between calls to the recv function. After I pared the function down to useless I can get the radio transmission.

I can't understand why data aren't held in the buffer long enough for me to do something and then check the radio transmission.


   
ReplyQuote
(@eliza)
Member
Joined: 2 years ago
Posts: 81
Topic starter  

The ASK library is using a hardware time defined as HardwareTimer timer(MAPLE_TIMER) with an alternate compile time definition of HardwareTimer timer(1)

Thus I think that ASK is doing its job looking for radio transmissions behind the scenes and I don't have to do more than call the recv function.

recv has this signature:

bool RH_INTERRUPT_ATTR RH_ASK::recv(uint8_t* buf, uint8_t* len)

recv checks available() and if available returns true then buf is filled with a memcpy statement.

Therefore: It looks to me like a call to recv should fill the buffer every time there are data available and then it should stay there until the next call.

However!!! I read in the library doco that you can get a zero length transmission, or empty buffer.

Therefore: I think my good data are being overwritten by an empty transmission before I have a chance to capture the good data that were there for a few ticks. I am definitely not transmitting any empty buffers. If that is happening it is against my will, and not because of any spurious transmission I'm making.

Thus:  ???? What to do? Don't give me no zero length buffers ASK library!! Give me some real data!!


   
ReplyQuote
(@eliza)
Member
Joined: 2 years ago
Posts: 81
Topic starter  

@will ASK uses timer1.  Found that in the code.

I'm not using my own timer routine but I'm thinking of trying that next to call recv while my tinkerbell code is running. I don't think recv() is itself timer driven. I'm concerned about the wisdom of using a timer to call another function that is itself timer driven, but I'm going to give it a go.


   
ReplyQuote
(@eliza)
Member
Joined: 2 years ago
Posts: 81
Topic starter  

@robotbuilder While I didn't change the name of the function, I changed the structure of the MakeTinkDance function so that I could enter, do a little work at a specific location, then return the next location. Each call is now:

position = MakeTinkDance( position );  Where the incoming position is updated inside the function. I think this agrees with your idea.


   
ReplyQuote
(@eliza)
Member
Joined: 2 years ago
Posts: 81
Topic starter  

@zander Yes, the 10 seconds was what I was originally doing. I had buttons with pin change interrupts that would set a state variable. The button press events were captured any time, regardless of separate processing. Then after executing the entire 10 second routine I checked the state variable and if a button had been pressed during the 10 second dance I had that event stored and I handled that new state.  Nothing time critical about when I went to the new state. Also, if the user pressed the same button again, no problem, I would just have state A change to state A.

This is supposed to be a magic trick (for a pirate) and it was too obvious that he was pushing a button in the lantern. So I'm trying to send the button push from a remote location. The button presses (on a separate arduino) are correctly captured and transmitted via the 433 mhz radio. The data are also correctly received, but not if I run too long between data checks. I chopped my 10 second function into a much smaller size and call it repeatedly with radio checks in between. Each call is now shorter than a second, but still too long.

The library doco says that an empty buffer transmission is legal, so I think that I'm getting an empty buffer some time after I get a good one. I'm not explicitly sending any empty buffers, they are going voluntarily.

I was hoping someone had used Bill's tutorial example and then did something a little more sophisticated with it, and had some experience with this ASK library.

Onward and upward! (perhaps)


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

@eliza Ok, sounds like you are working through it. I am under the weather at the moment, but when I feel better I will try it here, I have a few 433mHz radios. Once I am ready, you can send me your source and I can look into it. As I mentioned I did this type of time critical processing for a living back in the day so maybe my experience will help me to spot something. Don't send anything yet, I need to get over this Covid or Flu that I have. I will PM you when I am ready.

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.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.


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

@eliza 

The downside of using a library instead of writing it yourself 🙂

If the library erases the buffer after a very short time then that makes no sense.

I will give it some more thought later today as such communication issues are of interest to me.

 


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

@eliza Which 'Bill's tutorial example ' are you talking about? A link to it as a response to this query is what is expected.

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.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.


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

@zander 

I assumed this one.

https://dronebotworkshop.com/433mhz-rf-modules-arduino/

 


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

@robotbuilder That's only half of it. He has a task specific sketch as well, reading the data from the radio is trivial but if it isn't interrupt driven then the main sketch loop has to check for data  every pass and the main loop pass would be closer to 10msec than 10 secs. Something isn't making sense.

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.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.


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

@zander 

Something isn't making sense.

A mystery to solve.  I am sure if @eliza doesn't work it out someone can.

I suspect if you replace the radio connection with a direct connection between the pins and make a common ground between the two arduinos the library should also work or you can figure out your own code to do the same job.  After lunch I may get time to work on my own version just for fun.

 


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

@robotbuilder @eliza I am not sure it means anything, but I see in Bill's sketch the recv function has 2 unusual things. See pic. The comment preceding the call to recv says

'Check if received packet is correct size'. I see no code after that to do that. Secondly is the buflen argument is preceded by &. I have seen this mechanism before and it works like the following.

I pass in via buflen address the max msg size, and the recv function either does or does not have the same amount of data. There are 2 possibilities here, either the recv call returns a non zero which is the amt of data actually recvd or the left over. OR buflen gets changed to the amount of data left. I think it is the later and a call to recv of false says figure out what to do about the rest of the data.

To debug, print the return value from the call to recv and print the before and after values of buflen. That should tell you something.

Screen Shot 2022 10 17 at 14.27.15

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.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.


   
ReplyQuote
(@eliza)
Member
Joined: 2 years ago
Posts: 81
Topic starter  

@zander the 433 mhz radio video > https://dronebotworkshop.com/433mhz-rf-modules-arduino/

The radio communication works perfectly, provided I just use the simple "read it all the time" method


   
ReplyQuote
Page 2 / 6