Wednesday, March 17, 2021

Arduino RadioHead (not the group) RH_NRF24 Transceiver

Nothing posted in 2020 - well it was that sort of year wasn't it?

Boredom having really set in, 2021 sees me in my Arduino playground. In fact I've been unfaithful and have been using an ESP32 recently, which is quite fun because it has WiFi capabilities - maybe a post about that to follow.

And all that WiFi stuff made me think about my previous delve into the world of radio and so on, using the ubiquitous NRF24L01 Transceiver Module. I bought some of these ages ago, spent days trying to get them to work, eventually succeeded, and, exhausted, then threw them in a box and moved on to something easier.

So, I find them lying in said box... let's have another go. So... I did the classic old-person thing of making all the same mistakes on this attempt as I did on the previous one, what an idiot. Eventually it dawned on me what was going wrong... like last time i had tried to use the TMRh20 library, nRF24L01.h and RF24.h, as nearly everyone seems to do. Trouble is... for me at least, it doesn't work. I mean I suppose it must work for most folk, but not me. No... it was only when I tried the RadioHead offering, RH_NRF24.h, that things started to fall into place. 

I am just not technically proficient enough to know why this is, but as soon as I changed to the RadioHead version, I got results. Here are pictures of my two Arduino/NRF24L01 combinations:



So, at the top we have a Nano, sitting in its IO Shield, which I heartily recommend for this type of job - because you simply plug the RF24 into it, no wires, wonderful. Attached is a little OLED display.

And the other picture shows an Arduino Mega with a handy but unnecessary shield on top, attached to an RF24 sitting in a little holder designed for it, again very recommended, because it's easier to wire up and can be powered by 5volts, avoiding the 3.3 volt limit on the RF24 module.

Now, here's the thing... this all seems very complicated and fraught. The wires you need to connect vary depending on your Arduino, and it all feels a bit of a black art. In the end I connected the right wires, but it took a bit of time. The Mega for example, uses pins 50, 51 and 52, the Nano completely different, whoever came up with all this wasn't making it easy!

Similarly, the code to get all this working really taxed my limited knowledge of C++ or whatever it is, my head was frequently in my hands, but in the end it all worked, see below.

What does it do? Well... the same code runs on both Arduinos. Each one is sending a random number every few seconds and receiving a random number from the other one too. The OLED display on one of them is showing that it has received its 1744th random number from its mate, 6591. What use is this? None that I can think of, but it's nice to know it can be done.

The code is below, if you need any advice, well I might be able to help you. But probably not. And a proper programmer will probably wince at the code. What is it with C++ and strings... type conversion in general, it's bonkers.
 
//-------------------------------------------------------------------------------
//
// Written by Paul Crossley 16/03/2021
//
// www.magmamon.co.uk
//
//-------------------------------------------------------------------------------
#include <SPI.h>
#include <RH_NRF24.h>

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET -1
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define SCREEN_ADDRESS 0x3C


RH_NRF24 nrf24(9,10);

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

int count = 0;
int recvd = 0;
int int_value;
unsigned char char_list[4];

boolean oled = true;
int repeat   = 20;
long rnd = 0;
union myRandU {long unsignedlongValue; uint8_t bytes[4];} myRand;

// --------------------------------------------------------------------

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(9600);
  Serial.println("RF24...");
  if (!nrf24.init()) { 
    Serial.println("init failed"); 
  } else { 
    Serial.println("init good"); 
  }
  if (!nrf24.setChannel(1)) {                                               
    Serial.println("setChannel failed"); 
  }  else { 
    Serial.println("setChannel good"); 
  }
  if (!nrf24.setRF(RH_NRF24::DataRate2Mbps, RH_NRF24::TransmitPower0dBm)) { 
    Serial.println("setRF failed"); 
  } else { 
    Serial.println("setRF good"); 
  }   

  if (oled) { 
    Serial.println("OLED...");
    if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { 
      Serial.println(F("SSD1306 allocation failed")); for(;;); 
    }
      
    display.clearDisplay();
    display.setTextSize(2);
    display.setTextColor(WHITE);
    display.setCursor(0,0);
    display.println("Listening!");
    display.display();
  }
  Serial.println("Ready!");
}

