OLLYDOTDEV / Project-Birdseye-DTX-2020

The initial plan is to create a device that is made for the sole purpose of a Preemptive Security system for People who work with Confidential/Private Information and need to work on potentially more public places where one cant Guarantee fully secure/discrete room. My Approach to solving this is with a wireless computing node That Takes Sensor data from a variety of senses. Then the Data from the Senses is taken then and processed to determine whether there is a security breach if so then it will Relay that info over to the Raspberry Pi W that then Emulates an HID (Human interface device) Using the P4wnP1_aloa made by mame82 to Execute a custom user-defined action that will be set via Apache server hosted of the Raspberry Pi W Communicating From a web interface back to the purchase server utilizing Ajax
GNU General Public License v3.0
3 stars 1 forks source link

Wireless Communication Subsystem Development #17

Closed OLLYDOTDEV closed 4 years ago

OLLYDOTDEV commented 4 years ago

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

OLLYDOTDEV commented 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

OLLYDOTDEV commented 4 years ago

24 cover most of the setup but in short

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

OLLYDOTDEV commented 4 years ago

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

image

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

https://youtu.be/jFR7T_4C1Hg.

with all of this working how I wanted it to I am now about to continue with further development of the code

OLLYDOTDEV commented 4 years ago

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. image (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.

image ref

OLLYDOTDEV commented 4 years ago

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

OLLYDOTDEV commented 4 years ago

so really all that needs doing is to close the gap. This to consider when writing this code is for this is.

OLLYDOTDEV commented 4 years ago
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.

OLLYDOTDEV commented 4 years ago

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.

IMG_20200828_202618

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

OLLYDOTDEV commented 4 years ago

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

OLLYDOTDEV commented 4 years ago

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

OLLYDOTDEV commented 4 years ago

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 image (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 (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"

image

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

OLLYDOTDEV commented 4 years ago

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).

OLLYDOTDEV commented 4 years ago

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.) image

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

OLLYDOTDEV commented 4 years ago

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

image

OLLYDOTDEV commented 4 years ago

There are two ways to fix this in my mind.

  1. using txStandBy();
  2. using a timer to see if there has been x amount of failed transmissions

after some testing of plausible approaches both methods, I've come up the third method

  1. this uses 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
OLLYDOTDEV commented 4 years ago

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;
     }
OLLYDOTDEV commented 4 years ago

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

OLLYDOTDEV commented 4 years ago

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

OLLYDOTDEV commented 4 years ago

next of to allow it the Wireless network to dynamically send input to data rather than pre-allocated payloads

OLLYDOTDEV commented 4 years ago

for this Typedef and Structures Combined and key C++ alias naming function

norwegiancreations

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.

OLLYDOTDEV commented 4 years ago

as well so changing the fixed payload size . this changed mygetting the payload size with sizeof(wireless_receive )

OLLYDOTDEV commented 4 years ago

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

image

OLLYDOTDEV commented 4 years ago

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;

OLLYDOTDEV commented 4 years ago

note while testing the receiving data will always be 32 bytes as that is the size of the char array

image

OLLYDOTDEV commented 4 years ago

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

  1. 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

  2. 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){

OLLYDOTDEV commented 4 years ago

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