I think I got myself in over my head.

Hey, all. First off, thank you for taking the time to read my topic and if you help, Thank you!.. I am new to the world of arduino and coding. How new? I picked up my first book last Friday from barns and noble and started trying to code on Sunday. So VERY new. I want to learn coding and I am starting to understand it. Now, my problem is the language I understand parts but its like learning a new language. You may know bits and pieces until someone that knows the language starts speaking it. :astonished: :drooling_face: :~

So a little background on the project. I am trying to create a proof of concept for an idea that will help third world countries keep wells clean and from wasting water. It’s a long story and I summed it up in one sentence. Now, I want to do this small scale before I try this on a real well that is a life line of a village.

The first part to my idea is a wireless rotary encoder sending through a arudino nano via 433mhz transmitter to another arudio nano controlling a motor (For the time being a servo). Now, the first part is why am I using a nano. I need to keep the unit as small as possible and as cheap as possible. If its not possible ill change to a uno or a mega and xbees. REMEMBER this is a proof of concept.

So I been spending hours and hours and hours looking up codes and trying to learn what everything does. I came up with this code below. This is for the transmitter.

First off I changed the transmitting and receiving pin and am using the encoder on another pin

/* Digital IO pin that will be used for receiving data from the receiver */
const int RX_DIO_Pin = 1;
int encoder0PinA = 13;
int encoder0PinB = 14;

so I can save my intercepts for another part of the project.

#include <VirtualWire.h>

/* Rotary encoder read  */
int encoder0PinA = 13;
int encoder0PinB = 14;
volatile int encoder0Pos = 0;
volatile int encoder0PinALast = LOW;
volatile int n = LOW;
int valNew = 0;
int valOld = 0;
volatile int m = LOW;
int pos = 0;

 
void setup()
{
  /* Setup encoder pins as inputs */
  pinMode(encoder0PinA, INPUT);
  digitalWrite(encoder0PinA, HIGH);
  pinMode(encoder0PinB, INPUT);
  digitalWrite(encoder0PinB, HIGH);
  Serial.begin(9600);
  attachInterrupt(1, CountA, CHANGE);
  attachInterrupt(0, StateB, FALLING);
  vw_setup(2000);            
  vw_set_tx_pin(2); //Tx Pin 
}
 
void loop()
{
 encoder0PinALast = n;
 valNew = encoder0Pos;
 if (valNew != valOld) {
   pos = encoder0Pos;
   Serial.print(pos, byte(0));
   valOld = valNew;
   
   
  // send message
  vw_send((uint8_t *)encoder0Pos, 1);
  vw_wait_tx();                                          
  delay(100);

}
}
void CountA()
{
 n = digitalRead(encoder0PinA); 
 if ((encoder0PinALast == LOW) && (n == HIGH)) { 
   if (m == LOW) { 
     encoder0Pos--; 
   } 
   else { 
     encoder0Pos++; 
   } 
   if (encoder0Pos < 7){
     encoder0Pos = 7;
   }
   if (encoder0Pos > 176){
     encoder0Pos = 176;
   }
 }
}
void StateB()
{
 m = digitalRead(encoder0PinB);
}

For this part I understand most of it till I get to

  // send message
  vw_send((uint8_t *)encoder0Pos, 1);

I get confused there. I can’t figure out what I need to send. I know its the position of the encoder but I cant comprehend if its “encoder0pos” or “int pos”

Now the Receiver code is over my head. I know I can’t use servo.h with virtualwire so that is why I am using servotimer2.h. I know I need to map the encoder to be able to tell the servo where to be positioned but its not clicking for some reason. It looks off.

#include <ServoTimer2.h>
#include <VirtualWire.h>

ServoTimer2 myservo;  // create servo object to control a servo 
int pos = 0;    // variable to store the servo position 
/* Digital IO pin that will be used for receiving data from the receiver */
const int RX_DIO_Pin = 1;

void setup()
{
  Serial.begin(9600);
  Serial.println("setup");
  vw_setup(2000); // Bits per sec
  vw_rx_start();	// Start the receiver PLL running
  pinMode(6,OUTPUT);
  myservo.attach(9);
}

void loop()
{
  uint8_t buf[VW_MAX_MESSAGE_LEN];
  uint8_t buflen = VW_MAX_MESSAGE_LEN;
  if (vw_get_message(buf, &buflen)) // Non-blocking
  {
    int i;
    Serial.print("Got: ");
    for (i = 0; i < buflen; i  )
    {
      if(buf[i] == '1')
        {digitalWrite(6, HIGH);}
      else if(buf[i] == '0')
        {digitalWrite(6, LOW);}
      
      if(buf[i] != '0' && buf[i] != '1')
      {
        pos = buf[i];
        pos = map(pos,0,180,0,2000);
      }
      
      Serial.print(buf[i], HEX);
      Serial.print(" ");
      Serial.print(pos,DEC);
    }
    Serial.println("");
  }
  myservo.write(pos);
}

I am not expecting someone to rewrite the code. I want to learn to code but need people to point me in the right direction. Thank you all again.

What is the rotary encoder for? Does it need to detect direction of rotation or just rotation. How often will the values likely change and what is the resolution of the encoder.

Perhaps if you explained more. What does the encoder, and the motor do, to clean the well? And stop water wastage?

  1. Where did you get the code for driving the rotary encoder from? Are you sure it isn’t using one or both of the interrupts? If it is, you can’t change the pin numbers it uses.

  2. I believe the code you want is:

  // send message
  vw_send((uint8_t *)&pos, 2);

[EDIT: changed encoder0Pos to pos]

If you really are new to the Arduino system I strongly suggest that you break your concept into a series of small demonstration tasks which will allow you to learn how to manage the different parts. Later you will be able to combine the tasks into a full project. Trying to get the whole thing to work straight off is a recipe for frustration and failure.

Anything wireless is going to be very hard to debug unless you are very systematic because you can't tell if the wireless is working unless your code works.

...R

I second robin2's post, breaking it up into a series of individual parts is the best way to fully comprehend the project and not feel overwhelmed.

Let's get more clear about what the project entails. So what I understand is that you need two arduinos to communicate via 433MHz RF, one arduino has a rotary encoder and the other a servo. Is it safe to assume that the rotary encoder will be controlling the direction of the servo?

If you havent already learned about libraries and how to install them, I suggest you look into that.

Project 1 ~ Get a rotary encoder wired up and feeding data to the serial port. Get an understanding of the values it outputs.

Project 2 ~ Get a servo wired up and be able to control its angle. The servo library makes this as very easy, no need to install.

Project 3 ~ Connect two arduino boards with RF modules, for cost and testing purposed the nRF24l01 modules work well but for actual field use I would suggest something with better range. Get them communicating. The RF24 library by maniacbug has some great premade sketches to test them and learn how they work.

Project 4 ~ Mash it all up!

I've gotta say, this all sounds pretty ambitious for a beginner, for my first project, I had my work cut out for me just to get a few leds to blink with the mario song.

I would love to know how this is going to help prevent the wasting of water.