aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Embedded_SW/Embedded/Modules/IDS
diff options
context:
space:
mode:
authorShlomo Hecht <shlomo@twine-s.com>2019-04-02 15:16:32 +0300
committerShlomo Hecht <shlomo@twine-s.com>2019-04-02 15:16:32 +0300
commit3f6aecd92ceca69ffa5fc07ea0bbe93fd4097c85 (patch)
treea0e69764fe4eca3fc445f44e1f963a2a72e4327f /Software/Embedded_SW/Embedded/Modules/IDS
parent3713f74d0d811b869af5522a576e36f7e6a0ed2e (diff)
downloadTango-3f6aecd92ceca69ffa5fc07ea0bbe93fd4097c85.tar.gz
Tango-3f6aecd92ceca69ffa5fc07ea0bbe93fd4097c85.zip
Embedded SW Release note - Version 1.3.8.2
File upload: prevent on job, reduce priority (watchdog) Report: packages filters introduced, please feel free to use them. robustness in communication improved large number of segments and gradient support - initial at the end of job the screw does not return back rockers - adjust values before and after loading the cart
Diffstat (limited to 'Software/Embedded_SW/Embedded/Modules/IDS')
-rw-r--r--Software/Embedded_SW/Embedded/Modules/IDS/IDS.h1
-rw-r--r--Software/Embedded_SW/Embedded/Modules/IDS/IDS_dispenser.c2
-rw-r--r--Software/Embedded_SW/Embedded/Modules/IDS/IDS_ex.h3
-rw-r--r--Software/Embedded_SW/Embedded/Modules/IDS/IDS_maint.c2
-rw-r--r--Software/Embedded_SW/Embedded/Modules/IDS/IDS_print.c689
5 files changed, 543 insertions, 154 deletions
diff --git a/Software/Embedded_SW/Embedded/Modules/IDS/IDS.h b/Software/Embedded_SW/Embedded/Modules/IDS/IDS.h
index ba08101f8..80a55d63e 100644
--- a/Software/Embedded_SW/Embedded/Modules/IDS/IDS.h
+++ b/Software/Embedded_SW/Embedded/Modules/IDS/IDS.h
@@ -5,6 +5,7 @@
#include "drivers/motors/motor.h"
#include "ids_ex.h"
+extern uint32_t CurrentDispenserSpeed[MAX_SYSTEM_DISPENSERS];
extern uint32_t DispenserIdToMotorId[MAX_SYSTEM_DISPENSERS];
extern float DispenserPressure[MAX_SYSTEM_DISPENSERS];
uint32_t DispenserConfigMessage(HardwareDispenser * request);
diff --git a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_dispenser.c b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_dispenser.c
index 0fcd73b59..3eaa2f9c2 100644
--- a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_dispenser.c
+++ b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_dispenser.c
@@ -238,7 +238,7 @@ void IDS_Dispenser_Content_Init (void)
IDS_Dispenser_Data[i].has_nanolitterperpulse = true;
}
free (buffer);
- dispenser_data__free_unpacked(NULL,StoredDispenserData);
+ dispenser_data__free_unpacked(StoredDispenserData,NULL);
}
return;
diff --git a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_ex.h b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_ex.h
index ded3642a0..2e8d33e1a 100644
--- a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_ex.h
+++ b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_ex.h
@@ -33,6 +33,8 @@ extern bool EnableLubrication;
extern bool EnableIntersegment;
extern double IntersegmentLength;
+extern bool DispenserUsedInJob[MAX_SYSTEM_DISPENSERS];
+bool IDS_MapDispenserUsedinJob(void *JobDetails);
void IDS_ModuleInit (void);
void Calculateinit(void);
@@ -68,6 +70,7 @@ uint32_t IDS_Dispenser_Start_Motor_and_Open_Valve(int DispenserId, int MotorSpee
void IDS_Dispenser_Content_Calculation (char DispenserId);
+uint32_t IDS_MapDispenserUsedinFileJob(void *JobDetails);
float CalculateDispenserPressure (int DispenserId);
float GetDispenserPressure(int DispenserId);
diff --git a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_maint.c b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_maint.c
index 9e9c82131..1bdf15b29 100644
--- a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_maint.c
+++ b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_maint.c
@@ -84,7 +84,6 @@ uint32_t IDS_HomeDispenserBackMoveCallback(uint32_t deviceID, uint32_t ReadValue
if ((GetDispenserPressure(DispenserId)>=InitialDispenserPressure)||(DispenserHomingTime[DispenserId]>InitialDispenserTimeout))
{
MotorStop(deviceID,Hard_Hiz);
-
MotorSetMicroStep(deviceID, MotorsCfg[deviceID].microstep);
HomingActive[DispenserId]= false;
Report("End backlash",__FILE__,millisecondCounter,(int)DispenserId,RpWarning,(int)DispenserHomingTime[DispenserId],0);
@@ -169,6 +168,7 @@ uint32_t IDS_Dispenser_Alarm_On (uint8_t deviceID)
Enable_MidTank_Pressure_Reading(deviceID);
status |= MotorSetMicroStep(deviceID, MotorsCfg[deviceID].microstep);
status |= MotorStop(deviceID, Hard_Hiz);
+ JobEndReason = JOB_OUT_OF_DYE;
return status;
}
uint32_t IDS_Dispenser_Alarm_Off (uint8_t deviceID)
diff --git a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_print.c b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_print.c
index 38c139141..d868354dd 100644
--- a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_print.c
+++ b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_print.c
@@ -12,10 +12,18 @@
#include "../thread/thread.h"
#include "PMR/Hardware/Hardwaremotor.pb-c.h"
#include "PMR/Hardware/HardwareDispenser.pb-c.h"
+#include "PMR/Printing/JobDescriptionFileBrushStop.pb-c.h"
+#include "PMR/Printing/JobDescriptionFileSegment.pb-c.h"
+#include "PMR/Printing/JobUploadStrategy.pb-c.h"
+#include "PMR/Printing/JobSegment.pb-c.h"
+#include "PMR/Printing/JobTicket.pb-c.h"
#include "StateMachines/Printing/printingSTM.h"
#include "drivers/motors/motor.h"
#include "drivers/valves/valve.h"
+#include "Common/SWUpdate/FileSystem.h"
+#include "drivers/Flash_Memory/fatfs/ff.h"
+
#include "modules/heaters/heaters.h"
#include "drivers/Flash_ram/FlashProgram.h"
@@ -33,7 +41,8 @@ typedef struct
}DispenserControlConfig_t;
HardwarePidControl *DispensersControl;// = (HardwarePidControl *)GENHWCFG_MAP_IN_FLASH + 0x4000;
#define LUBRICANT_DISPENSER 7
-#define MAX_DYE_DISPENSERS 7
+#define CLEANER_DISPENSER 7
+#define MAX_DYE_DISPENSERS 6
int32_t DispenserSamples[MAX_SYSTEM_DISPENSERS][MAX_CONTROL_SAMPLES] = {0};
int DispenserSamplePointer[MAX_SYSTEM_DISPENSERS] = {0};
double DispenserNormalizedErrorCoEfficient[MAX_SYSTEM_DISPENSERS] = {0};
@@ -45,7 +54,8 @@ bool IDS_Active = false;
/******************** STRUCTURES AND ENUMs ********************************************/
uint32_t IDS_Valve_DistanceToSpoolReady(uint32_t deviceID, uint32_t ReadValue);
uint32_t IDS_Valve_PresegmentReady(uint32_t deviceID, uint32_t ReadValue);
-bool IDS_isDispenserUsedNextSegment(void *JobDetails,int DispenserId, int SegmentId);
+uint32_t IDSBrushStopRestartCallback(uint32_t IfIndex, uint32_t readValue);
+//bool IDS_isDispenserUsedNextSegment(void *JobDetails,int DispenserId, int SegmentId);
/******************** GLOBAL PARAMETERS ********************************************/
DispenserControlConfig_t DispenserControlConfig[MAX_SYSTEM_DISPENSERS];
uint32_t ControlIdtoDispenserId [MAX_SYSTEM_DISPENSERS] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
@@ -122,7 +132,7 @@ void DispenserPrepareReady(void)
return; //not all configured Dispensers are ready
}
}
- REPORT_MSG(Module_IDS,"DispenserPrepareReady");
+ REPORT_MSG(Module_IDS,"All Dispensers Prepare Ready");
PrepareReady(Module_IDS,ModuleDone);
}
//********************************************************************************************************************
@@ -137,45 +147,296 @@ void DispenserPrepareReady(void)
return OK; // all configured heaters are ready
}
- bool IDS_MapDispenserUsedinJob(void *JobDetails)
+/*
+ void OpenJobFile();
+void CloseJobFile();
+JobDescriptionFileSegment *GetNextSegmentFromJobFile();
+void FreeSegmentFileData(JobDescriptionFileSegment *Segment);
+JobDescriptionFileBrushStop *GetNextBrushStopFromJobFile();
+void FreeBrushStopFileData(JobDescriptionFileBrushStop *BrushStop);
+
+ */
+ /************************************************************************************************************************************/
+ uint32_t IDS_MapDispenserUsedinFileJobshort(void *JobDetails)
+ {
+ JobDescriptionFileBrushStop *BrushStop;
+ JobDescriptionFileSegment *Segment;
+ int Dispenser_i, Brush_i,DispenserId;
+ FRESULT Fresult = FR_OK;
+ uint32_t status = OK;
+
+ for (Dispenser_i = 0;Dispenser_i<MAX_SYSTEM_DISPENSERS;Dispenser_i++)
+ {
+ DispenserUsedInJob[Dispenser_i] = false;
+ }
+ Fresult = OpenJobFile();
+ if (Fresult == FR_OK)
+ {
+ Segment = GetNextSegmentFromJobFile();
+ while(Segment)
+ {
+ if ((Segment->has_brushstopscount)&&(Segment->brushstopscount))
+ {
+ for (Brush_i=0;Brush_i<Segment->brushstopscount;Brush_i++)
+ {
+ BrushStop = GetNextBrushStopFromJobFile();
+ if (BrushStop)
+ {
+ if (BrushStop->n_dispensers)
+ {
+ for (Dispenser_i = 0;Dispenser_i < BrushStop->n_dispensers;Dispenser_i++)
+ {
+ //prepare the SW structures
+ DispenserId = BrushStop->dispensers[Dispenser_i]->index;
+ if (BrushStop->dispensers[Dispenser_i]->nanolitterpersecond>0.0)
+ {
+ DispenserUsedInJob[DispenserId] = true;
+ /*if(DispenserId == LUBRICANT_DISPENSER)
+ {
+ lubricant_speed = JobTicket->segments[0]->brushstops[0]->dispensers[Dispenser_i]->nanolitterpersecond/
+ JobTicket->segments[0]->brushstops[0]->dispensers[Dispenser_i]->nanoliterperpulse;
+ REPORT_MSG (lubricant_speed*100, "LUBRICANT_SPEED*100");
+ }*/
+ }
+ }//for dispenser
+ }//if dispensers
+ else
+ {
+ LOG_ERROR (BrushStop->index, "no dispensers in brushstop");
+ }
+ FreeBrushStopFileData(BrushStop);
+ BrushStop = NULL;
+ }
+ else
+ {
+ LOG_ERROR (BrushStop, "malloc error");
+ status = ERROR;
+ }
+ }//for brushstops
+ }// if brush stop count
+ FreeSegmentFileData(Segment);
+ Segment = GetNextSegmentFromJobFile();
+ }
+ FreeSegmentFileData(Segment);
+ CloseJobFile();
+ }
+ return status;
+
+ }
+ /************************************************************************************************************************************/
+ uint32_t IDS_MapDispenserUsedinFileJob(void *JobDetails)
{
JobTicket* JobTicket = JobDetails;
- int Dispenser_i, Segment_i,Brush_i,DispenserId;
+ uint8_t *SegmentPtr = 0, *BrushStopPtr = 0;
+ JobDescriptionFileBrushStop *BrushStop;
+ JobDescriptionFileSegment *Segment;
+ int Dispenser_i, Brush_i,DispenserId;
+ uint32_t Bytes = 0,readBytes = 0,ImmediateRead = 0,SegmentSize = 0,BrushStopSize = 0;
+ uint32_t status = OK;
+ FRESULT Fresult = FR_OK;
+ FIL *FileHandle = 0; //the system supports a single active file
+
+/*
+ Parsing the job description file.
+The job description file simply contains an array of segments and their brush stops.
+The job description file is meant to be read brush stop by brush stop while the job is in progress.
+The following diagram represents a single job description file segment structure.
+The process of reading the whole file is simply repeating that reading order.
+
+Each JobDescriptionFileSegment contains a “BrushStopsCount” field that should be used to determine how many brush stops are associated
+with the current segment and how many times the process of reading brush stops should be repeated.
+1. 32bit integer containing the next JobFileDescriptionSegment message byte count
+2. JobDescriptionFileSegment message
+3. 32bit integer containing the next JobDescriptionFileBrushStop message byte count
+4. JobDescriptionFileBrushStop message
+1. Read segment message length.
+2. Read segment message.
+a. Read brush stop message length.
+b. Read brush stop message.
+c. Go to step 2.a x Segment.BrushStopsCount.
+3. Go to step 1 until end of file.
+ */
for (Dispenser_i = 0;Dispenser_i<MAX_SYSTEM_DISPENSERS;Dispenser_i++)
{
DispenserUsedInJob[Dispenser_i] = false;
}
- if (JobTicket->n_segments == 0)
- return false;
+ n_segments = 0;
+ if (JobTicket->uploadstrategy == JOB_UPLOAD_STRATEGY__JobDescriptionFile)
+ {
+ FileHandle = my_malloc(sizeof(FIL));
- for (Segment_i=0;Segment_i<JobTicket->n_segments;Segment_i++)
+ Fresult = FileOpen(JobTicket->jobdescriptionfile, &Bytes, FileHandle);
+ if (Fresult == FR_OK)
{
- for (Brush_i=0;Brush_i<JobTicket->segments[Segment_i]->n_brushstops;Brush_i++)
+ while((readBytes < Bytes)&&(status == OK))
{
- if (JobTicket->segments[Segment_i]->brushstops[Brush_i]->n_dispensers)
+ Fresult = f_read(FileHandle,&SegmentSize,4,&ImmediateRead );
+ if (Fresult == FR_OK)
{
- for (Dispenser_i = 0;Dispenser_i < JobTicket->segments[Segment_i]->brushstops[Brush_i]->n_dispensers;Dispenser_i++)
+ readBytes += ImmediateRead;
+ SegmentPtr = my_malloc (SegmentSize);
+ if (SegmentPtr)
{
- //prepare the SW structures
- DispenserId = JobTicket->segments[Segment_i]->brushstops[Brush_i]->dispensers[Dispenser_i]->index;
- if (JobTicket->segments[Segment_i]->brushstops[Brush_i]->dispensers[Dispenser_i]->nanolitterpersecond>0.0)
+ Fresult = f_read(FileHandle,SegmentPtr,SegmentSize,&ImmediateRead );
+ if (Fresult == FR_OK)
{
- DispenserUsedInJob[DispenserId] = true;
- if(DispenserId == LUBRICANT_DISPENSER)
+ readBytes += ImmediateRead;
+ n_segments++;
+ Segment = job_description_file_segment__unpack(NULL, SegmentSize, SegmentPtr);
+ if ((Segment->has_brushstopscount)&&(Segment->brushstopscount))
{
- lubricant_speed = JobTicket->segments[0]->brushstops[0]->dispensers[Dispenser_i]->nanolitterpersecond/
- JobTicket->segments[0]->brushstops[0]->dispensers[Dispenser_i]->nanoliterperpulse;
- REPORT_MSG (lubricant_speed*100, "LUBRICANT_SPEED*100");
+ REPORT_MSG (Segment->brushstopscount, "Segment->brushstopscount");
+ for (Brush_i=0;Brush_i<Segment->brushstopscount;Brush_i++)
+ {
+ if (status == ERROR)
+ break;
+ Fresult = f_read(FileHandle,&BrushStopSize,4,&ImmediateRead );
+ if (Fresult == FR_OK)
+ {
+ readBytes += ImmediateRead;
+ BrushStopPtr = my_malloc (BrushStopSize);
+ if (BrushStopPtr)
+ {
+ Fresult = f_read(FileHandle,BrushStopPtr,BrushStopSize,&ImmediateRead );
+ if (Fresult == FR_OK)
+ {
+ readBytes += ImmediateRead;
+ BrushStop = job_description_file_brush_stop__unpack(NULL, BrushStopSize, BrushStopPtr);
+ REPORT_MSG (BrushStopSize, "BrushStop");
+ if (BrushStop->n_dispensers)
+ {
+ for (Dispenser_i = 0;Dispenser_i < BrushStop->n_dispensers;Dispenser_i++)
+ {
+ //prepare the SW structures
+ DispenserId = BrushStop->dispensers[Dispenser_i]->index;
+ if (BrushStop->dispensers[Dispenser_i]->nanolitterpersecond>0.0)
+ {
+ DispenserUsedInJob[DispenserId] = true;
+ }
+ }//for dispenser
+ }//if dispensers
+ else
+ {
+ LOG_ERROR (BrushStop->index, "no dispensers in brushstop");
+ }
+ job_description_file_brush_stop__free_unpacked (BrushStop,NULL);
+ BrushStop = NULL;
+ } //read brush stop data
+ else
+ {
+ LOG_ERROR (Fresult, "f_read error");
+ status = ERROR;
+ }
+ my_free(BrushStopPtr);
+ BrushStopPtr = NULL;
+ }//brushstop malloc ok
+ else
+ {
+ LOG_ERROR (BrushStopPtr, "malloc error");
+ status = ERROR;
+ }
+ }//brushstop size read ok
+ else
+ {
+ LOG_ERROR (Fresult, "f_read error");
+ status = ERROR;
+ }
+ }//for brushstops
+ }// if brush stop count
+ else
+ {
+ LOG_ERROR (0, "no brushstops error");
+ status = ERROR;
}
+ job_description_file_segment__free_unpacked(Segment,NULL);
+ Segment = NULL;
+ }// read segment data
+ my_free(SegmentPtr);
+ SegmentPtr = NULL;
+ Task_sleep(10);
+ }//segment malloc
+ else
+ {
+ LOG_ERROR (SegmentPtr, "malloc error");
+ status = ERROR;
+ }
+ }//segment read size
+ else
+ {
+ LOG_ERROR (Fresult, "f_read error");
+ status = ERROR;
+ }
+ }//while(readBytes < Bytes)
+ }
+ else
+ {
+ LOG_ERROR (Fresult, "FileOpen error");
+ status = ERROR;
+ }
+ }//file job
- }
- }//for dispenser
- }//if dispensers
- }//for brush
- }//for segments
+ if (SegmentPtr)
+ my_free(SegmentPtr);
+ if (BrushStopPtr)
+ my_free(BrushStopPtr);
+ if (Segment != NULL)
+ job_description_file_segment__free_unpacked(Segment,NULL);
+ if (BrushStop != NULL)
+ job_description_file_brush_stop__free_unpacked (BrushStop,NULL);
+ Fresult = f_close(FileHandle);
+ REPORT_MSG (n_segments, "Finished checking the file");
+ return status;
+
+ }
+/************************************************************************************************************************************/
+ bool IDS_MapDispenserUsedinJob(void *JobDetails)
+ {
+ JobTicket* JobTicket = JobDetails;
+ int Dispenser_i, Segment_i,Brush_i,DispenserId;
+
+ if (JobTicket->uploadstrategy == JOB_UPLOAD_STRATEGY__JobDescriptionFile)
+ {
+ return (IDS_MapDispenserUsedinFileJob(JobDetails));
+ //return (IDS_MapDispenserUsedinFileJobshort(JobDetails));
+ }
+ else
+ {
+ for (Dispenser_i = 0;Dispenser_i<MAX_SYSTEM_DISPENSERS;Dispenser_i++)
+ {
+ DispenserUsedInJob[Dispenser_i] = false;
+ }
+ if (n_segments == 0)
+ return false;
- return false;
+ for (Segment_i=0;Segment_i<n_segments;Segment_i++)
+ {
+ for (Brush_i=0;Brush_i<JobTicket->segments[Segment_i]->n_brushstops;Brush_i++)
+ {
+ if (JobTicket->segments[Segment_i]->brushstops[Brush_i]->n_dispensers)
+ {
+ for (Dispenser_i = 0;Dispenser_i < JobTicket->segments[Segment_i]->brushstops[Brush_i]->n_dispensers;Dispenser_i++)
+ {
+ //prepare the SW structures
+ DispenserId = JobTicket->segments[Segment_i]->brushstops[Brush_i]->dispensers[Dispenser_i]->index;
+ if (JobTicket->segments[Segment_i]->brushstops[Brush_i]->dispensers[Dispenser_i]->nanolitterpersecond>0.0)
+ {
+ DispenserUsedInJob[DispenserId] = true;
+ if(DispenserId == LUBRICANT_DISPENSER)
+ {
+ lubricant_speed = JobTicket->segments[0]->brushstops[0]->dispensers[Dispenser_i]->nanolitterpersecond/
+ JobTicket->segments[0]->brushstops[0]->dispensers[Dispenser_i]->nanoliterperpulse;
+ REPORT_MSG (lubricant_speed*100, "LUBRICANT_SPEED*100");
+ }
+
+ }
+ }//for dispenser
+ }//if dispensers
+ }//for brush
+ }//for segments
+ }
+
+ return true;
}
@@ -214,7 +475,7 @@ void DispenserPrepareReady(void)
//ValveCommand (Enable,MixerDirection);
}
//set 3 dancers to the profile positions
- IDS_MapDispenserUsedinJob(JobDetails);
+ //IDS_MapDispenserUsedinJob(JobDetails);
for (i = 0; i < MAX_SYSTEM_DISPENSERS; i++)
{
if (DispenserUsedInJob[i] == true) //we actually should check for all dispensers
@@ -229,32 +490,6 @@ void DispenserPrepareReady(void)
DispenserPrepareReady();
return OK;
}
-bool IDS_isDispenserUsedNextSegment(void *SegmentDetails,int DispenserId, int SegmentId)
-{
- JobSegment* Segment = SegmentDetails;
- int Dispenser_i,n_dispensers;
- if (Segment->brushstops[0]->n_dispensers)
- {
- n_dispensers = Segment->brushstops[0]->n_dispensers;
- for (Dispenser_i = 0;Dispenser_i < n_dispensers;Dispenser_i++)
- {
- if (DispenserId == Segment->brushstops[0]->dispensers[Dispenser_i]->index) //dispenser is in use next segment
- {
- if (Segment->brushstops[0]->dispensers[Dispenser_i]->nanolitterpersecond>0)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- }
- }
-
- return false;
-
-}
//********************************************************************************************************************
uint32_t IDS_Valve_PresegmentValveReady(uint32_t deviceID, uint32_t ReadValue)
{
@@ -287,8 +522,17 @@ bool IDS_isDispenserUsedNextSegment(void *SegmentDetails,int DispenserId, int Se
int lInterSegmentLength = 0;
int InterSegmentStepsLimit = 0,InterSegmentStepsCount = 0;
- int InterSegmentWFCFTime;
+ uint32_t InterSegmentStartSprayCleaner;
+ uint32_t InterSegmentStartRocking;
+ uint32_t InterSegmentCenterRockers;
+ uint32_t InterSegmentStartWFCFDispensers;
+ bool EnableCleaning = false;
+
+
uint32_t DispenserPreSegmentControlId = 0xFF;
+ uint32_t BrushStopControlId = 0xFF;
+ uint32_t PreSegmentControlId = 0xFF;
+
//********************************************************************************************************************
uint32_t IDSPreSegmentStateCallbackRunner(uint32_t IfIndex, uint32_t ReadValue)
@@ -313,19 +557,49 @@ This means that for each Pre-segment we must calculate: TW,TU,Tending,
This means that for each segment we must calculate: Tx,Ty.
*/
+/*uint32_t InterSegmentStartSprayCleaner = 500;
+uint32_t InterSegmentStartRocking = 1000;
+uint32_t InterSegmentCenterRockers = 3000;
+uint32_t InterSegmentStartWFCFDispensers = lInterSegmentLength-1500;*/
//InterSegmentStepsLimit = lInterSegmentLength*10;//100 millisec steps
- InterSegmentStepsCount++;
- if (InterSegmentStepsCount == InterSegmentStepsLimit)
+ InterSegmentStepsCount+=100;
+ if (InterSegmentStepsCount == lInterSegmentLength)
{
- IDS_Valve_PresegmentReady(1,0);
+ //IDS_Valve_PresegmentReady(1,0);
+ Report("End of Pre-segment Handling",__FILE__,__LINE__,InterSegmentStepsCount,RpWarning,(int)lInterSegmentLength,0);
SafeRemoveControlCallback(DispenserPreSegmentControlId,IDSPreSegmentStateCallbackRunner);
}
+ if (EnableCleaning == true)
+ {
+ if (InterSegmentStartSprayCleaner == InterSegmentStepsCount)
+ {
+ Report("Start Spray Cleaner",__FILE__,__LINE__,InterSegmentStepsCount,RpWarning,(int)lInterSegmentLength,0);
+ //startClenerSpray(speed);
+ }
+ if (InterSegmentStartRocking == InterSegmentStepsCount)
+ {
+ Report("Start cleaning rockers",__FILE__,__LINE__,InterSegmentStepsCount,RpWarning,(int)lInterSegmentLength,0);
+ //startRocking(leftspeed,rightspeed);
+ }
+ if (InterSegmentCenterRockers == InterSegmentStepsCount)
+ {
+ Report("Stop spray and center rockers",__FILE__,__LINE__,InterSegmentStepsCount,RpWarning,(int)lInterSegmentLength,0);
+ //stopClenerSpray(speed);
+ //centerRockers();
+ }
+ }
+ if (InterSegmentStartWFCFDispensers == InterSegmentStepsCount)
+ {
+ Report("start dispensers at rate * WFCF",__FILE__,__LINE__,InterSegmentStepsCount,RpWarning,(int)lInterSegmentLength,0);
+ //startDispensersAtSegmentSpeed*1=WFCFClenerSpray(speed);
+ }
return OK;
}
-
+JobDescriptionFileBrushStop * FileBrushStop;
uint32_t IDSPreSegmentState(void *SegmentDetails, int SegmentId)
{
JobSegment* Segment = SegmentDetails;
+ JobDispenser **Dispensers;
//set the speed only before the first segment, speed is constant accros job
int Dispenser_i,n_dispensers,DispenserId;
TimerMotors_t HW_Motor_Id;
@@ -339,7 +613,9 @@ uint32_t IDSPreSegmentState(void *SegmentDetails, int SegmentId)
REPORT_MSG(SegmentId,"IDSPreSegmentState");
if (JobBrushStopId>=Segment->n_brushstops)
{
- LOG_ERROR(JobBrushStopId,"Error JobBrushStopId");
+ LOG_ERROR(Segment->n_brushstops,"Error JobBrushStopId");
+ JobEndReason = JOB_OUT_OF_DYE;
+ PreSegmentReady(Module_IDS,ModuleFail);
return ERROR;
}
@@ -347,148 +623,248 @@ uint32_t IDSPreSegmentState(void *SegmentDetails, int SegmentId)
if ((EnableIntersegment == true)&&(IntersegmentLength>0))
{
Valve_Set(VALVE_MIXCHIP_WASTECH, Mixer_Waste); //if intersegment is defined throw the ink away
- lInterSegmentLength = ((IntersegmentLength*100)/dyeingspeed);
- InterSegmentStepsLimit = lInterSegmentLength*10;//100 millisec steps
- InterSegmentStepsCount = 0;
- /*DispenserPreSegmentControlId = AddControlCallback( IDSPreSegmentStateCallbackRunner, 100,TemplateDataReadCBFunction ,0, 0, 0 );
- if (DispenserPreSegmentControlId == 0xFF)
+ if (SegmentId>0)
{
- Report("Add control callback failed",__FILE__,__LINE__,(int)InterSegmentLength,RpWarning,(int)0,0);
- return ERROR;
- }*/
+ lInterSegmentLength = ((IntersegmentLength*100)*1000/dyeingspeed);
+ lInterSegmentLength-=(lInterSegmentLength%100); //round to a 100 multiplication
+ InterSegmentStepsCount = 0;
+ DispenserPreSegmentControlId = AddControlCallback( IDSPreSegmentStateCallbackRunner, 100,TemplateDataReadCBFunction ,0, 0, 0 );
+ if (DispenserPreSegmentControlId == 0xFF)
+ {
+ Report("Add control callback failed",__FILE__,__LINE__,(int)100,RpWarning,(int)0,0);
+ return ERROR;
+ }
+ Report("Add control callback ",__FILE__,__LINE__,(int)100,RpWarning,(int)IntersegmentLength,0);
+ if (EnableCleaning == true)
+ {
+ InterSegmentStartSprayCleaner = 500;
+ InterSegmentStartRocking = 1000;
+ InterSegmentCenterRockers = 3000;
+ }
+ InterSegmentStartWFCFDispensers = lInterSegmentLength-1500;
+ }
}
- if (Segment->brushstops[JobBrushStopId]->n_dispensers)
+ if (uploadstrategy == JOB_UPLOAD_STRATEGY__Default)
{
+ Dispensers = Segment->brushstops[JobBrushStopId]->dispensers;
n_dispensers = Segment->brushstops[JobBrushStopId]->n_dispensers;
+ }
+ else
+ {
+ if (BrushStopControlId != 0xFF)
+ {
+ RemoveControlCallback(BrushStopControlId,IDSBrushStopRestartCallback);
+ BrushStopControlId = 0xFF;
+ }
+ FileBrushStop = GetNextBrushStopFromJobFile();
+ if (FileBrushStop)
+ {
+ REPORT_MSG(FileBrushStop->index,"BrushStopRead Index");
+ Dispensers = FileBrushStop->dispensers;
+ n_dispensers = FileBrushStop->n_dispensers;
+ }
+ else
+ {
+ LOG_ERROR(FileBrushStop,"BrushStopReadError");
+ JobEndReason = JOB_OUT_OF_DYE;
+ SegmentReady(Module_IDS,ModuleFail);
+ }
+ }
+ if (n_dispensers)
+ {
for (Dispenser_i = 0;Dispenser_i < n_dispensers;Dispenser_i++)
{
- DispenserId = Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->index;
- HW_Motor_Id = DispenserIdToMotorId[DispenserId];
- if (MotorsCfg[HW_Motor_Id].hardwaremotortype != DispenserIdToMotorId[DispenserId])//unconfigured dispenser
- {
- REPORT_MSG(DispenserId,"Dispenser PreSegment not configured");
- continue;
- }
+ DispenserId = Dispensers[Dispenser_i]->index;
DispenserPreSegmentReady[DispenserId] = false;
}
for (Dispenser_i = 0;Dispenser_i < n_dispensers;Dispenser_i++)
{
- DispenserId = Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->index;
+ DispenserId = Dispensers[Dispenser_i]->index;
HW_Motor_Id = DispenserIdToMotorId[DispenserId];
if (MotorsCfg[HW_Motor_Id].hardwaremotortype != DispenserIdToMotorId[DispenserId])//unconfigured dispenser
{
REPORT_MSG(DispenserId,"Dispenser PreSegment not configured");
+ DispenserPreSegmentReady[DispenserId] = true; //27/03/19 check if job should be stopped
continue;
}
REPORT_MSG(DispenserId,"IDS_Valve_Presegment start");
IDS_Dispenser_Set_Flow_Params(DispenserId,0,0);
- if (Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->dispenserstepdivision != DISPENSER_STEP_DIVISION__Auto)
+ if (Dispensers[Dispenser_i]->dispenserstepdivision != DISPENSER_STEP_DIVISION__Auto)
{
- MotorSetMicroStep(HW_Motor_Id, Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->dispenserstepdivision);
+ MotorSetMicroStep(HW_Motor_Id, Dispensers[Dispenser_i]->dispenserstepdivision);
}
else
{
MotorSetMicroStep(HW_Motor_Id, MotorsCfg[HW_Motor_Id].microstep);
}
+ MotorStop(HW_Motor_Id,Hard_Hiz); //26/03/19 test without valves
+ CurrentDispenserSpeed[DispenserId] = 0;
+ IDS_Valve_PresegmentReady(DispenserId,0); //27/03/19 to be removed when the presegment handler will be added
+ //REPORT_MSG(DispenserId,"Dispenser stopped pre Segment");
+ }
+ }
- if (Segment->brushstops[0]->dispensers[Dispenser_i]->nanolitterpersecond==0)
+ return OK;
+}
+//********************************************************************************************************************
+
+ char IdsMessage[100];
+uint32_t SegmentNumOfBrushStops = 0;
+double BrushStopTime = 0;
+
+void IDS_StartBrushStop(int n_dispensers, JobDispenser** Dispensers)
+{
+ int Dispenser_i,DispenserId;
+ TimerMotors_t HW_Motor_Id;
+ double segmentfirst_speed;
+ Report("IDS_StartBrushStop",__FILE__,__LINE__,(int)JobBrushStopId,RpWarning,(int)0,0);
+
+ if (n_dispensers)
+ {
+ for (Dispenser_i = 0; Dispenser_i < n_dispensers; Dispenser_i++)
+ {
+ DispenserId = Dispensers[Dispenser_i]->index;
+ HW_Motor_Id = DispenserIdToMotorId[DispenserId];
+ if (MotorsCfg[HW_Motor_Id].hardwaremotortype
+ != DispenserIdToMotorId[DispenserId])
+ continue;
+
+ //(Speed*uStep*PPR)/((2*PI*Dispenser_Radius)
+ segmentfirst_speed = Dispensers[Dispenser_i]->nanolitterpersecond
+ / Dispensers[Dispenser_i]->nanoliterperpulse;
+ if (Dispensers[Dispenser_i]->dispenserstepdivision
+ != DISPENSER_STEP_DIVISION__Auto)
{
- MotorStop(HW_Motor_Id,Hard_Hiz); //26/03/19 test without valves
- IDS_Valve_PresegmentReady(DispenserId,0);
- //Control3WayValvesWithCallback ((Valves_t)DispenserId, MidTank_Dispenser, IDS_Valve_PresegmentValveReady); //direction: MidTank_Dispenser or Dispenser_Mixer
- //IDS_Dispenser_Close_Valve_And_Stop_Motor(DispenserId,IDS_Valve_PresegmentValveReady);
- REPORT_MSG(DispenserId,"Dispenser Not Used Next Segment");
+ //MotorSetMicroStep(HW_Motor_Id, Dispensers[Dispenser_i]->dispenserstepdivision);
+ segmentfirst_speed /=
+ Dispensers[Dispenser_i]->dispenserstepdivision; //the dye supply is calculated based on a 1/8 microstep
+ IDS_Dispenser_Set_Flow_Params(
+ DispenserId, Dispensers[Dispenser_i]->nanoliterperpulse,
+ Dispensers[Dispenser_i]->dispenserstepdivision);
}
else
{
- if (IntersegmentLength&&(SegmentId>0)) //there is an intersegment, stop all the dispensers. otherwise stop only dispensers that are not in use in the next segment.
- {
- //Control3WayValvesWithCallback ((Valves_t)DispenserId, MidTank_Dispenser, IDS_Valve_PresegmentValveReady); //direction: MidTank_Dispenser or Dispenser_Mixer
- MotorStop(HW_Motor_Id,Hard_Hiz); //26/03/19 test without valves
- IDS_Valve_PresegmentReady(DispenserId,0);
- //IDS_Dispenser_Close_Valve_And_Stop_Motor(DispenserId,IDS_Valve_PresegmentValveReady);
- REPORT_MSG(DispenserId,"Dispenser Used Next Segment with intersegment");
- }
- else
- {
- IDS_Valve_PresegmentReady(DispenserId,0);
- }
- REPORT_MSG(DispenserId,"Dispenser is Used Next Segment");
+ //segmentfirst_speed/=MotorsCfg[HW_Motor_Id].microstep; //the dye supply is calculated based on a 1/8 microstep
+ IDS_Dispenser_Set_Flow_Params(
+ DispenserId, Dispensers[Dispenser_i]->nanoliterperpulse,
+ MotorsCfg[HW_Motor_Id].microstep);
+ }
+ if ((int) segmentfirst_speed > 0)
+ {
+ DispenserSegmentReady[DispenserId] = false;
+ //Control3WayValvesWithCallback (DispenserId, Dispenser_Mixer, NULL); //direction: MidTank_Dispenser or Dispenser_Mixer
+ IDS_Dispenser_Start_Motor_and_Open_Valve(DispenserId,
+ segmentfirst_speed,
+ NULL);
+ usnprintf(IdsMessage, 80,
+ "Dispenser %d nl/sec %d nl/pulse %d speed %d",
+ DispenserId,
+ (int) Dispensers[Dispenser_i]->nanolitterpersecond,
+ (int) Dispensers[Dispenser_i]->nanoliterperpulse,
+ (int) segmentfirst_speed);
+ //REPORT_MSG(segmentfirst_speed,IdsMessage);
+ Report(IdsMessage, __FILE__, __LINE__, Dispenser_i, RpWarning, segmentfirst_speed, 0);
+ SendJobProgress(0.0, 0, false, IdsMessage);
}
}
}
+}
+uint32_t IDSBrushStopRestartCallback(uint32_t IfIndex, uint32_t readValue)
+{
+ JobDispenser **Dispensers = NULL;
+ int n_dispensers = 0;
+ JobSegment* Segment = (void *)IfIndex;
+ if (uploadstrategy == JOB_UPLOAD_STRATEGY__Default)
+ {
+ Dispensers = Segment->brushstops[JobBrushStopId]->dispensers;
+ n_dispensers = Segment->brushstops[JobBrushStopId]->n_dispensers;
+ }
+ else
+ {
+ if (FileBrushStop)
+ FreeBrushStopFileData(FileBrushStop);
+ FileBrushStop = GetNextBrushStopFromJobFile();
+ if (FileBrushStop)
+ {
+ REPORT_MSG(FileBrushStop->index,"BrushStopRead Index");
+ Dispensers = FileBrushStop->dispensers;
+ n_dispensers = FileBrushStop->n_dispensers;
+ }
+ else
+ {
+ LOG_ERROR(FileBrushStop,"BrushStopReadError");
+ JobEndReason = JOB_OUT_OF_DYE;
+ SegmentReady(Module_IDS,ModuleFail);
+ }
+ }
+ if (n_dispensers)
+ {
+ IDS_StartBrushStop(n_dispensers, Dispensers);
+ }
+ JobBrushStopId++;
+ Report("brushstop",__FILE__,__LINE__,(int)JobBrushStopId,RpWarning,(int)SegmentNumOfBrushStops,0);
+ if (JobBrushStopId >= SegmentNumOfBrushStops)
+ {
+ Report("last brushstop",__FILE__,__LINE__,(int)JobBrushStopId,RpWarning,(int)SegmentNumOfBrushStops,0);
+ SafeRemoveControlCallback(BrushStopControlId,IDSBrushStopRestartCallback);
+ BrushStopControlId = 0Xff;
+ }
return OK;
}
//********************************************************************************************************************
-
- uint32_t IDS_Valve_SegmentReady(uint32_t deviceID, uint32_t ReadValue)
- {
- int i;
- DispenserSegmentReady[deviceID] = true;
- for (i=0;i<MAX_SYSTEM_DISPENSERS;i++)
- {
- if (DispenserSegmentReady[i] == false)
- {
- return OK; //not all configured heaters are ready
- }
- }
- SegmentReady(Module_IDS,ModuleDone);
- return OK; // all configured heaters are ready
- }
-
- char IdsMessage[100];
-//********************************************************************************************************************
uint32_t IDSSegmentState(void *SegmentDetails, int SegmentId)
{
JobSegment* Segment = SegmentDetails;
- int Dispenser_i,n_dispensers,DispenserId;
- TimerMotors_t HW_Motor_Id;
- double segmentfirst_speed;
+ JobDispenser **Dispensers;
+ int n_dispensers;
Valve_Set(VALVE_MIXCHIP_WASTECH, Mixer_Head);
- if (Segment->brushstops[JobBrushStopId]->n_dispensers)
+
+ SegmentNumOfBrushStops = Segment->n_brushstops;
+ BrushStopTime = Segment->length/SegmentNumOfBrushStops; //brushstop in meters
+ BrushStopTime = ((BrushStopTime*100)/dyeingspeed);//brushstop in seconds
+ BrushStopTime *= 1000; //brushstop in millisecond
+ Report("IDSSegmentState",__FILE__,__LINE__,(int)BrushStopTime,RpWarning,(int)SegmentNumOfBrushStops,0);
+ if (uploadstrategy == JOB_UPLOAD_STRATEGY__Default)
{
+ Dispensers = Segment->brushstops[JobBrushStopId]->dispensers;
n_dispensers = Segment->brushstops[JobBrushStopId]->n_dispensers;
- for (Dispenser_i = 0;Dispenser_i < n_dispensers;Dispenser_i++)
+ }
+ else
+ {
+ if (FileBrushStop)
{
- DispenserId = Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->index;
- HW_Motor_Id = DispenserIdToMotorId[DispenserId];
- if (MotorsCfg[HW_Motor_Id].hardwaremotortype != DispenserIdToMotorId[DispenserId])//unconfigured dispenser
- continue;
- //(Speed*uStep*PPR)/((2*PI*Dispenser_Radius)
- segmentfirst_speed = Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->nanolitterpersecond/
- Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->nanoliterperpulse;
- if (Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->dispenserstepdivision != DISPENSER_STEP_DIVISION__Auto)
- {
- //MotorSetMicroStep(HW_Motor_Id, Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->dispenserstepdivision);
- segmentfirst_speed/=Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->dispenserstepdivision; //the dye supply is calculated based on a 1/8 microstep
- IDS_Dispenser_Set_Flow_Params ( DispenserId, Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->nanoliterperpulse
- , Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->dispenserstepdivision);
- }
- else
- {
- //segmentfirst_speed/=MotorsCfg[HW_Motor_Id].microstep; //the dye supply is calculated based on a 1/8 microstep
- IDS_Dispenser_Set_Flow_Params ( DispenserId, Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->nanoliterperpulse
- ,MotorsCfg[HW_Motor_Id].microstep);
- }
- if ((int)segmentfirst_speed > 0)
- {
- DispenserSegmentReady[DispenserId] = false;
- //Control3WayValvesWithCallback (DispenserId, Dispenser_Mixer, NULL); //direction: MidTank_Dispenser or Dispenser_Mixer
- IDS_Dispenser_Start_Motor_and_Open_Valve(DispenserId,segmentfirst_speed,NULL);
- usnprintf(IdsMessage, 80, "Dispenser %d nl/sec %d nl/pulse %d speed %d",Dispenser_i,(int)Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->nanolitterpersecond,
- (int)Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->nanoliterperpulse,(int)segmentfirst_speed);
- //REPORT_MSG(segmentfirst_speed,IdsMessage);
- Report(IdsMessage,__FILE__,__LINE__,Dispenser_i,RpWarning,segmentfirst_speed,0);
- SendJobProgress(0.0,0,false, IdsMessage);
-
-
- }
+ Dispensers = FileBrushStop->dispensers;
+ n_dispensers = FileBrushStop->n_dispensers;
+ }
+ else
+ {
+ LOG_ERROR(FileBrushStop,"BrushStopReadError");
}
}
+ IDS_StartBrushStop(n_dispensers, Dispensers);
+ JobBrushStopId++;
+ if ((BrushStopTime)&&(SegmentNumOfBrushStops > 1))
+ {
+ BrushStopControlId = AddControlCallback( IDSBrushStopRestartCallback, BrushStopTime,TemplateDataReadCBFunction ,SegmentDetails, 0, 0 );
+ if (BrushStopControlId == 0xFF)
+ {
+ Report("Add control callback failed",__FILE__,__LINE__,(int)BrushStopTime,RpWarning,(int)0,0);
+ return ERROR;
+ }
+ Report("Add control callback ",__FILE__,__LINE__,(int)BrushStopTime,RpWarning,(int)n_dispensers,0);
+
+ }
+ else
+ {
+ if (FileBrushStop)
+ FreeBrushStopFileData(FileBrushStop);
+ FileBrushStop = NULL;
+ }
+
return OK;
}
//********************************************************************************************************************
@@ -513,6 +889,7 @@ uint32_t IDSSegmentState(void *SegmentDetails, int SegmentId)
return OK; //not all configured heaters are ready
}
}
+ REPORT_MSG(deviceID,"IDS_Valve_DistanceToSpoolReady End called");
DistanceToSpoolReady(Module_IDS,ModuleDone);
return OK; // all configured heaters are ready
}
@@ -551,6 +928,14 @@ uint32_t IDSSegmentState(void *SegmentDetails, int SegmentId)
IDS_Active = false;
Valve_Set(VALVE_MIXCHIP_WASTECH, Mixer_Waste);
REPORT_MSG(0,"Dispenser End Start");
+ if (BrushStopControlId != 0xFF)
+ {
+ RemoveControlCallback(BrushStopControlId,IDSBrushStopRestartCallback);
+ BrushStopControlId = 0xFF;
+ }
+ if (FileBrushStop)
+ FreeBrushStopFileData(FileBrushStop);
+ FileBrushStop = NULL;
for ( Dispenser_i = 0;Dispenser_i < MAX_SYSTEM_DISPENSERS;Dispenser_i++)
{
if (DispenserUsedInJob[Dispenser_i] == true)