From d711003f66181f285a6e200ea6c55be62616bd77 Mon Sep 17 00:00:00 2001 From: Rob Tillaart Date: Thu, 28 Dec 2023 12:13:40 +0100 Subject: [PATCH] 0.1.0 KT0803 --- libraries/KT0803/.arduino-ci.yml | 28 +++ libraries/KT0803/.github/FUNDING.yml | 4 + .../KT0803/.github/workflows/arduino-lint.yml | 13 ++ .../.github/workflows/arduino_test_runner.yml | 17 ++ .../KT0803/.github/workflows/jsoncheck.yml | 18 ++ libraries/KT0803/CHANGELOG.md | 10 + libraries/KT0803/LICENSE | 21 ++ libraries/KT0803/README.md | 184 ++++++++++++++++ .../KT0803_minimal/KT0803_minimal.ino | 32 +++ libraries/KT0803/keywords.txt | 41 ++++ libraries/KT0803/library.json | 23 ++ libraries/KT0803/library.properties | 11 + libraries/KT0803/src/KT0803.cpp | 199 ++++++++++++++++++ libraries/KT0803/src/KT0803.h | 80 +++++++ 14 files changed, 681 insertions(+) create mode 100644 libraries/KT0803/.arduino-ci.yml create mode 100644 libraries/KT0803/.github/FUNDING.yml create mode 100644 libraries/KT0803/.github/workflows/arduino-lint.yml create mode 100644 libraries/KT0803/.github/workflows/arduino_test_runner.yml create mode 100644 libraries/KT0803/.github/workflows/jsoncheck.yml create mode 100644 libraries/KT0803/CHANGELOG.md create mode 100644 libraries/KT0803/LICENSE create mode 100644 libraries/KT0803/README.md create mode 100644 libraries/KT0803/examples/KT0803_minimal/KT0803_minimal.ino create mode 100644 libraries/KT0803/keywords.txt create mode 100644 libraries/KT0803/library.json create mode 100644 libraries/KT0803/library.properties create mode 100644 libraries/KT0803/src/KT0803.cpp create mode 100644 libraries/KT0803/src/KT0803.h diff --git a/libraries/KT0803/.arduino-ci.yml b/libraries/KT0803/.arduino-ci.yml new file mode 100644 index 00000000..77a333f9 --- /dev/null +++ b/libraries/KT0803/.arduino-ci.yml @@ -0,0 +1,28 @@ +platforms: + rpipico: + board: rp2040:rp2040:rpipico + package: rp2040:rp2040 + gcc: + features: + defines: + - ARDUINO_ARCH_RP2040 + warnings: + flags: + +packages: + rp2040:rp2040: + url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json + +compile: + # Choosing to run compilation tests on 2 different Arduino platforms + platforms: + - uno + # - due + # - zero + # - leonardo + - m4 + - esp32 + - esp8266 + # - mega2560 + - rpipico + diff --git a/libraries/KT0803/.github/FUNDING.yml b/libraries/KT0803/.github/FUNDING.yml new file mode 100644 index 00000000..90d9ab4c --- /dev/null +++ b/libraries/KT0803/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms + +github: RobTillaart + diff --git a/libraries/KT0803/.github/workflows/arduino-lint.yml b/libraries/KT0803/.github/workflows/arduino-lint.yml new file mode 100644 index 00000000..8a26f14a --- /dev/null +++ b/libraries/KT0803/.github/workflows/arduino-lint.yml @@ -0,0 +1,13 @@ + +name: Arduino-lint + +on: [push, pull_request] +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: arduino/arduino-lint-action@v1 + with: + library-manager: update + compliance: strict diff --git a/libraries/KT0803/.github/workflows/arduino_test_runner.yml b/libraries/KT0803/.github/workflows/arduino_test_runner.yml new file mode 100644 index 00000000..fadfa904 --- /dev/null +++ b/libraries/KT0803/.github/workflows/arduino_test_runner.yml @@ -0,0 +1,17 @@ +--- +name: Arduino CI + +on: [push, pull_request] + +jobs: + runTest: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: 2.6 + - run: | + gem install arduino_ci + arduino_ci.rb diff --git a/libraries/KT0803/.github/workflows/jsoncheck.yml b/libraries/KT0803/.github/workflows/jsoncheck.yml new file mode 100644 index 00000000..37a11298 --- /dev/null +++ b/libraries/KT0803/.github/workflows/jsoncheck.yml @@ -0,0 +1,18 @@ +name: JSON check + +on: + push: + paths: + - '**.json' + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: json-syntax-check + uses: limitusus/json-syntax-check@v1 + with: + pattern: "\\.json$" + diff --git a/libraries/KT0803/CHANGELOG.md b/libraries/KT0803/CHANGELOG.md new file mode 100644 index 00000000..c21f3700 --- /dev/null +++ b/libraries/KT0803/CHANGELOG.md @@ -0,0 +1,10 @@ +# Change Log KT0803 + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/) +and this project adheres to [Semantic Versioning](http://semver.org/). + + +## [0.1.0] - 2023-12-27 +- initial version diff --git a/libraries/KT0803/LICENSE b/libraries/KT0803/LICENSE new file mode 100644 index 00000000..16ef1551 --- /dev/null +++ b/libraries/KT0803/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023-2023 Rob Tillaart + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libraries/KT0803/README.md b/libraries/KT0803/README.md new file mode 100644 index 00000000..52e32152 --- /dev/null +++ b/libraries/KT0803/README.md @@ -0,0 +1,184 @@ + +[![Arduino CI](https://github.com/RobTillaart/KT0803/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci) +[![Arduino-lint](https://github.com/RobTillaart/KT0803/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/KT0803/actions/workflows/arduino-lint.yml) +[![JSON check](https://github.com/RobTillaart/KT0803/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/KT0803/actions/workflows/jsoncheck.yml) +[![GitHub issues](https://img.shields.io/github/issues/RobTillaart/KT0803.svg)](https://github.com/RobTillaart/KT0803/issues) + +[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/KT0803/blob/master/LICENSE) +[![GitHub release](https://img.shields.io/github/release/RobTillaart/KT0803.svg?maxAge=3600)](https://github.com/RobTillaart/KT0803/releases) +[![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/KT0803.svg)](https://registry.platformio.org/libraries/robtillaart/KT0803) + + + +# KT0803 + +Arduino Library for KT0803 FM transmitter. + + +## Legal point of attention + +In different countries there are different laws with respect to using transmitting devices +and their range. +Please inform yourself of the local rules and laws if and how you may or may not use a +device like the KT0803 in your projects, either hobby, commercial or otherwise. + + +## Description + +This **experimental** library allows basic control of the KT0803 FM transmitter device. +It is written as I wanted to understand the possibilities and the interface of the device. + +The library is not tested yet with hardware. (see future). + +There are some newer, more capable, follow up devices like model K, L and M however these +are not supported (yet) although they probably will work as they seem backwards compatible. + +#### Warning + +The KT0803 is an 3.3 Volt device and cannot be connected directly to 5V MCU's. + + +#### Related + +- https://github.com/RobTillaart/KT0803 +- https://www.hackster.io/hesam-moshiri/stereo-digital-fm-transmitter-circuit-arduino-code-2dbd8d +- https://www.hackster.io/hesam-moshiri/full-digital-fm-receiver-with-arduino-and-tea5767-52be37 +- https://www.hackerstore.nl/Artikel/388 + + + +## Interface + +```cpp +#include "KT0803.h" +``` + +` +#### Constructor + +- **KT0803(uint8_t address, TwoWire \*wire = &Wire)** constructor, +optional Wire interface. +- **bool begin()** initializes the library. +Furthermore it checks if the deviceAddress is available on the I2C bus. +Returns true if deviceAddress is found on the bus, false otherwise. +- **bool isConnected()** test to see if deviceAddress is found on the I2C-bus. + + +#### Frequency + +- **bool setFrequency(float frequency)** converts the frequency to call **setChannel()** +- **float getFrequency()** returns the current frequency, can be slightly different, +due to rounding math. +The return value if derived from **getChannel()** +- **bool setChannel(uint16_t channel)** sets the channel to broadcast on. +- **uint16_t getChannel()** returns the set channel. + + +#### PGA, RFGain + +Read datasheet. + +- **bool setPGA(uint8_t pga)** +- **uint8_t getPGA()** + +| pga | gain | +|:-----:|:-------:| +| 111 | 12dB | +| 110 | 8dB | +| 101 | 4dB | +| 100 | 0dB | +| 000 | 0dB | +| 001 | -4dB | +| 010 | -8dB | +| 011 | -12dB | + +- **bool setRFGain(uint8_t rfgain); +- **uint8_t getRFgain(); + +TODO RFGAIN table + + +#### Region selection + +Read datasheet. + +The first four are convenience wrappers for **setPHTCNST()** + +- **void setEurope()** +- **void setAustralia()** +- **void setUSA()** +- **void setJapan()** +- **bool setPHTCNST(bool on)** +- **bool getPHTCNST()** + +If some region is missing please let me know and I can add it. + + +#### PilotToneAdjust + +Read datasheet. + +- **bool setPilotToneAdjust(uint8_t mode)** // HIGH = 1 LOW = 0 +- **uint8_t getPilotToneAdjust()** + + +#### Mute + +- **bool setMute(bool mute)** enables or disables the transmitting. +- **bool getMute()** returns the current state. + + +## Derived classes + +The KT0803K/L/M devices might work as they seem backwards compatible. + + + +## Future + +#### Must + +- improve documentation + - fill in gaps (TODO). +- buy hardware +- test and verify. + +#### Should + +- check validity/range parameters + - enums for parameters - readability? +- investigate support + - KT0803K, KT0803L, KT0803M (derived classes) +- at startup + - mute device + - set 'dummy' channel + - preset channel array in .h file (hardcoded) + + +#### Could + +- investigate efficiency of register access. + - caching all (allowed) registers in **begin()** 0.1.1 + - 3 bytes for KT0803 + - 12 bytes for KT0803K + - cache frequency. + - only writing is needed. +- need hardware to test. +- examples + - create frequency hopping device + - preset channels (eeprom?) + - send binary data over FM? +- investigate tea5767 FM receiver + + +#### Wont + + +## Support + +If you appreciate my libraries, you can support the development and maintenance. +Improve the quality of the libraries by providing issues and Pull Requests, or +donate through PayPal or GitHub sponsors. + +Thank you, + diff --git a/libraries/KT0803/examples/KT0803_minimal/KT0803_minimal.ino b/libraries/KT0803/examples/KT0803_minimal/KT0803_minimal.ino new file mode 100644 index 00000000..811e01f6 --- /dev/null +++ b/libraries/KT0803/examples/KT0803_minimal/KT0803_minimal.ino @@ -0,0 +1,32 @@ +// +// FILE: KT0803_minimal.ino +// AUTHOR: Rob Tillaart +// PURPOSE: minimal demo +// URL: https://github.com/RobTillaart/KT0803 + + +#include "Arduino.h" +#include "Wire.h" +#include "KT0803.h" + + +KT0803 FM_SEND; + + +void setup() +{ + Serial.begin(115200); + while(!Serial); + + FM_SEND.begin(); + + FM_SEND.setChannel(1000); +} + +void loop() +{ +} + + +// -- END OF FILE -- + diff --git a/libraries/KT0803/keywords.txt b/libraries/KT0803/keywords.txt new file mode 100644 index 00000000..d31ebda3 --- /dev/null +++ b/libraries/KT0803/keywords.txt @@ -0,0 +1,41 @@ +# Syntax Colouring Map For KT0803 + + +# Data types (KEYWORD1) +KT0803 KEYWORD1 + + +# Methods and Functions (KEYWORD2) +# Common +begin KEYWORD2 +isConnected KEYWORD2 + +setFrequency KEYWORD2 +getFrequency KEYWORD2 +setChannel KEYWORD2 +getChannel KEYWORD2 + +setPGA KEYWORD2 +getPGA KEYWORD2 + +setRFGain KEYWORD2 +getRFgain KEYWORD2 + +setEurope KEYWORD2 +setAustralia KEYWORD2 +setUSA KEYWORD2 +setJapan KEYWORD2 +setPHTCNST KEYWORD2 +getPHTCNST KEYWORD2 + +setPilotToneAdjust KEYWORD2 +getPilotToneAdjust KEYWORD2 + +setMute KEYWORD2 +getMute KEYWORD2 + + +# Constants (LITERAL1) +KT0803_LIB_VERSION LITERAL1 + + diff --git a/libraries/KT0803/library.json b/libraries/KT0803/library.json new file mode 100644 index 00000000..7a187618 --- /dev/null +++ b/libraries/KT0803/library.json @@ -0,0 +1,23 @@ +{ + "name": "KT0803", + "keywords": "Broadcast, KT0803K, KT0803L, KT0803M", + "description": "Arduino library for the KT0803 FM transmitter.", + "authors": + [ + { + "name": "Rob Tillaart", + "email": "Rob.Tillaart@gmail.com", + "maintainer": true + } + ], + "repository": + { + "type": "git", + "url": "https://github.com/RobTillaart/KT0803.git" + }, + "version": "0.1.0", + "license": "MIT", + "frameworks": "*", + "platforms": "*", + "headers": "KT0803.h" +} diff --git a/libraries/KT0803/library.properties b/libraries/KT0803/library.properties new file mode 100644 index 00000000..2236e268 --- /dev/null +++ b/libraries/KT0803/library.properties @@ -0,0 +1,11 @@ +name=KT0803 +version=0.1.0 +author=Rob Tillaart +maintainer=Rob Tillaart +sentence=Arduino library for the KT0803 FM transmitter. +paragraph=KT0803K, KT0803L, KT0803M +category=Communication +url=https://github.com/RobTillaart/KT0803 +architectures=* +includes=KT0803.h +depends= diff --git a/libraries/KT0803/src/KT0803.cpp b/libraries/KT0803/src/KT0803.cpp new file mode 100644 index 00000000..bb96086d --- /dev/null +++ b/libraries/KT0803/src/KT0803.cpp @@ -0,0 +1,199 @@ +// +// FILE: KT0803.cpp +// AUTHOR: Rob Tillaart +// VERSION: 0.1.0 +// PURPOSE: Arduino Library for KT0803 FM transmitter +// URL: https://github.com/RobTillaart/KT0803 + + +#include "KT0803.h" + + +// REGISTERS on page 7 datasheet + + +KT0803::KT0803(TwoWire * wire) +{ + _address = 0x3E; + _wire = wire; +} + + +bool KT0803::begin() +{ + return isConnected(); +} + + +bool KT0803::isConnected() +{ + _wire->beginTransmission(_address); + return (_wire->endTransmission() == 0); +} + + +/////////////////////////////////////////////////////////// + + +bool KT0803::setFrequency(float frequency) +{ + return setChannel(round(frequency * 20)); +} + + +float KT0803::getFrequency() +{ + return getChannel() * 0.05; +} + + +bool KT0803::setChannel(uint16_t channel) +{ + if (writeData(0x00, channel & 0xFF) == false) return false; + + uint8_t data = readData(0x01); + data &= 0xF8; // keep other bits + data |= (channel >> 8) & 0x07; + return writeData(0x01, data); + + // Reg02 CHSEL[0] = 0 ==> 100 KHz accuracy. + // Reg02 CHSEL[0] = 1 ==> 50 KHz accuracy. // TODO KT0803K derived class +} + + +uint16_t KT0803::getChannel() +{ + uint16_t channel = readData(0x01) & 0x07; + channel <<= 8; + channel |= readData(0x00); + return channel; +} + + +bool KT0803::setPGA(uint8_t pga) +{ + uint8_t data = readData(0x01); + data &= 0xC7; // keep other bits + data |= (pga << 3); + return writeData(0x01, data); +} + + +uint8_t KT0803::getPGA() +{ + return (readData(0x01) >> 3) & 0x07; +} + + +bool KT0803::setRFGain(uint8_t rfgain) +{ + // bits 0 and 1 + uint8_t data = readData(0x01) & 0x3F; + data |= (rfgain & 0x03) << 6; + writeData(0x01, data); + // bit 2 + data = readData(0x13) & 0x7F; + data |= (rfgain & 0x04) << 5; + writeData(0x13, data); + // bit 3 + data = readData(0x02) & 0xBF; + data |= (rfgain & 0x08) << 3; + writeData(0x02, data); + return true; // TODO add error handling. +} + + +uint8_t KT0803::getRFgain() +{ + uint8_t data = readData(0x01) >> 6; // bit 0, 1 + data |= ((readData(0x13) & 0x80) >> 5); // bit 2 + data |= ((readData(0x02) & 0x40) >> 3); // bit 3 + return data; +} + + +bool KT0803::setPHTCNST(bool on) +{ + uint8_t data = readData(0x02); + // is the bit already OK + if ((on == true) && (data & 0x01) == 0x01) return true; + if ((on == false) && (data & 0x01) == 0x00) return true; + // otherwise flip the bit + data = data ^ 0x01; + return writeData(0x02, data); +} + +bool KT0803::getPHTCNST() +{ + return (readData(0x02) & 0x01) > 0; +} + + +bool KT0803::setPilotToneAdjust(uint8_t mode) +{ + uint8_t data = readData(0x02); + // is the bit already OK + if ((mode == 1) && (data & 0x04) == 0x04) return true; + if ((mode == 0) && (data & 0x04) == 0x00) return true; + // otherwise flip the bit + data = data ^ 0x04; + return writeData(0x02, data); +} + + +uint8_t KT0803::getPilotToneAdjust() +{ + return (readData(0x02) & 0x04) > 0; +} + + +bool KT0803::setMute(bool mute) +{ + uint8_t data = readData(0x02); + // is the bit already OK + if ((mute == true) && (data & 0x08) == 0x08) return true; + if ((mute == false) && (data & 0x08) == 0x00) return true; + // otherwise flip the bit + data = data ^ 0x08; + return writeData(0x02, data); +} + + +bool KT0803::getMute() +{ + return (readData(0x02) & 0x08) > 0; +} + + + + +/////////////////////////////////////////////////////////////////////// +// +// PROTECTED +// +bool KT0803::writeData(uint8_t reg, uint8_t data) +{ + _wire->beginTransmission(_address); + _wire->write(reg); + _wire->write(data); + return (_wire->endTransmission() == 0); +} + + +int KT0803::readData(uint8_t reg) +{ + _wire->beginTransmission(_address); + _wire->write(reg); + _wire->endTransmission(); + + if (_wire->requestFrom(_address, (uint8_t) 1) == 1) + { + uint8_t data = _wire->read(); + return data; + } + return -1; +} + + +// -- END OF FILE -- + diff --git a/libraries/KT0803/src/KT0803.h b/libraries/KT0803/src/KT0803.h new file mode 100644 index 00000000..e92f95f5 --- /dev/null +++ b/libraries/KT0803/src/KT0803.h @@ -0,0 +1,80 @@ +#pragma once +// +// FILE: KT0803.h +// AUTHOR: Rob Tillaart +// VERSION: 0.1.0 +// PURPOSE: Arduino Library for KT0803 FM transmitter +// URL: https://github.com/RobTillaart/KT0803 + + +#include "Arduino.h" +#include "Wire.h" + + +#define KT0803_LIB_VERSION (F("0.1.0")) + + +class KT0803 +{ +public: + KT0803(TwoWire * wire = &Wire); + + bool begin(); + bool isConnected(); + + + // FM FREQUENCY + bool setFrequency(float frequency); + float getFrequency(); + bool setChannel(uint16_t channel); + uint16_t getChannel(); + + + // GAIN + bool setPGA(uint8_t pga); // 0-3 = 0..-12dB 4-7 = 0..12dB + // 111: 12dB + // 110: 8dB + // 101: 4dB + // 100: 0dB + // 000: 0dB + // 001: -4dB + // 010: -8dB + // 011: -12dB + uint8_t getPGA(); + + bool setRFGain(uint8_t rfgain); + uint8_t getRFgain(); + + + // REGION SELECTION + // first four are wrappers + void setEurope() { setPHTCNST(true); }; + void setAustralia() { setPHTCNST(true); }; + void setUSA() { setPHTCNST(false); }; + void setJapan() { setPHTCNST(false); }; + bool setPHTCNST(bool on); + bool getPHTCNST(); + + + // PILOT TONE ADJUST (PLTADJ) + bool setPilotToneAdjust(uint8_t mode); // HIGH = 1 LOW = 0 + uint8_t getPilotToneAdjust(); + + + // MUTE software + bool setMute(bool mute); // true == muted + bool getMute(); // isMuted(). + + +protected: + + bool writeData(uint8_t reg, uint8_t data); + int readData(uint8_t reg); + + uint8_t _address = 0x3E; // fixed address for KT0803. + TwoWire * _wire = NULL; +}; + + +// -- END OF FILE -- +