TinkerCAD Ardunio code error too few arguments - arduino-c++

I'm building a robot for my class, and we have to have 2 servos and 1 DC motor working in a specific way. Everything is hooked up to an arduino uno, and my code works, but I using tinkercad to test a few things but I'm getting an error which is stopping my code from functioning in tinker cad, and I'm at a total loss.
ERROR
In function 'void loop()':
44:9: error: too few arguments to function 'void motor(char, char)'
17:6: note: declared here
exit status 1
CODE
#include <Servo.h> // set servo header to let ardduino know you intend to use a servo
Servo mycontinuousservo; // declare servos to be used
Servo mydegreeservo;
int In1 = 7; // declare your global variables to indicate pin numbers
int In2 = 8;
int pin = 6;
int servocontinuouspin = 10;
int servodegreepin = 9;
int angle = 90;
void servopos();
void servocontinous();
void motor(char Speed,char Direction);
void setup() {
// put your setup code here, to run once:
pinMode(In1, OUTPUT);
pinMode(In2, OUTPUT);
pinMode(pin, OUTPUT);
digitalWrite(In1, HIGH); //pin 7 moves forward
digitalWrite(In2, LOW); //pin 8 moves forward
analogWrite(pin, 0); // start at 0
pinMode(servocontinuouspin, OUTPUT);
pinMode(servodegreepin, OUTPUT);
mycontinuousservo.attach(servocontinuouspin);
mydegreeservo.attach(servodegreepin);
mycontinuousservo.write(90);
Serial.begin(9600); // for serial communication
}
void loop() {
servocontinous(); //call by ref aforedeclared functions
servopos();
motor();
}
// EXIT THE LOOP
void servopos() { //position function
int degree = 0;
int i = 0;
for (i = 0; i < 18; i++) {
mydegreeservo.write(degree);
delay(500); //delay 0.5 seconds
degree = degree + 10;
}
}
void servocontinous() // continous servo settings
{
for (int angle = 90; angle >= 0; angle--) {
mycontinuousservo.write(angle);
delay(50);
}
if (angle == 0) {
Serial.print("speed\n");
}
for (angle = 0; angle < 90; angle++)
{
mycontinuousservo.write(angle);
delay(50);
}
}
void motor() //motor function
{
char Speed = 0;
char Direction = 0;
if (Serial.available() > 0) //initialising
{
if (Direction == 'f') //70 representing F on the ASCII table
{
delay(500);
Serial.println("F");
}
if (Direction == 'r')
{
delay(500);
Serial.println("R");
}
}
if (Serial.available() > 0)
{
Speed = Serial.read();
if (Speed == '0')
{
Speed = 0;
Serial.println("Speed 0");
}
if (Speed == '1')
{
Speed = 14;
Serial.println("Speed 1");
}
if (Speed == '2')
{
Speed = 29;
Serial.println("Speed 2");
}
if (Speed == '3')
{
Speed = 42;
Serial.println("Speed 3");
}
if (Speed == '4')
{
Speed = 56;
Serial.println("Speed 4");
}
if (Speed == '5')
{
Speed = 70;
Serial.println("Speed 5");
}
if (Speed == '6')
{
Speed = 84;
Serial.println("Speed 6");
}
if (Speed == '7')
{
Speed = 98;
Serial.println("Speed 7");
}
if (Speed == '8')
{
Speed = 112;
Serial.println("Speed 8");
}
if (Speed == '9')
{
Speed = 128;
Serial.println("Speed 9");
}
} delay(5000);
analogWrite(pin, Speed);
if (Direction == 'f')
{ digitalWrite(In1, HIGH);
digitalWrite(In2, LOW);
} if (Direction == 'r')
{
digitalWrite(In1, LOW);
digitalWrite(In2, HIGH);
}
}

