Sunday, October 19, 2014

Arduino Hellschreiber II

I modified the input circuit of my Hellschreiber Arduino project so I could feed it directly with audio from a receiver or other source. I replaced the electret mic with a 600:600 ohm isolation transformer. Yesterday (Saturday 10-18-2014) I recorded some of the Hellschreiber Sprint (2014-sprints) and the video below is a part of a QSO between Lou W8LEW and Bill WD9EQD before the contest on 20 meters. I recorded it using the WebSDR network and K2SDR receiver(s) in New Jersey.




Below is the complete circuit to feed the receiver audio into the Arduino for display. I am using three of the analog ports. One for the signal and two for pots to adjust the contrast of the signal on the display. Perhaps others will have better ideas of dealing with display adjustments and image processing. The cool thing is that Hellschreiber can be generated by a simple QRP CW transmitter and with the Arduino display and a simple direct conversion receiver, a portable Hellschrieber rig could be built. I am also thinking about a software based squelch that will pause the display when there is not a valid Hellschreiber signal present. This could be cool for beacons or short messages since the display holds over 2 minutes of receive output. You could then review transmissions that occurred hours ago.



Here is the code I am using currently. You will need to get the Seed 1.0 TFT library setup first and I suggest testing the display with the example code provided from Seed before trying my code. 73



 // Seven Line Hellscriber Painter  
   
 #include <stdint.h>  
 #include <TFT.h>  
   
 int analogPin = 5; // The audio input pin  
 int analogPot1 = 4; // Lower Limit Pot pin  
 int analogPot2 = 3; // Upper Limit Pot pin  
   
   
 int x, y, x2; // plotting varables  
 int sig = 0; // Audio signal varable   
 int pot1, pot2; // Analog pot values   
 int greendot, dot; // The Hellscrieber dot varables  
 int lower, upper; // Contrast mapped pot values  
   
   
   
   
 void setup()  
 {  
   
 Tft.init(); //init TFT library  
   
 }  
   
 void loop()  
 {  
  // Each Line is 28 pixels high  
  for (int y=0; y<320; y++)  
  {  
  for (int x=215-x2; x<229-x2; x++)  
  {  
   sig=analogRead(analogPin); // signal input  
   pot1=analogRead(analogPot1); //get lower limit  
   pot2=analogRead(analogPot2); //get upper limit  
     
   lower=map(pot1,0,1023,0,511); // map pot1 to lower range  
   upper=map(pot2,0,1023,512,1023); // map pot2 to upper range  
     
   dot=map(sig,lower,upper,0,63); // Signal mapped into 5 bits with a lower & upper limit for contrast  
     
   greendot= dot << 5; // shift the dot value into the green range of the display RGB 565  
     
   Tft.setPixel(x, y, greendot); // plot green dot  
   Tft.setPixel(x+13 ,y ,greendot); // plot sample green dot again shifted by 14 pixels  
     
   delayMicroseconds(3480L); // master time delay for Hellschreiber  
   
  }  
  }  
  x2=x2+35; // paint line offset with boundary to seperate each line with black space  
  if(x2>210) x2=0; // if seventh line, start at the top again  
 }  
   

4 comments:

  1. I've built this circuit up using an Arduino Due and a 3.2 inch 320x240 TFT display bought from China via eBay. It seems to work very well. Many thanks for publishing the interface and code.
    I found that the delay in the code loop needed to be adjusted to get a proper display. To help with this, I used IZ8BLY's Hellscreiber software to send a sequence of ++++++++++++ and fed the audio output from the laptop into your interface. I then adjusted the loop delay to give a none-sloping display. This gave an optimum delay value of 3680.
    73

    Barry, G8AGN

    ReplyDelete
    Replies
    1. Very Cool Barry, let us know if you make any more improvements! Thanks for the kind words! -Dan

      Delete
    2. Dan

      I found that the x and y origin on my display was slightly different to yours so had to modify your code a bit. I've also produced a "large font" version of the code which makes the displayed characters twice as big but this does mean less lines on the screen, 3 instead of 7. See code below:

      // Seven Line Hellscriber Painter WA6PZB
      // modified by G8AGN to use UTFT LCD library 8 March 2015
      // 14 March 2015 double size characters

      #include
      extern uint8_t BigFont[];

      int analogPin = 5; // The audio input pin
      int analogPot1 = 4; // Lower Limit Pot pin
      int analogPot2 = 3; // Upper Limit Pot pin

      // 2.4" 320x240 TFT display using ILI9325C controller
      //UTFT myGLCD(ITDB24,38,39,40,41);

      // 3.2" 320x240 TFT display using SSD1289 controller
      UTFT myGLCD(SSD1289,38,39,40,41);



      int x, y, y2=239; // plotting variables
      int sig = 0; // Audio signal variable
      int pot1, pot2; // Analog pot values
      int dot; // The Hellscrieber dot varable
      int lower, upper; // Contrast mapped pot values




      void setup()
      {
      myGLCD.InitLCD();
      myGLCD.clrScr();
      myGLCD.setFont(BigFont);
      int Xsize=myGLCD.getDisplayXSize();
      int Ysize=myGLCD.getDisplayYSize();
      Serial.begin(9600);
      Serial.print(Xsize);
      Serial.print(" ");
      Serial.println(Ysize);
      }

      void loop()
      {

      // Each Line is 28 pixels high
      for (int x=319; x>=1; x-=2)
      {
      for (int y=y2-30; y<y2; y+=2)
      {
      sig=analogRead(analogPin); // signal input
      pot1=analogRead(analogPot1); //get lower limit
      pot2=analogRead(analogPot2); //get upper limit

      lower=map(pot1,0,1023,0,511); // map pot1 to lower range
      upper=map(pot2,0,1023,512,1023); // map pot2 to upper range

      dot=map(sig,lower,upper,0,255); // Signal mapped into 8 bits with a lower & upper limit for contrast


      myGLCD.setColor(0, dot, 0);
      myGLCD.drawPixel(x,y); // plot green dot
      myGLCD.drawPixel(x-1,y);
      myGLCD.drawPixel(x,y-1);
      myGLCD.drawPixel(x-1,y-1);

      myGLCD.drawPixel(x,y-30); // plot sample green dot again shifted by 14 pixels
      myGLCD.drawPixel(x-1,y-30);
      myGLCD.drawPixel(x,y-31);
      myGLCD.drawPixel(x-1,y-31);
      delayMicroseconds(3320); // master time delay for Hellschreiber

      }
      }
      y2=y2-70; // paint line offset with boundary to separate each line with black space
      if(y2<30)
      {
      y2=239; // if seventh line, start at the top again
      myGLCD.clrScr();
      }
      }


      73
      Barry, G8AGN

      Delete
  2. Barry,

    It seems your schematic link has died. Is there any chance you could upload it somewhere?

    73 de KK6POR

    ReplyDelete