// --------------------------------------------------------------------

void loop() {

  digitalWrite(LED_BUILTIN, HIGH);
  count++;
  if (count==repeat) {
    rnd = random(0,9999);
    myRand.unsignedlongValue = rnd;
    nrf24.send(myRand.bytes, 4);
    nrf24.waitPacketSent();
    Serial.print("Sent : ");
    Serial.println(rnd);
    count=0;
  } else {
    Serial.print(".");
    uint8_t buf[RH_NRF24_MAX_MESSAGE_LEN];
    uint8_t len = sizeof(buf);
    while (nrf24.waitAvailableTimeout(200) && nrf24.recv(buf, &len)) {   
      Serial.print("Received : ");
      for (int i = 0; i < 4; i++) { char_list[i] = buf[i]; }
      memcpy(&int_value, char_list, 4);
      Serial.println(int_value);

      if (oled) { 
        recvd++;
        display.clearDisplay();
        display.setCursor(0,0);
        display.println("Listening!");
        display.setCursor(0,32);
        display.print(recvd);
        display.print(": ");
  //    display.print((char*)buf);
        display.print(int_value);
        display.display();
      }
    }      
  }
  digitalWrite(LED_BUILTIN, LOW);
  delay(100);
}

Friday, December 20, 2019

Arduino based Temperature/Humidity/Clock


Above is a Fritzing generated schematic of a project I've recently been working on for the Arduino Nano. The project uses a Real Time Clock component, a temperature/humidity sensor and a liquid crystal display. It is powered by a portable power bank.




The code for the project is shown below.

//-------------------------------------------------------------------------------
//
// Written by Paul Crossley 20/12/2019
//
// www.magmamon.co.uk
//
// Temperature/Humidity sensor on D8
// RTC and Display on A4 and A5
// my own personal temperature adjustment was -2C
// my display I2C address was 0x3F, use i2c-scanner 
//
//-------------------------------------------------------------------------------

#include <SimpleDHT.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <TimerOne.h>
#include <RTClib.h>

//-------------------------------------------------------------------------------

volatile unsigned int clockMilliSeconds = 0;
volatile byte clockSeconds = 0;
volatile byte clockMinutes = 0;
volatile byte clockHours = 12;
volatile byte clockEnabled = 1;
byte alarmMinutes = 30;
byte alarmHours = 6;
volatile byte alarmEnabled = false;
byte alarmTogglePressed = false;
enum displayModeValues
{
  MODE_CLOCK_TIME,
  MODE_CLOCK_TIME_SET_HOUR,
  MODE_CLOCK_TIME_SET_MINUTE,
  MODE_ALARM_TIME,
  MODE_ALARM_TIME_SET_HOUR,
  MODE_ALARM_TIME_SET_MINUTE
};
byte displayMode = MODE_CLOCK_TIME;
RTC_DS1307 RTC;

//-------------------------------------------------------------------------------

void clockISR ()
{
  if (clockEnabled)
  {
    clockMilliSeconds++;
    if (clockMilliSeconds >= 1000)
    {
      clockMilliSeconds = 0;

      clockSeconds++;
      if (clockSeconds >= 60)
      {
        clockSeconds = 0;

        clockMinutes++;
        if (clockMinutes >= 60)
        {
          clockMinutes = 0;

          clockHours++;
          if (clockHours >= 24)
          {
            clockHours = 0;
          }
        }
      }
    }
  }
}

//-------------------------------------------------------------------------------

LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
#define BACKLIGHT_PIN     13

int pinDHT11 = 8;
SimpleDHT11 dht11(pinDHT11);

int tempAdjust = -2;