Here you declare the function as taking two arguments:
void motor(char Speed,char Direction);
Later you call it with no arguments, which is invalid when compared to that declaration:
motor();
This will be an immediate compiler error. That function is described as having two arguments, you call it with zero. Compile hard fails and stops because of this contradiction.
Yet when you define it the arguments are gone, they're actually local variables:
void motor() //motor function
{
char Speed = 0;
char Direction = 0;
// ...
}
This too contradicts the earlier declaration, so if you comment out the place where it's called you'll likely get a different error.
Local variables are the private business of a function, they do not need to be shown in the function signature, so don't think these need to be included as arguments.
What you need to do is either snip the arguments from the declaration, make sure that declaration matches the function signature exactly, or move the motor() function definition to before where it is first called.
I prefer to organize things so that pre-declaration is not necessary, or at least minimized. There's no reason to not put the motor() definition before loop().

Related

Changing signal on every posedge of clock in SC_THREAD

I want to implement module, which when is called to work changes signal x the way below:
1 clk pos.edge : x = 0 // 1st phase
2 clk pos.edge : x = 0 // 2nd phase
3 clk pos.edge : x = 1 // 3rd phase
And then stops until called again.
I have function foo() in my module, which is called from main and allows thread work_foo() to execute on the posedge of clock.
I tried to do it this way (with wait()), and in some simple test it gives right wave, but it is an inappropriate way: my_module.h:
#include "systemc.h"
SC_MODULE (my_module)
{
sc_in <bool> clk;
sc_out <sc_logic> x;
sc_signal <bool> valid;
void foo()
{
valid = 1;
return;
}
void work_foo()
{
while (true)
{
if (valid == 1)
{ // foo() was called
if (phase == 0)
{
x = SC_LOGIC_0;
wait(); // waiting for the next tick
x = SC_LOGIC_0;
wait(); // waiting for the next tick
x = SC_LOGIC_1;
wait(); // waiting for the next tick
}
else
{
valid=0;
wait();
}
}
}
SC_HAS_PROCESS(my_module);
my_module(sc_module_name name):
sc_module(name),
clk("clk"), x("x"), valid("valid")
{
SC_THREAD(work_foo);
//dont_initialize();
sensitive<<clk.pos();
valid=0;
}
};
main.cpp:
#include "systemc.h"
#include "my_module.h"
int sc_main (int argc, char* argv[])
{
sc_clock clock("clock", 10, SC_NS);
sc_signal<sc_logic > x;
my_module mm("my_mod");
mm.clk(clock);
mm.x(x);
mm.foo ();
sc_start(200, SC_NS);
sc_stop();
return 0;
}
And now I'm trying to implement it another way. I was advised to use additional sc_signal (or variable) in my module, which indicates the incrementing number of the phase. The problem is what this gets looped at the very start. How can I solve this?
#include "systemc.h"
SC_MODULE (my_module)
{
sc_in <bool> clk;
sc_out <sc_logic> x;
sc_signal <bool> valid;
sc_signal <uint> phase;
void foo()
{
valid = 1;
return;
}
void work_foo()
{
while (true)
{
if (valid == 1)
{
if (phase == 0)
{
x = SC_LOGIC_0;
phase=phase+1;
}
else if (phase == 1)
{
x = SC_LOGIC_0;
phase=phase+1;
}
else if (phase == 2)
{
x = SC_LOGIC_1;
phase=phase+1;
}
}
else
{
phase=0;
valid=0;
wait();
}
}
}
SC_HAS_PROCESS(my_module);
my_module(sc_module_name name):
sc_module(name),
clk("clk"), x("x"), valid("valid")
{
SC_THREAD(work_foo);
//dont_initialize();
sensitive<<clk.pos();
valid=0;
phase=0;
}
};

Error: Failed to read audio(pocketsphinx + espeak)

I am trying to recognize voices from microphone by pocketsphinx and pass it through espeak to say what it recognized in real-time/continuous speech(I mean user says a word/sentence, pocketsphinx will recognize it and collects it inside char* hyp, then passes the hyp to speech() function that uses espeak to say what is inside the hyp. But I don't know why do I get
Failed to read audio
In this part of the code:
if ((k = ad_read(ad, adbuf, 2048)) < 0)
E_FATAL("Failed to read audio\n");
This is the complete code:
static ps_decoder_t *ps;
static cmd_ln_t *config;
static FILE *rawfd;
ad_rec_t *ad;
char *hyp;
espeak_POSITION_TYPE position_type;
espeak_AUDIO_OUTPUT output;
char *path=NULL;
int Buflength = 2048, Options=0;
void* user_data;
char Voice[] = {"English"};
unsigned int Size,position=0, end_position=0, flags=espeakCHARS_AUTO, *unique_identifier;
t_espeak_callback *SynthCallback;
espeak_PARAMETER Parm;
static void after_speech()
{
espeak_Synth( hyp, Size, position, position_type, end_position, flags,unique_identifier, user_data );
espeak_Synchronize( );
ad_start_rec(ad);
}
int receive_espeak_events(short *wav, int numsamples, espeak_EVENT *event)
{
while (event->type != espeakEVENT_LIST_TERMINATED)
{
if (event->type == espeakEVENT_MSG_TERMINATED)
{
after_speech();
}
++event;
}
return 0;
}
static void initFuncs()
{
espeak_Initialize(output, Buflength, path, AUDIO_OUTPUT_PLAYBACK ); //AUDIO_OUTPUT_SYNCHRONOUS ); //Options );
espeak_SetVoiceByName(Voice);
}
static void sleep_msec(int32 ms)
{
struct timeval tmo;
tmo.tv_sec = 0;
tmo.tv_usec = ms * 1000;
select(0, NULL, NULL, NULL, &tmo);
}
static void speech(char* hyp)
{
Size = strlen(hyp)+1;
espeak_SetSynthCallback(receive_espeak_events);
}
static void recognize_from_microphone()
{
int16 adbuf[2048];
uint8 utt_started, in_speech;
int32 k;
if ((ad = ad_open_dev(cmd_ln_str_r(config, "-adcdev"),(int) cmd_ln_float32_r(config,"-samprate"))) == NULL)
E_FATAL("Failed to open audio device\n");
if (ad_start_rec(ad) < 0)
E_FATAL("Failed to start recording\n");
if (ps_start_utt(ps) < 0)
E_FATAL("Failed to start utterance\n");
utt_started = FALSE;
E_INFO("Ready....\n");
for (;;)
{
if ((k = ad_read(ad, adbuf, 2048)) < 0)
E_FATAL("Failed to read audio\n");
ps_process_raw(ps, adbuf, k, FALSE, FALSE);
in_speech = ps_get_in_speech(ps);
if (in_speech && !utt_started)
{
utt_started = TRUE;
E_INFO("Listening...\n");
}
if (!in_speech && utt_started)
{
ps_end_utt(ps);
hyp = (char*)ps_get_hyp(ps, NULL );
if (hyp != NULL)
{
ad_stop_rec(ad);
speech(hyp);
printf("%s\n",hyp);
fflush(stdout);
// sleep_msec(3000);
}
if (ps_start_utt(ps) < 0)
E_FATAL("Failed to start utterance\n");
utt_started = FALSE;
E_INFO("Ready....\n");
}
}//for loop
ad_close(ad);
}
int main(int argc, char *argv[])
{
initFuncs();
config = cmd_ln_init(NULL, ps_args(), TRUE,
"-hmm", "/home/m/myrobot3/robot/model_parameters/robot.cd_cont_1000",
"-lm","/home/m/myrobot3/robot/etc/robot.lm.bin",
"-dict", "/home/m/myrobot3/robot/etc/robot.dic",
NULL);
ps = ps_init(config);
recognize_from_microphone();
ps_free(ps);
cmd_ln_free_r(config);
return 0;
}
NOTE: I used espeak_SetSynthCallback(receive_espeak_events); because I must pause the pocketsphinx's listening to new voices, until the espeak ends speaking of the previous recognized voice. So I tried to ad_stop_rec(ad); after finding a new hyp() inside the for(;;) loop, then tried to ad_start_rec(ad); when espeakEVENT_MSG_TERMINATED happened inside the receive_espeak_events callback.

Breaking a while loop in Arduino

I have a program that moves a stepper motor to the right, left and have a stop button that stops the motor. In one part of my program, a motor gradually lowers a speed and stops after a certain period of time iv.
The problem is that in this part of a program (when a motor gradually lowers a speed and then stops) I can’t stop the motor upon pressing a stop button. I understand that I need to break a while loop somehow, but using a break statement doesn't wort for me.
Do you have some ideas?
Here is my function:
/* --- STEPPER MOTOR ---*/
const int motor_step = 3;
const int motor_dir = 4;
int stepSpeed = 0;
int stepMaxSpeed = 1000;
int fadeAmount = 100;
int fadeDelay = 10;
/* ---- STOP BUTTON ---- */
int buttonStop = 5;
int stateStop=0;
void setup() {
.
.
.
stateStop = digitalRead(buttonStop);
}
void loop () {
.
.
.
myfunc();
}
void myfunc() {
if(stateStop == HIGH) {noTone(motor_step); stepSpeed = 0;}
elapsedMillis te;
unsigned int iv = 1500;
while (te < iv) {
if(stepSpeed == stepMaxSpeed) {
stepSpeed = stepSpeed+0;
tone(motor_step,stepSpeed);
digitalWrite(motor_dir,HIGH);
}
else {
stepSpeed = stepSpeed + fadeAmount;
tone(motor_step,stepSpeed);
digitalWrite(motor_dir,HIGH);
delay(fadeDelay);
}
if(stateStop == HIGH) { stepSpeed = 0; break;}
}
if(stepSpeed == stepMaxSpeed) {
while(stepSpeed>0){
stepSpeed = stepSpeed-fadeAmount;
tone(motor_step,stepSpeed);
digitalWrite(motor_dir,HIGH);
delay(fadeDelay);
if(stateStop == HIGH) { stepSpeed = 0; break;}
}
}
stepSpeed = 0;
noTone(motor_step);
digitalWrite(enable,LOW); // enable changed from HIGH
}
Your break condition does never trigger as stateStop is never being updated inside your while loop. How is your program supposed to know? It's busy running the loop and does not care about anything outside it's scope.
Check the button state inside the while loops or use interrupts

PubSubClient & ArduinoJSON - Arduino passing char to digitalWrite

I am not sure how to pass the values in the function in order to be used within the digitalWrite functions.
I'm getting the following error:
error: cannot convert 'String' to 'uint8_t' {aka unsigned char}' for argument '1' to 'void digitalWrite(uint8_t, uint8_t)'
pubsub callback
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("New message on [");
Serial.print(topic);
Serial.print("] ");
Serial.println("");
char s[length];
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
s[i]=payload[i];
}
StaticJsonBuffer<500> jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(s);
if (!root.success()) {
Serial.println("parseObject() failed");
}
String relay = root["relay"]; // "relayOne"
int time = root["timestamp"]; // 1351824120
String trigger = root["trigger"]; // "ON"
// Feel free to add more if statements to control more GPIOs with MQTT
commander(relay, trigger);
}
commander function
void commander(String relay, String trigger) {
if(trigger == "ON"){
Serial.print("Turning ");
Serial.println(relay);
Serial.println(" on");
digitalWrite(relay, HIGH);
} else if(trigger == "OFF"){
Serial.println(relay);
digitalWrite(relayOne, LOW);
Serial.print("TRIGGERED!");
} else {
// turn all the LEDs off:
for (int pin = 0; pin < relayPinCount; pin++) {
digitalWrite(relayPins[pin], LOW);
}
}
Serial.println();
}
void commander(String relay, String trigger) {
uint8_t pinNo;
if ( relay == "relayOne" ) {
pinNo = RELAY_1_PIN;
} else
if ( relay == "anotherRelay" ) {
pinNo = OTHER_RELAY_PIN;
} else
if ( ... ) {
...
} else {
return;
}
if(trigger == "ON"){
Serial.print("Turning ");
Serial.println(relay);
Serial.println(" on");
digitalWrite(pinNo, HIGH);
} else if(trigger == "OFF"){
Serial.println(relay);
digitalWrite(pinNo, LOW);
Serial.print("TRIGGERED!");
} else {
// turn all the LEDs off:
for (int pin = 0; pin < relayPinCount; pin++) {
digitalWrite(relayPins[pin], LOW);
}
}
Serial.println();
}

