Closed OLLYDOTDEV closed 4 years ago
with the #24 set up the #16 will next be startup then I can make a start on the code
start off with install the NRF24 library to the Arduino IDE
http://tmrh20.github.io/RF24/Linux.html http://tmrh20.github.io/RF24/RPi.html
cover what needs to be for setting everything. again the only issue I had was due to the face what I am using kali Linux I did not have stubs-hard so for the easy of me and other people trying to replicate a similar project I have made a fork with a reminder of what do if you encounter this issue as it was not documented anywhere on the web and had to be directly inquired with the head developer of this repository
as for testing the connection made in this user story
all that I needed to do from here was to make sure the radio object instructor was being given the correct CE and CSN pins number and that they match with the hardware layout given in
with that, I was ready to test.
note for latter usage the constant variable was use in place of the address arrayconst uint64_t pipes[2] = { 0xABCDABCD71LL, 0x544d52687CLL }; // radio address
If project birds eye is every deployed this array should be changed to ensure privacy
with all of this working how I wanted it to I am now about to continue with further development of the code
while I may now be able to control the NRF24 I how need to consider the flow of information for this, I can check my flow chart seen here. (From Components and relationships sheet)
from here we can see that there is two mainstream of data that are being transferred. the first data stream is the mode that the ROMS should be in. (RPI --> ROMS) and the other steam of stat would be the alert status coming from the (ROMS --> RPI) now it so happens the NRFT24 is only half-duplex meaning that it can only transmit or received data but not at the same time and has to switch modes. whereas a radio with full-duplex is able to transmit and received at the same time. see image to a visual explanation.
https://lastminuteengineers.com/nrf24l01-arduino-wireless-communication/
give a good wire up on now the inner workings the nRF24L01 module works when It comes to the duplexing system.
so with both streams of data identified I now will work on the logic that driver when what radios know what and when to send and receive
so really all that needs doing is to close the gap. This to consider when writing this code is for this is.
Setup
#------
import NRFT24 LIbrary
the set default mode to RX
initialize radio object
let channels and adders
#------
#TX
if input needs to be sent
set radio to TX
take input and formate it so that it is ready to send.
write to FIFO (First In, First Out) buffer
wait till FIFO butter is empty
reset to RX mode so that it is ready to received data
#------
#RX
loop (
check if radio free
listen to radio
pass data from radio data to variable
)
this would be the core of the transmission
on the ROMS and RPI, there would get in place some logic extra logic #29 to hand the data input/output of this Communication Network.
to here after a week of debugging and coding, I think I have found out have a way for me to make a Virtual serial link. how the logic works is explained in the comment above
see here for code https://github.com/OLLYDOTDEV/Project-Birdseye-DTX-2020/commit/b3fb46a5d136f45c1329921d71ef1e2286163eb6
so while this code that I have write might work but you can't be sure if it hasn't been fully tested but this arose an issue
the hardware that this was going to be tested on was an Arduino and a raspberry pi zero. while the Arduino use the Arduino environment with its helper functions as well as C++
whereas raspberry pi zero can be used .cpp
files raw ` C++ files. This is where my issue arises as if I code for one platform here it will not work on the other platform so this is why I have set up another Arduino for tested to just make sure that the logic of this Wireless_Communication_NRFT24_Test.ino
is working.
once I have that the usability search functionality for this code is as desired for the user story then I will be able to manually Port the code into a Version where the Raspberry Pi will be able to understand. (if there was more time available I would consider making automatic compiler due to time restrictions and budgetary constraints this will not happen but the framework needed for the automatic compiler will be laid out and place for a latter developer to pick this up and make this and wanted to keep developing this project)
something I must keep in mind with using radios is the Legal Implications. NRF24 radio operates on the 2.4 - 2.5Ghz Radio band, this is great as we can see that within ISM Bands that part of the radio Spectrum is carved out Worldwide for people Amateur meaning that it is unlicenced thus everybody is able to freely use it. but found within this band we mainly see the IEEE 802.11n wifi standard which is only found in the 2.4Ghz band. so to prevent interference with other mainstream services, the radio's i am using will be set to only use 2.5Ghz
so I broke it down to smaller core components BULK_SEND.INO and BULK_READ.ino Here is a testing video showing that I was able to break down my aim into two separate scripts that are able to automatically reconnect ensuring functionality in the event that this signal was interrupted without the need of a person to manually configure it again to connect.
but while this is great and all it lacks the ability to both transmit and receive per each node.
so next I will be upgrading Wireless_communctionation test so what all nodes are able to transmit and receive.
as of that last commit, it is able to receive just fine but it is unable to transmit successfully so what is when is next to work on
Sending was not to hard do all that is needed for a simple send function is radio.writeFast(&wireless_send, 4)
and it will find the location of the wireless_send array in memory and then transmit the next four bytes.
the advantage of using radio.writeFast
over radio.write
is that radio.writeFast
it uses queues so rather then it having to the microprocessor having one peace if information if sent and received by the other radio, is dump everything it has that needs to be sent into the NRF24 chipset buffer allowing the microprocessor to be free to continue with other checks, this allowing the radio so send data at a fast speed as there is no wait time for the second or third set of data to be received by the radio before it can be retransmitted.
but is has the issue that the packet was not successfully received it is unable to tell and this leads us to out End-user considerations as if for some reason if the packet was not received it could result in the alert sub system not being sent off and in turn alert subsystem isn't sent off when needed then it would result in the whole point of this project being irrelevant
to work that's the packet was received intact we can use a CRC, in short CRC is just a checksum (cryptographic hash function that will always give the same output if the same input is given) is used to check if the packet is fully received (Checksum image from Wikipedia) Both Nodes already have the checksum function and all that happens is when the input of the received data in contrast to the checksum of the received data if the checksums match then the data was received successfully. these principles are implemented into nRF24L01+, it also uses the Enhanced shockburst mode for send RF data thus allowing to have these more complicated methods of validation compared to the traditional regular nrf24 packet. (image from http://yveaux.blogspot.com/2014/07/nrf24l01-sniffer-part-1.html)
but so far I have only shown how I will be using checksums but that by itself is not enough to reliably determine whether the transmission was received. there is where the acknowledgment (ACK) subroutine comes into use. This sub-routine automatically sends back an ACK packet and according to the official examples of the NRF24 library tmrh20.github.io and also this is stated in the documentation documentation" Returns: True if the payload was delivered successfully false if not"
to see if we received ACK packet that needs to be put in an IF statement. Returns 0 if no ACK packet received . 1 if successfully received ACK packet
if (radio.writeFast(&buf,32){
// error code
}
now if there was a error then i cant be sure that the data was successfully received and will re-transmit until I get ACK packet back
this gives a valid demonstration on how to secure a reliable connection between NRF24 radios youtube.com/Andreas_Spiess
using this ack system gives me a form of feedback control allowing me to confirm if the Functionality & Sustainability (it is able to self correct if it happens ) to ensure reliability - Implications
there i have added ACK capabilities to my transmission code as well as smooth out another bug I was having after a successful transmission of a still continue to transmit rather than defaulting back to receive mode. This issue is caused by some incorrect logic within the an if statement that controlled when to change the mode back to RX(received).
With this we can see that if I give the device a packet to send I will automatically switch into TX mode then transmit the packet and looking ACK packet and to then switch back into RX mode if it did get confirmation that the packet was received successfully if it does not receive an act packet able continue to retransmit until it gets a reply.(while it is still waiting for a ACK packet I puts it in a queue that then get cycled through of tasks for the microprocessor to complete.)
note: On the odd occasion radios will not connect to each other and is a simple matter of rebooting both radios and issue will be fixed
Having it automatically switch into TX mode is great but there is a rare board case that both nodes set them self both to TX mode due to both trying to transmit at the same time no packets will be received and they will stay in the transmit mode infinitely. now, this is a bit of an issue. here is that the printed out when both ended up in transmit mode
There are two ways to fix this in my mind.
after some testing of plausible approaches both methods, I've come up the third method
txStandBy(time);
to Number of milliseconds to retry failed payloads then if it still fails after that I all ready know that is had been failing for X ms so I then will all the RXF() function (this function changes the mode receive) and after 5 seconds looking if another radio is sending then Return to trying to send the last message well turn out that using txStandBy(time)
in this manner would be an incorrect uses of this function, but for while trying to get this function to work that I had managed to create the logic need for it anyway fortunately I found a way to reuse it
if(0==radio.txStandBy() ){ // keeps trying to send data for 5 seconds
Serial.println("Unable to Transmit ");
Serial.println("Checking to other Radio is Transmitting ");
RXF(); // change to
while(receiving == true){
Serial.println("other radio transmitting waiting for available transmission slot");
RECEIVE();
}
TXF();
receiving = false;
}
}else{
Serial.println("Transmission Successful\n");
UnsentData == false;
}
so while this might not be the desired outcome of this operation of the transmission system in the development of the radio drop out sub-system there was another idea that some to mind. a fourth option that could be used in place of the logic to control this sub system. I can use the system of keeping track of the time spent trying to transmit, this by its self will work but to ensure that this reserve subsystem does not accidentally engage to do this I will also be checking if the amount of fails transmitters is at x amount
commit https://github.com/OLLYDOTDEV/Project-Birdseye-DTX-2020/commit/7c9ae55017f3311ce2f69ba2962192cacbc47956 shows what changes what made.
the main changes that can be focused on are
error reset function as this used to stop the incrementing values reaching a border case value. it also being that the TX down subsystem will get activates when it reachs a value of 10 (starting to count from 0-)
if(error > 9){ // if error count great then 10 reset value
error = 0;
}
the next another main part that needed to be modified as there needed to be some logic to check how much time has past
and a change is time is found with the final - initial = change
and on the odd case where maybe the amount of failed transmission not at the required threshold is 10 but for some reason, the microprocessor is running behind in the execution of the code then this will see that the radio code should be been executored quicker than that and I like to cause of that is due to the fact that the other radios are sending so I sets Transmissiontime = true;
so what it knows next time to look for a radio signal next time I go to the transmit and acting as a fallback to catch in the unexpected board cases that were already caught last statement. as due to this being part of the critical functionality you helping the radios to recover connection having multiple failed safes is a practical safety measure as some you need to consider for implications is the end user is how the client will end up utilising this item that's why all main systems able to independently from user input recover from unexpected board cases
else{
stopTime = millis();
if(stopTime - startTime > 5000)
Serial.println(stopTime - startTime );
Serial.println("Transmition taking to long");
Transmissiontime = true;
}
there are more changes made to the code but these are the main ones that stick out, other code included within this change is primarily for allowing the code talked about to fulfill as full functionality
next of to allow it the Wireless network to dynamically send input to data rather than pre-allocated payloads
for this Typedef and Structures Combined and key C++ alias naming function
and example of this being implemention on both NRF24 project from other electronic engineers.
so the first change that needs to be made is to allow for dynamic payloads. dynamic payloads for the radio is easy as radio.enableDynamicPayloads() ;
just needs to be called in the start-up.
as well so changing the fixed payload size . this changed mygetting the payload size with sizeof(wireless_receive )
dynamic payloads work fine but the Text I am trying to send happens to be in a string form and the NRF24 Radio Libray I am using happen to not support transmitting or receiving strings but rather only char, char arrays, int, Bytes
so this is where non-trivial string manipulation comes into play, I began seeing what form string can be converted into. the first thing that comes to might was converting into Bytes (raw binary) but turn out, fortunately, strings can be converted to char array with relative ease why shown here
DataPak.Data.toCharArray(RadioBuffPak.Buff,DataPak.Data.length());
but that didn't work there Is like the likes of charAt()
but I was unable to get that to work.
but what i was able to get to work was
BuffPak.Data[i] = DataPak.Data[i];
^^^ ^^^
char array String
demo of this code can be viewed here.
with all of this, I am able to send and received Strings by converting them to Char array then transmitting them and then converting them back to a String
As for char array to String Conversion, it is done by calling the C++ String Constructor in the formate String foo(char_array)
as found in https://forum.arduino.cc/index.php?topic=519481.0 String TempBuffString(BuffPak.Data)
is what am using is found https://github.com/OLLYDOTDEV/Project-Birdseye-DTX-2020/commit/6e22f91d8f08b35da6c1547a4a911b280b5df6fb
and this covers the my non-trivial string manipulation, so the full process string >> char > > char array > > Typedef and Structures Comb >> packet transmited(bytes) >> received(bytes) >> Typedef and Structures Comb >> Char array >> Char >> string
it should be noted that due to Typedef and Structures Combined you cant just directly declare the char array into it but rather have to set another temp String equal to the char array then make the temp String = the string you want to equal the array
String TempBuffString(BuffPak.Data); DataPak.Data = TempBuffString;
note while testing the receiving data will always be 32 bytes as that is the size of the char array
the last check that needed to be implemented was to check if the packet meets the necessary conditions to be able to send via the nrf24 radio.
There are two checking key points that need to be checked
when converting the String into the char array buff to make sure that the string it not larger then the array this is done with
if(Wireless_Send.Data.length() <= sizeof(Buff_Send.Data)){
With this I am able to stop the prevent overloading Char array with to large-sized string
also to stop data loss it is checked if the Buffer that the radio is going to send is smaller then the max amount of byte the radio can send if(sizeof(Buff_Send)> 32){
With this the network is fully working but in the microprocessor side of the code. it now needs to be Compiled into raw C++ this will be covered in #30
As an engineer To utilize the transceivers within ROMS I need software that will link the radios So that data can be transferred allow ROMS to communicate with the Central local relay