TopicA blending station in SCL
Title
Weighing the hopper in one scan
ExampleW09.1
Step1 / 3
Mode
Given
Given
An S7-300 runs the Blender function block below once a scan. Its three load cells read to for to kg, and the recipe wants , and kg. For each set of raw values, fill in the weight in the hopper, how full the batch is, and how many kg bags it fills, rounded to the nearest bag.
- load cells: raw to is to kg
- recipe: , and kg
- bags of kg
| raw 1 | raw 2 | raw 3 | totalkg | fill% | bags |
|---|---|---|---|---|---|
| 3456 | 2592 | 4320 | 187.5 | ||
| 6480 | 4320 | 6480 | 312.5 | ||
| 7344 | 4536 | 6912 | 339.8 |
Weigh the silos
The FOR loop scales each load cell with ToKg, , and adds it up: kg.
Sim
The blending station, running
Set the load cells and the buttons, then step a statement or run a whole scan. Each scan calls the Blender block once; the trace shows what every statement decided and wrote.
// A blending station: three silos dose into one hopper, then a mixer runs the batch.TYPE "Silo"STRUCTtarget_kg : REAL; // the recipe's weight from this siloraw : INT; // load cell: 0..27648 = 0..500 kgkg : REAL; // the weight it readsshort : BOOL; // still under its targetEND_STRUCTEND_TYPEDATA_BLOCK "Recipe"VARsilo : ARRAY[1..3] OF "Silo";batches : INT; // batches mixed so farEND_VARBEGINsilo[1].target_kg := 120.0;silo[2].target_kg := 80.0;silo[3].target_kg := 120.0;END_DATA_BLOCKFUNCTION ToKg : REALVAR_INPUTraw : INT;END_VARBEGINToKg := INT_TO_REAL(raw) / 27648.0 * 500.0;END_FUNCTIONFUNCTION_BLOCK "Blender"VAR_INPUTstart : BOOL; // the operator's start buttonraw1 : INT; // the three load cellsraw2 : INT;raw3 : INT;mixed : BOOL; // the mixer's timer has run outEND_VARVAR_OUTPUTvalve : INT; // the silo dosing now, 0 = nonetotal_kg : REAL; // in the hopperfill_pct : REAL; // of the batch's weightbags : INT; // 25 kg bags the hopper fillsmixer : BOOL;END_VARVARstep : INT; // 0 IDLE, 1 DOSE, 2 MIXlast_start : BOOL; // start, one scan agoEND_VARVAR_TEMPi : INT;target : REAL;END_VARBEGIN"Recipe".silo[1].raw := raw1;"Recipe".silo[2].raw := raw2;"Recipe".silo[3].raw := raw3;total_kg := 0.0;target := 0.0;FOR i := 1 TO 3 DO"Recipe".silo[i].kg := ToKg(raw := "Recipe".silo[i].raw);"Recipe".silo[i].short := "Recipe".silo[i].kg < "Recipe".silo[i].target_kg;total_kg := total_kg + "Recipe".silo[i].kg;target := target + "Recipe".silo[i].target_kg;END_FOR;fill_pct := total_kg / target * 100.0;bags := REAL_TO_INT(total_kg / 25.0); // 312.5 kg is 12.5 bags(a Divergence: the exam's answer differs from a real S7)valve := 0;CASE step OF0: // IDLE: wait for start to riseIF start AND NOT last_start THENstep := 1;END_IF;1: // DOSE: open the first silo still shortFOR i := 1 TO 3 DOIF "Recipe".silo[i].short THENvalve := i;EXIT;END_IF;END_FOR;IF valve = 0 THENstep := 2;END_IF;2: // MIX: run the mixer until its timer runs outmixer := NOT mixed;IF mixed THEN"Recipe".batches := "Recipe".batches + 1;step := 0;END_IF;ELSEstep := 0;END_CASE;last_start := start;END_FUNCTION_BLOCK
Statement92 last_start := start;
Writtenlast_start := FALSE
| Variable | Value |
|---|---|
| step | 0 |
| valve | 0 |
| total_kg | 312.5 |
| fill_pct | 97.65625 |
| bags | 12 |
| mixer | FALSE |
| Recipe.silo[1].kg | 117.1875 |
| Recipe.silo[2].kg | 78.125 |
| Recipe.silo[3].kg | 117.1875 |
| Recipe.batches | 0 |
| Line | Statement | Result |
|---|---|---|
| 54 | "Recipe".silo[1].raw := raw1; | Recipe.silo[1].raw := 6480 |
| 55 | "Recipe".silo[2].raw := raw2; | Recipe.silo[2].raw := 4320 |
| 56 | "Recipe".silo[3].raw := raw3; | Recipe.silo[3].raw := 6480 |
| 57 | total_kg := 0.0; | total_kg := 0.0 |
| 58 | target := 0.0; | target := 0.0 |
| 59 | FOR i := 1 TO 3 DO | into the loop |
| 60 | "Recipe".silo[i].kg := ToKg(raw := "Recipe".silo[i].raw); | Recipe.silo[1].kg := 117.1875 |
| 61 | "Recipe".silo[i].short := "Recipe".silo[i].kg < "Recipe".silo[i].target_kg; | Recipe.silo[1].short := TRUE |
| 62 | total_kg := total_kg + "Recipe".silo[i].kg; | total_kg := 117.1875 |
| 63 | target := target + "Recipe".silo[i].target_kg; | target := 120.0 |
| 64 | END_FOR; | again |
| 60 | "Recipe".silo[i].kg := ToKg(raw := "Recipe".silo[i].raw); | Recipe.silo[2].kg := 78.125 |
| 61 | "Recipe".silo[i].short := "Recipe".silo[i].kg < "Recipe".silo[i].target_kg; | Recipe.silo[2].short := TRUE |
| 62 | total_kg := total_kg + "Recipe".silo[i].kg; | total_kg := 195.3125 |
| 63 | target := target + "Recipe".silo[i].target_kg; | target := 200.0 |
| 64 | END_FOR; | again |
| 60 | "Recipe".silo[i].kg := ToKg(raw := "Recipe".silo[i].raw); | Recipe.silo[3].kg := 117.1875 |
| 61 | "Recipe".silo[i].short := "Recipe".silo[i].kg < "Recipe".silo[i].target_kg; | Recipe.silo[3].short := TRUE |
| 62 | total_kg := total_kg + "Recipe".silo[i].kg; | total_kg := 312.5 |
| 63 | target := target + "Recipe".silo[i].target_kg; | target := 320.0 |
| 64 | END_FOR; | done |
| 65 | fill_pct := total_kg / target * 100.0; | fill_pct := 97.65625 |
| 66 | bags := REAL_TO_INT(total_kg / 25.0); | bags := 12 |
| 67 | valve := 0; | valve := 0 |
| 68 | CASE step OF | 0: line 69 |
| 70 | IF start AND NOT last_start THEN | FALSE |
| 92 | last_start := start; | last_start := FALSE |
- Derived
- worked out here, no official key: bags, held as
- Divergence
- The exam answer is bags, the Professor's. REAL_TO_INT rounds to the even number on a real S7, so the CPU holds .