Serial.Event() only runs once (using single char input)

On my Arduino Mega 2560, I'm trying to run a motor that turns a 20-vial container (accepting int input 1-20) while regulating temperature via PID of a separate cooler. I am generally new to this field of technology so bear with me. I also have an interrupt set up for an encoder to keep track of vial position.
The void serialEvent() and void loop() are the most important portions to look at, but I decided to put the rest of the code in there just in case you needed to see it.
#include <PID_v1.h>
#include <SPI.h>
#include <TMC26XStepper.h>
#define COOL_INPUT 0
#define PIN_OUTPUT 9
TMC26XStepper tmc26XStepper = TMC26XStepper(200,5,7,6,500);
int step = 6;
int value;
int i;
char junk = ' ';
volatile long enc_count = 0;
const byte interruptPinA = 2;
const byte interruptPinB = 3;
//Define Variables we'll be connecting to
int outMax = 255;
int outMin = -145;
double Setpoint, Input, Output;
double heatInput, heatOutput, originalInput;
//Specify the links and initial tuning parameters
// AGGRESSIVE VALUES (to get to 4 deg C)
double aggKp=8.0, aggKi=3.0, aggKd=0.15;
// CONSERVATIVE VALUES (to hover around 4 deg C)
double consKp=2.5, consKi = 0.0, consKd = 1.0;
PID myPID(&Input, &Output, &Setpoint, aggKp, aggKi, aggKd, REVERSE);
void setup()
{
pinMode(step, OUTPUT);
pinMode(interruptPinA, INPUT_PULLUP);
pinMode(interruptPinB, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPinA), encoder_isr, CHANGE);
attachInterrupt(digitalPinToInterrupt(interruptPinB), encoder_isr, CHANGE);
//initialize the variables we're linked to
Input = (5.0*analogRead(COOL_INPUT)*100.0) / 1024;
Setpoint = 10.75;
myPID.SetOutputLimits(outMin, outMax);
//turn the PID on
myPID.SetMode(AUTOMATIC);
Serial.begin(115200);
tmc26XStepper.setSpreadCycleChopper(2,24,8,6,0);
tmc26XStepper.setMicrosteps(32);
tmc26XStepper.setStallGuardThreshold(4,0);
Serial.println("...started...");
tmc26XStepper.start();
Serial.flush();
Serial.println("Enter vial numbers 1-20");
}
void loop() {
Input = (5.0*analogRead(COOL_INPUT)*100.0) / 1024;
// A BUNCH OF CODE FOR TEMP REGULATION
Serial.println(Input);
delay(150);
}
void serialEvent() {
while (Serial.available() == 0) {}
i = Serial.parseInt();
Serial.print("position: ");
Serial.print(i);
Serial.print(" ");
while (Serial.available() > 0) {
junk = Serial.read();
}
if (i == 1) {
value = 0;
} else {
int num = i - 1;
value = num * 72;
}
while (enc_count != value) {
digitalWrite(6, HIGH);
delayMicroseconds(100);
digitalWrite(6, LOW);
delayMicroseconds(100);
if (enc_count == 1440) {
enc_count = 0;
}
}
Serial.println(enc_count);
}
// INFO FOR ENCODER
void encoder_isr() {
static int8_t lookup_table[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
static uint8_t enc_val = 0;
enc_val = enc_val << 2;
enc_val = enc_val | ((PIND & 0b1100) >> 2);
enc_count = enc_count + lookup_table[enc_val & 0b1111];
}
So, originally I had the two processes tested separately (vial position + encoder, then temperature regulation) and everything did exactly as it was supposed to. Now, I fused the code together and stored the vial position entry in the serialEvent() method to keep the temperature reading continuous and the vial position entry available for whenever I decided to provide input. However, when I put in a value, the program stops all together. I am able to see the number I entered (position: 5), but the Serial.println(enc_count) never gets printed. On top of the that, the temperature readings stop displaying readings.
Any thoughts? Need more information?