e45-ttl-100
Ceci est une ancienne révision du document !
Table des matières
Le transceiver (émetteur/récepteur) LoRa E45-TTL-100
- Basé sur le SX1276 de semtech.
- “E32-868T20D”
- Pilotable avec un UART.
- Mono canal.
- 100 mW
- Pas de support pour le RSSI (Radio Signal Strength Indicator)
- Consommation un peu trop élever pour être alimenté par le 3.3V de l'ESP32.
Fabrication d'un kit de mesure du signal LoRa
2 Modules :
- Une module mobile qui emet des messages et mesure la qualité du signal et le débit (ou meilleut spread factor) utilisable.
- Une simili gateway fixe qui répond au message LoRa
Algorithme de négociation du spread factor :
- Si pas de méssage valide depuis linkDeadTimeout, on écoute sur le plus gros SF.
- Si validMessageCountSpeedIncreaseThreshold messages séquentielle valides reçu alors on tente d'augmenter le SF
- Si on a reçu speedIncreaseRequestCount demandes séquentielles valides de changement de SF on change de SF.
- Si on a pas reçu de message depuis tooFastTimeout on décrémente le SF.
- Après un retour à la normal suite à un tooFastTimeout on ne retente pas l'augmentation de SF avant un temps waitBeforeSpeedIncreaseInterval
- La gateway acquitte les méssages en retournant le message avec le numéro de sequence incrémenté.
- Tant qu'un message n'est pas acquitté il est retransmis.
- linkDeadTimeout > 2 x tooFastTimeout
- tooFastTimeout dépend du SF tel que tooFastTimeout > 2 x messageTransmissionTime
- messageTransmissionTime = messageSize / SFdebit
- waitBeforeSpeedIncreaseInterval > 10 * messageTransmissionTime ?
Contenu des messages :
- indicateur de session
- indicateur de sequence
- SF demandé
Gateway / Repeater
SPEED_INC_VALID_MSG_COUNT = 5; SPEED_INC_REQ_COUNT = 2; WAIT_ACK_TIMEOUT = 10000; TOO_FAST_TIMEOUT = WAIT_ACK_TIMEOUT * 2 + 1000; LINK_DEAD_TIMEOUT = TOO_FAST_TIMEOUT * 2 + 1000; MIN_AIR_RATE = 0; MAX_AIR_RATE = 5; String sessionId = null; int seqId = -1; byte airRate = 0; int sequentialValidMessages = 0; int speedIncreaseReqCount = 0; long lastValidMessageReceivedTimestamp = now(); while(lastValidMessageReceivedTimestamp + LINK_DEAD_TIMEOUT > now()) { boolean notValidMessage = true; while (notValidMessage && lastMessageSentTimestamp + TOO_FAST_TIMEOUT > now()) { String receivedMsg = receiveMessage(); int msgSessionId = receivedMsg.substring(); int msgSeqId = receivedMsg.substring(); if (sessionId == null && msgSeqId == 0 || sessionId == msgSessionId && msgSeqId == seqId + 1) { int msgRequestedAirRate = receivedMsg.substring(); seqId = msgSeqId + 1; String ack = msgSessionId + "_" + seqId + "_"; if (msgRequestedAirRate == airRate + 1) { speedIncreaseReqCount ++; ack = ack + (airRate + 1); } sendMessage(ack); if (speedIncreaseReqCount > SPEED_INC_REQ_COUNT) { speedIncreaseReqCount = 0; requestedAirRate = min(requestedAirRate + 1, MAX_AIR_RATE); configLora(requestedAirRate); } } } if (notValidMessage) { sequentialValidMessages = 0; requestedAirRate = max(requestedAirRate - 1, MIN_AIR_RATE); } }
Emetteur
SPEED_INC_VALID_MSG_COUNT = 5; SPEED_INC_REQ_COUNT = 2; WAIT_ACK_TIMEOUT = 10000; TOO_FAST_TIMEOUT = WAIT_ACK_TIMEOUT * 2 + 1000; LINK_DEAD_TIMEOUT = TOO_FAST_TIMEOUT * 2 + 1000; WAIT_BEFORE_SPEED_INC_INTERVAL = 10 * WAIT_ACK_TIMEOUT; MIN_AIR_RATE = 0; MAX_AIR_RATE = 5; String sessionId = random; int seqId = 0; byte airRate = 0; int sequentialValidMessages = 0; int speedIncreaseReqCount = 0; long lastValidMessageReceivedTimestamp = now(); long lastTooFastTimeout = 0; while(lastValidMessageReceivedTimestamp + LINK_DEAD_TIMEOUT > now()) { message = sessionId + "_" + seqId + "_"; if (lastTooFastTimeout + WAIT_BEFORE_SPEED_INC_INTERVAL < now() && sequentialValidMessages > SPEED_INC_VALID_MSG_COUNT) { message = message + (airRate + 1); } boolean notAckedMessage = true; while (notAckedMessage && lastMessageSentTimestamp + TOO_FAST_TIMEOUT > now()) { // Try to send a message and get an ACK for TOO_FAST_TIMEOUT sendMessage(message); long lastMessageSentTimestamp = now(); while (notAckedMessage && lastMessageSentTimestamp + WAIT_ACK_TIMEOUT > now()) { // Try to get an ACK for WAIT_ACK_TIMEOUT String receivedMsg = receiveMessage(); int msgSessionId = receivedMsg.substring(); int msgSeqId = receivedMsg.substring(); if (msgSessionId == sessionId && msgSeqId == seqId + 1) { sequentialValidMessages ++; int msgRequestedAirRate = receivedMsg.substring(); if (msgRequestedAirRate == airRate + 1) { speedIncreaseReqCount ++; if (speedIncreaseReqCount > SPEED_INC_REQ_COUNT) { speedIncreaseReqCount = 0; airRate = min(airRate + 1, MAX_AIR_RATE); configLora(requestedAirRate); } } notAckedMessage = false; seqId = msgSeqId + 1; lastValidMessageReceivedTimestamp = now(); } else { sequentialValidMessages = 0; } } } if (notAckedMessage) { sequentialValidMessages = 0; airRate = max(airRate - 1, MIN_AIR_RATE); lastTooFastTimeout = now(); } }
Ressources
- Quelques billets de blog : https://quadmeup.com/tag/e45-ttl-100/
e45-ttl-100.1547698258.txt.gz · Dernière modification : 2019/01/17 04:10 de bigMax