byte degree[8] = {
  B01100,
  B10010,
  B10010,
  B01100,
  B00000,
  B00000,
  B00000,
};

void setup() {
  Serial.begin (9600);
  lcd.begin(16, 2);
  lcd.clear();
  lcd.createChar(0, degree);
  lcd.setBacklight(BACKLIGHT_ON);
  pinMode(LED_BUILTIN, OUTPUT);
  RTC.begin();
//  RTC.adjust(DateTime(__DATE__, __TIME__));  to set time
}

void loop() {

  byte temperature = 0;
  byte humidity = 0;
  int err = SimpleDHTErrSuccess;

  digitalWrite(LED_BUILTIN, HIGH);

  if ((err = dht11.read(pinDHT11, &temperature, &humidity, NULL)) != SimpleDHTErrSuccess) 
  {
    Serial.print("No reading , err="); Serial.println(err); delay(1000);
    return;
  }

  Serial.print("Temp: ");
  Serial.print((int)temperature); Serial.print("C, ");
  Serial.print("Humid: ");
  Serial.print((int)humidity); Serial.println("%");

  lcd.home();

  lcd.print ("T: ");
  if ((temperature + tempAdjust) < 10) { lcd.print (" "); }

  lcd.print ((int)temperature + tempAdjust);
  lcd.write (byte(0));
  lcd.print ("C   ");

  lcd.print ("H: ");
  if ((humidity) < 10) { lcd.print (" "); }
  lcd.print ((int)humidity);
  lcd.print ("%");

  delay (1000);
  digitalWrite(LED_BUILTIN, LOW);

  DateTime now = RTC.now();

  Serial.print(now.year(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.day(), DEC);
  Serial.print(' ');
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.println(); 

  lcd.setCursor ( 0, 1 );
  if (now.day() < 10) { lcd.print ("0"); }
  lcd.print ((int)(now.day()));
  lcd.print ("/");
  if (now.month() < 10) { lcd.print ("0"); }
  lcd.print ((int)(now.month()));
  lcd.print ("/");
  lcd.print ((int)(now.year()));
  lcd.print (" ");
  if (now.hour() < 10) { lcd.print ("0"); }
  lcd.print ((int)(now.hour()));
  lcd.print (":");
  if (now.minute() < 10) { lcd.print ("0"); }
  lcd.print ((int)(now.minute()));

  delay (1000);
}

Wednesday, October 10, 2018

Epiphone Pro-1 Plus Acoustic


My newest guitar (I must stop buying them now, I have too many - said nobody ever) is an Epiphone Pro-1 Plus, in 'Blueburst', or 'Trans Blue' - I'm not quite sure. It's blue anyway. You can get them in dark red, black, and two kinds of wood finish. I started off liking the red, then went to natural and ended up with blue, partly because it matched my Ibanez, see elsewhere. I expect they all sounds the same!

There are three levels, the Pro which is around £100 has no white binding and not such a good spruce top. Then the Pro as here £150, then the Pro Ultra which has electrics and a cutaway body, £200.

They all have a mahogany body, an okoume neck and a rosewood fingerboard. I guess I'll never know if the extra 50 quid was worth it for the better spruce top, but it looks a nice thing, and the binding sets off the blue nicely.

The tuners are said to be high quality and have a good turn ratio (or whatever that is called) and work well, though possibly not as good as all that, just okay.

It's supposed to be easy to play, with a good aspect neck and jumbo frets, and thin strings, though in truth I haven't really noticed it being that easy - maybe that's just me!

I got it for a good price, and also by chance really there was an offer on that month to get a free accessory pack with the guitar, which duly arrived a month later from Epiphone. It comprised a strap, strings, tuner, polishes, plectrums and so on, worth £40 - so I am happy with what I paid.


It is loud. I'm comparing it to my Ovation, and it is a lot louder than that. And the tone is good, not as harsh as the Ovation, sounds great.

The blue finish was blemish free, but I have noticed it picks up dust really easily, and scratches too, despite my care with it. Ironically my major complaint about the guitar is to do with scratches... the scratch plate. This was billed as being impervious to scratching, which it appears to be, the only trouble is to achieve that they have made it of a plastic without a shiny finish, more matt - and that (for me) generates a scratchy noise when playing from the nail of my little finger. I am having to adopt a new technique to avoid this, which I'd rather not. If I could return to a 'shiny scratch-plate that gets scratched' some how I would...

I'm also not convinced by the light gauge strings as supplied, they feel wrong somehow. I use them on my electrics, but here there's something a bit loose about them. I'll try heavier gauges next time.

Truth be told - I bought this because I was bit bored with my Ovation... but though this Epiphone is nice, it isn't as good as the Ovation. The Ovation is class. So no disrespect to the Epi. I just haven't bonded with it yet I guess.

Ignoring that, I'd give it thumbs up - I'm happy with it and build quality and sound is great.

Wednesday, January 31, 2018

Ibanez GIO GRG121DX

Here is my new Ibanez GIO GRG121DX, in Starlight Blue Sunburst.

It's a lovely thing. I got it reasonably cheaply on eBay, advertised as being brand new, an unwanted gift - and it turned out that was true, immaculate condition and it came with a great gig bag too.

 As far as I know it has a mahogany body and a maple neck, 24 fret rosewood fingerboard and IBZ-6 Humbucking pickups.

I'm not well versed with technicalities to be honest, all I know is that the action is great, and it sounds really good through my Fender Mustang 1 v2 amp.

You can't get simpler controls... well actually I guess you can, but one volume, one tone and a selector work nicely, and the tuners are precise, if a little too stiff.

Okay, I really wanted a red one, but the blue has grown on me, it's a lovely finish.

It's nicely weighted too, unlike for example my Epiphone SG which is very neck heavy.

All I need to do now is learn how to play it!

Two Years On - KIA pro_cee'd SE 1.6 CRDi



A second year has passed, and the KIA is still going strong. Cut to the chase, I still like it, it's not been any bother (almost) and it still looks as good as new, inside and out.

And we still haven't come with a name for it other then the KIA. It has now covered a modest 12,500 odd miles, pretty low I guess. It's done school runs (but not any more, now it's Uni runs) and toured around Dumfries and Galloway on holiday. Over all that distance it has returned 54mpg.

Looking back over my previous article, little has changed in truth. In a nutshell, the car itself is perfectly fine, the software in the car is a bit dubious. Looking back you will see I criticised the sat-nav, the air-con, the stop-start and key-less entry system. None of them work all that well, but you get used to it - I mean they all work, it's just not that easy to get them to work somehow.

If I was to be even more picky, during a recent visit to Pentraeth Automotive I was given a Picanto as a courtesy car. Not in the same league as the cee'd but I have to say the dash instruments were way better. The cee'd has a red display which isn't the clearest, the Picanto was white on black, much easier to read.

Ah, yes, why was I at the garage? Well, I pointed out when the car was being serviced a few weeks ago that the alloy wheels appeared to be suffering from corrosion, a bit early on a two year old car I thought. To everyone involved's credit, I was duly offered a complete new set! I was amazed. Thank you KIA.

Unfortunately (in a way) while swapping the wheels the mechanics spotted a bulge on one of my tyres, which required replacing, damn these pot-holes in all our roads, don't get me started.

Returning to the car then, the only other gripe I have is that the Traffic Announcement system on the radio has been a bit flaky. I asked them to sort it at the service and to be honest I've not been off Anglesey since, so I'm not sure if they've fixed it or not. A nuisance but not fatal.

So, looking at all the twaddle above I've done nothing but moan. So I should put that right - I actually DO like the car rather a lot and its solid build, 100% reliability and its frugality are commendable, long may it continue. And just one more thing to praise, it managed to accommodate three adults and a serious amount of clothing, computer equipment, guitars and general junk while transporting my lad off to Uni, in other words, it's actually bigger than it looks inside!